From 5114cd3ec7f8ada955a911d6b56a4dba6a36286f Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 12 Nov 2022 22:42:03 +0800 Subject: [PATCH] feat(wifi): support wifi connection. --- .vscode/settings.json | 11 +++- main/CMakeLists.txt | 2 +- main/main.c | 7 +- main/wifi.c | 147 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 main/wifi.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 3842302..64c29b5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,14 @@ "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": "JTAG", + "files.associations": { + "*.ejs": "html", + "css": "postcss", + "scss": "postcss", + "*.cjson": "jsonc", + "*.wxss": "css", + "*.wxs": "javascript", + "*.inc": "c" + } } diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index e0287b7..aeb3410 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "main.c" +idf_component_register(SRCS "main.c" "wifi.c" INCLUDE_DIRS ".") \ No newline at end of file diff --git a/main/main.c b/main/main.c index 33bb208..b783f8b 100644 --- a/main/main.c +++ b/main/main.c @@ -12,8 +12,9 @@ #include "freertos/task.h" #include "led_strip.h" #include "sdkconfig.h" +#include "wifi.c" -static const char *TAG = "example"; +static const char *TAG = "ScreenBgLight"; #define RMT_TX_CHANNEL RMT_CHANNEL_0 #define RMT_TX_GPIO 1 @@ -98,6 +99,8 @@ void app_main(void) { 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) { @@ -115,6 +118,4 @@ void app_main(void) { } start_rgb += 60; } - - connect_wifi() } diff --git a/main/wifi.c b/main/wifi.c new file mode 100644 index 0000000..a95a6c1 --- /dev/null +++ b/main/wifi.c @@ -0,0 +1,147 @@ +/* WiFi station Example + + 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 + +#include "esp_event.h" +#include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "nvs_flash.h" + +/* The examples use WiFi configuration that you can set via project + configuration menu + + If you'd rather not, just change the below entries to strings with + the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" +*/ +#define EXAMPLE_ESP_WIFI_SSID "Ivan" +#define EXAMPLE_ESP_WIFI_PASS "ivanli.cc" +#define EXAMPLE_ESP_MAXIMUM_RETRY 5 + +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* 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 + +static const char* WIFI_TAG = "ScreenBgLight_WIFI"; + +static int s_retry_num = 0; + +static void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && + event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(WIFI_TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(WIFI_TAG, "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; + ESP_LOGI(WIFI_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void wifi_init_sta(void) { + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t instance_any_id; + esp_event_handler_instance_t instance_got_ip; + ESP_ERROR_CHECK(esp_event_handler_instance_register( + WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register( + IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip)); + + wifi_config_t wifi_config = { + .sta = + { + .ssid = EXAMPLE_ESP_WIFI_SSID, + .password = EXAMPLE_ESP_WIFI_PASS, + /* Setting a password implies station will connect to all security + * modes including WEP/WPA. However these modes are deprecated and + * not advisable to be used. Incase your Access point doesn't + * support WPA2, these mode can be enabled by commenting below + * line */ + .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, + .sae_pwe_h2e = WPA3_SAE_PWE_BOTH, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(WIFI_TAG, "wifi_init_sta finished."); + + /* 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(s_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) { + 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) { + ESP_LOGI(WIFI_TAG, "Failed to connect to SSID:%s, password:%s", + EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); + } else { + ESP_LOGE(WIFI_TAG, "UNEXPECTED EVENT"); + } + + /* The event will not be processed after unregister */ + ESP_ERROR_CHECK(esp_event_handler_instance_unregister( + IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister( + WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id)); + vEventGroupDelete(s_wifi_event_group); +} + +void connect_wifi(void) { + // Initialize NVS + esp_err_t ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ESP_LOGI(WIFI_TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(); +}