From 56f83e7258b0a5f465f15c0fcfffa26b046aeb9a Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 13 Nov 2022 17:05:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=81=AF=E5=85=89=E4=B8=8E=20Wi-Fi=20?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E8=81=94=E5=8A=A8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/c_cpp_properties.json | 58 +++++----- .vscode/settings.json | 6 +- debug.log | 3 + main/CMakeLists.txt | 2 +- main/light.c | 194 ++++++++++++++++++++++++++++++++++ main/main.c | 116 ++------------------ main/wifi.c | 10 +- 7 files changed, 243 insertions(+), 146 deletions(-) create mode 100644 debug.log create mode 100644 main/light.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 1d33717..889c6cb 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,30 +1,30 @@ { - "configurations": [ - { - "name": "ESP-IDF", - "compilerPath": "/Users/ivan/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch3-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", - "cStandard": "c11", - "cppStandard": "c++17", - "includePath": [ - "${config:idf.espIdfPath}/components/**", - "${config:idf.espIdfPathWin}/components/**", - "${config:idf.espAdfPath}/components/**", - "${config:idf.espAdfPathWin}/components/**", - "${workspaceFolder}/**" - ], - "browse": { - "path": [ - "/Users/ivan/esp/esp-idf/components", - "${config:idf.espIdfPathWin}/components", - "/Users/ivan/esp/esp-idf/components/**", - "${config:idf.espAdfPathWin}/components/**", - "${workspaceFolder}" - ], - "limitSymbolsToIncludedHeaders": false - }, - "compileCommands": "${workspaceFolder}/build/compile_commands.json", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 -} \ No newline at end of file + "configurations": [ + { + "name": "ESP-IDF", + "compilerPath": "/Users/ivan/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "includePath": [ + "${config:idf.espIdfPath}/components/**", + "${config:idf.espIdfPathWin}/components/**", + "${config:idf.espAdfPath}/components/**", + "${config:idf.espAdfPathWin}/components/**", + "${workspaceFolder}/**" + ], + "browse": { + "path": [ + "/Users/ivan/esp/esp-idf/components", + "${config:idf.espIdfPathWin}/components", + "/Users/ivan/esp/esp-idf/components/**", + "${config:idf.espAdfPathWin}/components/**", + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": false + }, + "compileCommands": "${workspaceFolder}/build/compile_commands.json", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 64c29b5..16dbf64 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,7 +11,7 @@ "idf.pythonBinPath": "/Users/ivan/.espressif/python_env/idf4.4_py3.8_env/bin/python", "idf.toolsPath": "/Users/ivan/.espressif", "idf.gitPath": "/usr/bin/git", - "idf.flashType": "JTAG", + "idf.flashType": "UART", "files.associations": { "*.ejs": "html", "css": "postcss", @@ -19,6 +19,8 @@ "*.cjson": "jsonc", "*.wxss": "css", "*.wxs": "javascript", - "*.inc": "c" + "*.inc": "c", + "*.tcc": "c", + "*.ipp": "c" } } diff --git a/debug.log b/debug.log new file mode 100644 index 0000000..73e6e9e --- /dev/null +++ b/debug.log @@ -0,0 +1,3 @@ +2022-11-13 16:59:32,574 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_STARTED +2022-11-13 16:59:32,576 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_READY2CONNECT +2022-11-13 16:59:42,978 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_STOPPED diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index aeb3410..d717f27 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "main.c" "wifi.c" +idf_component_register(SRCS "main.c" "wifi.c" "light.c" INCLUDE_DIRS ".") \ No newline at end of file diff --git a/main/light.c b/main/light.c new file mode 100644 index 0000000..431da5c --- /dev/null +++ b/main/light.c @@ -0,0 +1,194 @@ +/* RMT example -- RGB LED Strip + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include "driver/rmt.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "led_strip.h" +#include "sdkconfig.h" + +static const char *LIGHT_TAG = "ScreenBgLight_Light"; + +#define RMT_TX_CHANNEL RMT_CHANNEL_0 +#define RMT_TX_GPIO 1 +#define STRIP_LED_NUMBER 60 +#define EXAMPLE_CHASE_SPEED_MS (10) + +typedef enum light_mode_e { + light_mode_init = 0, + light_mode_connection_wifi = 1, + light_mode_idle = 2, +} light_mode_t; + +led_strip_t *light_led_strip; +light_mode_t light_mode; + +/** + * @brief Simple helper function, converting HSV color space to RGB color + * space + * + * Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV + * + */ +void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, + uint32_t *g, uint32_t *b) { + h %= 360; // h -> [0,360] + uint32_t rgb_max = v * 2.55f; + uint32_t rgb_min = rgb_max * (100 - s) / 100.0f; + + uint32_t i = h / 60; + uint32_t diff = h % 60; + + // RGB adjustment amount by hue + uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; + + switch (i) { + case 0: + *r = rgb_max; + *g = rgb_min + rgb_adj; + *b = rgb_min; + break; + case 1: + *r = rgb_max - rgb_adj; + *g = rgb_max; + *b = rgb_min; + break; + case 2: + *r = rgb_min; + *g = rgb_max; + *b = rgb_min + rgb_adj; + break; + case 3: + *r = rgb_min; + *g = rgb_max - rgb_adj; + *b = rgb_max; + break; + case 4: + *r = rgb_min + rgb_adj; + *g = rgb_min; + *b = rgb_max; + break; + default: + *r = rgb_max; + *g = rgb_min; + *b = rgb_max - rgb_adj; + break; + } +} + +void light_for_init() { + ESP_LOGI(LIGHT_TAG, "light_for_init"); + ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100)); + + uint32_t red = 0, green = 0, blue = 0; + int8_t i = 0; + + do { + for (; i < 100; i++) { + for (int j = 0; j < STRIP_LED_NUMBER; j++) { + led_strip_hsv2rgb(0, 0, i, &red, &green, &blue); + ESP_ERROR_CHECK( + light_led_strip->set_pixel(light_led_strip, j, red, green, blue)); + } + ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100)); + vTaskDelay(pdMS_TO_TICKS(10)); + } + } while (light_mode == light_mode_init); +} + +void light_for_connecting_wifi() { + ESP_LOGI(LIGHT_TAG, "light_for_connecting_wifi"); + + int8_t tick_tock = 0; + + do { + ESP_ERROR_CHECK( + light_led_strip->set_pixel(light_led_strip, tick_tock, 150, 150, 0)); + ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, + (tick_tock + 1) % 2, 0, 200, 0)); + ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100)); + ESP_LOGI(LIGHT_TAG, "tick_tock %d", tick_tock); + tick_tock = !tick_tock; + vTaskDelay(pdMS_TO_TICKS(200)); + } while (light_mode == light_mode_connection_wifi); +} + +void light_for_idle() { + ESP_LOGI(LIGHT_TAG, "light_for_idle"); + ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100)); + + uint32_t red = 0, green = 0, blue = 0; + uint16_t step_length = 360 / STRIP_LED_NUMBER; + + for (uint16_t offset = 0; light_mode == light_mode_idle; + offset = (offset + 1) % 360) { + for (uint16_t j = 0, hue = offset; j < STRIP_LED_NUMBER; + j++, hue += step_length) { + // Build RGB values + led_strip_hsv2rgb(hue, 100, 50, &red, &green, &blue); + // Write RGB values to strip driver + ESP_ERROR_CHECK( + light_led_strip->set_pixel(light_led_strip, j, red, green, blue)); + } + ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100)); + vTaskDelay(pdMS_TO_TICKS(10)); + } +} + +void light_strip_running_task(void *pv_parameters) { + while (true) { + if (!light_led_strip) { + ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed 2"); + } + // Show simple rainbow chasing pattern + ESP_LOGI(LIGHT_TAG, "light_strip_running_task"); + switch (light_mode) { + case light_mode_init: + light_for_init(); + break; + case light_mode_connection_wifi: + light_for_connecting_wifi(); + break; + case light_mode_idle: + light_for_idle(); + break; + default: + break; + } + } + vTaskDelete(NULL); +} + +void light_init_strip() { + rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_GPIO, RMT_TX_CHANNEL); + // set counter clock to 40MHz + config.clk_div = 2; + + ESP_ERROR_CHECK(rmt_config(&config)); + ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0)); + + // install ws2812 driver + led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG( + STRIP_LED_NUMBER, (led_strip_dev_t)config.channel); + light_led_strip = led_strip_new_rmt_ws2812(&strip_config); + if (!light_led_strip) { + ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed"); + } + // Clear LED strip (turn off all LEDs) + ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100)); + // Show simple rainbow chasing pattern + ESP_LOGI(LIGHT_TAG, "LED Rainbow Chase Start"); + + light_mode = light_mode_init; + + xTaskCreate(light_strip_running_task, "LIGHT_STRIP_RUNNING_TASK", 4096, NULL, + 1, NULL); +} + +void light_play(light_mode_t mode) { light_mode = mode; } \ No newline at end of file diff --git a/main/main.c b/main/main.c index b783f8b..59e77cb 100644 --- a/main/main.c +++ b/main/main.c @@ -1,121 +1,17 @@ -/* RMT example -- RGB LED Strip - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "driver/rmt.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "led_strip.h" +#include "light.c" #include "sdkconfig.h" #include "wifi.c" static const char *TAG = "ScreenBgLight"; -#define RMT_TX_CHANNEL RMT_CHANNEL_0 -#define RMT_TX_GPIO 1 -#define STRIP_LED_NUMBER 1 - -#define EXAMPLE_CHASE_SPEED_MS (10) - -/** - * @brief Simple helper function, converting HSV color space to RGB color space - * - * Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV - * - */ -void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, - uint32_t *g, uint32_t *b) { - h %= 360; // h -> [0,360] - uint32_t rgb_max = v * 2.55f; - uint32_t rgb_min = rgb_max * (100 - s) / 100.0f; - - uint32_t i = h / 60; - uint32_t diff = h % 60; - - // RGB adjustment amount by hue - uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60; - - switch (i) { - case 0: - *r = rgb_max; - *g = rgb_min + rgb_adj; - *b = rgb_min; - break; - case 1: - *r = rgb_max - rgb_adj; - *g = rgb_max; - *b = rgb_min; - break; - case 2: - *r = rgb_min; - *g = rgb_max; - *b = rgb_min + rgb_adj; - break; - case 3: - *r = rgb_min; - *g = rgb_max - rgb_adj; - *b = rgb_max; - break; - case 4: - *r = rgb_min + rgb_adj; - *g = rgb_min; - *b = rgb_max; - break; - default: - *r = rgb_max; - *g = rgb_min; - *b = rgb_max - rgb_adj; - break; - } -} - void app_main(void) { - uint32_t red = 0; - uint32_t green = 0; - uint32_t blue = 0; - uint16_t hue = 0; - uint16_t start_rgb = 0; - - rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_GPIO, RMT_TX_CHANNEL); - // set counter clock to 40MHz - config.clk_div = 2; - - ESP_ERROR_CHECK(rmt_config(&config)); - ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0)); - - // install ws2812 driver - led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG( - STRIP_LED_NUMBER, (led_strip_dev_t)config.channel); - led_strip_t *strip = led_strip_new_rmt_ws2812(&strip_config); - if (!strip) { - ESP_LOGE(TAG, "install WS2812 driver failed"); - } - // Clear LED strip (turn off all LEDs) - ESP_ERROR_CHECK(strip->clear(strip, 100)); - // Show simple rainbow chasing pattern - ESP_LOGI(TAG, "LED Rainbow Chase Start"); - - connect_wifi(); - while (true) { - for (int i = 0; i < 3; i++) { - for (int j = i; j < STRIP_LED_NUMBER; j += 3) { - // Build RGB values - hue = j * 360 / STRIP_LED_NUMBER + start_rgb; - led_strip_hsv2rgb(hue, 100, 100, &red, &green, &blue); - // Write RGB values to strip driver - ESP_ERROR_CHECK(strip->set_pixel(strip, j, red, green, blue)); - } - // Flush RGB values to LEDs - ESP_ERROR_CHECK(strip->refresh(strip, 100)); - vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS)); - strip->clear(strip, 50); - vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS)); - } - start_rgb += 60; + light_init_strip(); + vTaskDelay(pdMS_TO_TICKS(10)); + light_play(light_mode_connection_wifi); + if (connect_wifi()) { + light_play(light_mode_idle); } } diff --git a/main/wifi.c b/main/wifi.c index a95a6c1..4d6e229 100644 --- a/main/wifi.c +++ b/main/wifi.c @@ -67,7 +67,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, } } -void wifi_init_sta(void) { +bool wifi_init_sta(void) { s_wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_netif_init()); @@ -111,10 +111,11 @@ void wifi_init_sta(void) { EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); - + bool connected = 0; /* xEventGroupWaitBits() returns the bits before the call returned, hence we * can test which event actually happened. */ if (bits & WIFI_CONNECTED_BIT) { + connected = 1; ESP_LOGI(WIFI_TAG, "connected to ap SSID:%s password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } else if (bits & WIFI_FAIL_BIT) { @@ -130,9 +131,10 @@ void wifi_init_sta(void) { ESP_ERROR_CHECK(esp_event_handler_instance_unregister( WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); vEventGroupDelete(s_wifi_event_group); + return connected; } -void connect_wifi(void) { +bool connect_wifi(void) { // Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || @@ -143,5 +145,5 @@ void connect_wifi(void) { ESP_ERROR_CHECK(ret); ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); - wifi_init_sta(); + return wifi_init_sta(); }