summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2024-11-05 02:34:09 +0100
committerLouis Burda <quent.burda@gmail.com>2024-11-05 02:34:09 +0100
commitc55a5c678f7c3751a1411c55f451e5938c878307 (patch)
tree9a5cbe5fe25ca63928340ec93ce2384b7d5ce8aa
parent1e1c0cf8dfd2ad7bd5d9ee620160b7363280284c (diff)
downloaddesk-andon-c55a5c678f7c3751a1411c55f451e5938c878307.tar.gz
desk-andon-c55a5c678f7c3751a1411c55f451e5938c878307.zip
Add http server to control lights
-rw-r--r--firmware/src/main/CMakeLists.txt4
-rw-r--r--firmware/src/main/main.c135
2 files changed, 109 insertions, 30 deletions
diff --git a/firmware/src/main/CMakeLists.txt b/firmware/src/main/CMakeLists.txt
index ecce39d..0db536d 100644
--- a/firmware/src/main/CMakeLists.txt
+++ b/firmware/src/main/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ""
- REQUIRES "esp32-ssd1306" "esp_driver_gpio" "esp_driver_uart" "esp_wifi" "nvs_flash")
-#component_compile_options("-O0")
+ REQUIRES "esp32-ssd1306" "esp_driver_gpio"
+ "esp_driver_uart" "esp_wifi" "nvs_flash" "esp_http_server")
diff --git a/firmware/src/main/main.c b/firmware/src/main/main.c
index 51e6c36..a9ed2d0 100644
--- a/firmware/src/main/main.c
+++ b/firmware/src/main/main.c
@@ -9,6 +9,7 @@
#include "driver/gpio.h"
#include "hal/gpio_types.h"
#include "esp_wifi.h"
+#include "esp_http_server.h"
#include "esp_log.h"
#include "nvs_flash.h"
@@ -17,12 +18,12 @@
#define TICKS_MS(x) ((x) / portTICK_PERIOD_MS)
#define LOG(...) ESP_LOGI("desk-andon", __VA_ARGS__)
+#define PANIC(...) lcd_panic(__VA_ARGS__);
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
-#define WIFI_FAIL_BIT BIT1
#define WIFI_ATTEMPT_MAX 5
@@ -85,20 +86,43 @@ static const uint8_t bitmap_light2[] = {
0xe0, 0x00
};
-const static int ANDON_PINS[SPEAKER+1] = { 10, 6, 3, 5, 7, 4 };
+static const int ANDON_PINS[SPEAKER+1] = { 10, 6, 3, 5, 7, 4 };
+static const char *ANDON_NAMES[SPEAKER+1] = {
+ [RED] = "red",
+ [ORANGE] = "orange",
+ [GREEN] = "green",
+ [BLUE] = "blue",
+ [WHITE] = "white",
+ [SPEAKER] = "speaker",
+};
static uint8_t state = 0;
static SSD1306_t display = { 0 };
static bool lcd_init = false;
+static TaskHandle_t lcd_task = NULL;
static char mac_str[16] = { 0 };
static char ip_str[17] = { 0 };
static bool wifi_connected = false;
static int wifi_connect_attempt = 0;
-
static EventGroupHandle_t wifi_event_group;
+static esp_err_t http_get_handler(httpd_req_t *req);
+static esp_err_t http_post_handler(httpd_req_t *req);
+static const httpd_uri_t http_get = {
+ .uri = "/",
+ .method = HTTP_GET,
+ .handler = http_get_handler,
+ .user_ctx = NULL
+};
+static const httpd_uri_t http_post = {
+ .uri = "/",
+ .method = HTTP_POST,
+ .handler = http_post_handler,
+ .user_ctx = NULL
+};
+
static void
lcd_task_main(void *_p)
{
@@ -162,6 +186,19 @@ lcd_task_main(void *_p)
}
static void
+lcd_panic(const char *msg)
+{
+ vTaskSuspend(lcd_task);
+ vTaskDelete(lcd_task);
+ ssd1306_clear_screen(&display, false);
+ ssd1306_display_text(&display, 20, 42, "PANIC", 10, false);
+ while (1) {
+ ESP_LOGE("desk-andon", "panic: %s", msg);
+ vTaskDelay(TICKS_MS(1000));
+ }
+}
+
+static void
set_output(uint8_t bv)
{
state = bv;
@@ -182,16 +219,11 @@ wifi_event_handler(void *arg, esp_event_base_t event_base,
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
wifi_connected = false;
- if (wifi_connect_attempt < WIFI_ATTEMPT_MAX) {
- esp_wifi_connect();
- wifi_connect_attempt++;
- LOG("retry to connect to the AP");
- snprintf(ip_str, sizeof(ip_str), " connecting..%c ",
- '0' + wifi_connect_attempt);
- } else {
- snprintf(ip_str, sizeof(ip_str), " no wifi ");
- xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT);
- }
+ esp_wifi_connect();
+ wifi_connect_attempt++;
+ LOG("retry to connect to the AP");
+ snprintf(ip_str, sizeof(ip_str), " connecting..%c ",
+ wifi_connect_attempt % 2 == 0 ? '.' : ' ');
LOG("connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
@@ -252,18 +284,67 @@ wifi_init(void)
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT)
* or connection failed for the maximum number of re-tries (WIFI_FAIL_BIT).
* The bits are set by event_handler() (see above) */
- EventBits_t bits = xEventGroupWaitBits(wifi_event_group,
- WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
-
- /* xEventGroupWaitBits() returns the bits before the call returned,
- * hence we can test which event actually happened. */
- if (bits & WIFI_CONNECTED_BIT) {
- LOG("connected to ap SSID:%s password:%s", WIFI_SSID, WIFI_PASS);
- } else if (bits & WIFI_FAIL_BIT) {
- LOG("Failed to connect to SSID:%s, password:%s", WIFI_SSID, WIFI_PASS);
- } else {
- LOG("UNEXPECTED EVENT");
+ xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT,
+ pdFALSE, pdFALSE, portMAX_DELAY);
+}
+
+static esp_err_t
+http_get_handler(httpd_req_t *req)
+{
+ uint8_t current = state;
+ for (int i = 0; i <= SPEAKER; i++) {
+ if (current & (1 << i)) {
+ httpd_resp_send_chunk(req, ANDON_NAMES[i],
+ HTTPD_RESP_USE_STRLEN);
+ httpd_resp_send_chunk(req, " ", 1);
+ }
+ }
+ httpd_resp_send_chunk(req, NULL, 0);
+ return ESP_OK;
+}
+
+static esp_err_t
+http_post_handler(httpd_req_t *req)
+{
+ char buf[128] = { 0 };
+ int ret = httpd_req_recv(req, buf,
+ MIN(sizeof(buf)-1, req->content_len));
+ if ((ret <= 0)) {
+ httpd_resp_send(req, "fail", 4);
+ return ESP_FAIL;
+ }
+ uint8_t next = 0;
+ for (char *c = buf; c < buf + 128; ) {
+ size_t n = strcspn(c, "\t \n");
+ for (int i = 0; n > 0 && i <= SPEAKER; i++) {
+ if (n == strlen(ANDON_NAMES[i])
+ && !strncmp(c, ANDON_NAMES[i], n)) {
+ next |= 1 << i;
+ httpd_resp_send_chunk(req, ANDON_NAMES[i], n);
+ httpd_resp_send_chunk(req, " ", 1);
+ }
+ }
+ c += n + 1;
}
+ set_output(next);
+ httpd_resp_send_chunk(req, NULL, 0);
+ return ESP_OK;
+}
+
+static void
+http_init(void)
+{
+ httpd_handle_t server = NULL;
+ httpd_config_t config = HTTPD_DEFAULT_CONFIG();
+ config.lru_purge_enable = true;
+
+ LOG("Starting http server");
+
+ if (httpd_start(&server, &config) != ESP_OK)
+ PANIC("failed to start http server");
+
+ httpd_register_uri_handler(server, &http_get);
+ httpd_register_uri_handler(server, &http_post);
}
void
@@ -282,18 +363,16 @@ app_main(void)
ssd1306_display_text(&display, 3, 24, "DESK ANDON", 10, false);
vTaskDelay(TICKS_MS(500));
- TaskHandle_t lcd_task = NULL;
xTaskCreate(lcd_task_main, "lcd", 16 * 1024, NULL, tskIDLE_PRIORITY, &lcd_task);
vTaskDelay(TICKS_MS(500));
wifi_init();
+ http_init();
+
int tick = 0;
- uint8_t b = 0;
while (1) {
printf("Tick %i\n", ++tick);
- set_output(b);
- b = (b + 1) & ((1 << SPEAKER) - 1);
vTaskDelay(TICKS_MS(1000));
}
}