diff options
| author | Louis Burda <quent.burda@gmail.com> | 2024-11-05 02:34:09 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2024-11-05 02:34:09 +0100 |
| commit | c55a5c678f7c3751a1411c55f451e5938c878307 (patch) | |
| tree | 9a5cbe5fe25ca63928340ec93ce2384b7d5ce8aa | |
| parent | 1e1c0cf8dfd2ad7bd5d9ee620160b7363280284c (diff) | |
| download | desk-andon-c55a5c678f7c3751a1411c55f451e5938c878307.tar.gz desk-andon-c55a5c678f7c3751a1411c55f451e5938c878307.zip | |
Add http server to control lights
| -rw-r--r-- | firmware/src/main/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | firmware/src/main/main.c | 135 |
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)); } } |
