From 58111a25eed52da4c32b317b6a808bf00d3d7d0d Mon Sep 17 00:00:00 2001 From: Advaith Menon Date: Tue, 25 Nov 2025 06:56:10 -0500 Subject: [PATCH] Add Wi-Fi code * Deregister task_imu in hello_world_main * Create new task_wifi_time and register it in the entrypoint * Create helper to retrieve SSID/password from SD card (need to enable long filename support in idf.py menuconfig -> Component config -> FAT Filesystem support -> Long filename support * Add WiFi connection code --- .gitignore | 1 + main/CMakeLists.txt | 3 + main/hello_world_main.c | 30 +++-- main/task_wifi.c | 237 ++++++++++++++++++++++++++++++++++++++++ main/task_wifi.h | 8 ++ 5 files changed, 270 insertions(+), 9 deletions(-) create mode 100644 main/task_wifi.c create mode 100644 main/task_wifi.h diff --git a/.gitignore b/.gitignore index 5d362fb..dd6a001 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __pycache__/ build/ build_*_*/ sdkconfig +sdkconfig.old # idf-ci build run output build_summary_*.xml diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index c41f1c1..0dbaf7c 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -5,10 +5,13 @@ idf_component_register(SRCS "hello_world_main.c" "task_imu.c" "sdcardspi.c" "bmp_reader.c" + "task_wifi.c" INCLUDE_DIRS "." PRIV_REQUIRES esp_driver_gpio esp_driver_uart esp_driver_i2c esp_driver_spi esp_driver_sdspi + esp_wifi + nvs_flash fatfs) diff --git a/main/hello_world_main.c b/main/hello_world_main.c index bc2b430..31720e8 100644 --- a/main/hello_world_main.c +++ b/main/hello_world_main.c @@ -1,27 +1,25 @@ -/* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - */ - #include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" +#include "esp_log.h" -/* custom headers we made!!*/ #include "task_imu.h" #include "pins.h" #include "task_lcd.h" #include "task_button.h" +#include "task_wifi.h" #include "sdcardspi.h" int gt_global_sdsupport; +static const char *TAG = "hello_world_main"; + void app_main(void) { + TaskHandle_t wifi_taskh; printf("Hello world!\n"); ESP_ERROR_CHECK(gpio_reset_pin(PIN_BUTTON_WHITE)); @@ -53,9 +51,23 @@ void app_main(void) gt_btn_setup(); gt_global_sdsupport = task_sdcard(); + + /* register the wifi task */ + if (xTaskCreate( + task_wifi_time, + "wifi.ntime", + 4096, + NULL, + tskIDLE_PRIORITY, + &wifi_taskh) != pdPASS) { + ESP_LOGW(TAG, "failed to initialize wifi time update!"); + } + + + /* start the main gui thread which starts all else */ - // lcd_task(); - task_imu_all(NULL); + lcd_task(); + //task_imu_all(NULL); /* for (int i = 10; i >= 0; i--) { printf("Restarting in %d seconds...\n", i); diff --git a/main/task_wifi.c b/main/task_wifi.c new file mode 100644 index 0000000..c68bea4 --- /dev/null +++ b/main/task_wifi.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_log.h" +#include "nvs_flash.h" +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include "lwip/netdb.h" +#include "lwip/dns.h" +#include "sdkconfig.h" + +#include "pins.h" +#include "sdcardspi.h" + +#include "task_wifi.h" + +#define WIFI_SSID_SIZE 16 +#define WIFI_PASS_SIZE 32 + + +#define EXAMPLE_ESP_MAXIMUM_RETRY 3 + +#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_HUNT_AND_PECK +#define EXAMPLE_H2E_IDENTIFIER "" + +#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK + + +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +/* Constants that aren't configurable in menuconfig */ +#define WEB_SERVER "timehttp.bp4k.net" +#define WEB_PORT "80" +#define WEB_PATH "/" + +static const char *TAG = "task_wifi"; + +static const char *REQUEST = "GET " WEB_PATH " HTTP/1.0\r\n" + "Host: "WEB_SERVER":"WEB_PORT"\r\n" + "User-Agent: esp-idf/1.0 esp32\r\n" + "\r\n"; + +static int s_retry_num = 0; + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; + +/* local fns */ +int get_wifi_creds(char *username, size_t usz, char *password, size_t psz); +void wifi_init_sta(char *username, char *password); + + +void task_wifi_time(void *pvParams) { + char wifi_ssid[WIFI_SSID_SIZE]; + char wifi_pass[WIFI_PASS_SIZE]; + + /* simply get the SSID and passwd */ + if (!gt_global_sdsupport) { + ESP_EARLY_LOGE(TAG, "Cannot obtain wifi password since no sd support"); + vTaskDelete(NULL); + } + + if (get_wifi_creds(wifi_ssid, WIFI_SSID_SIZE, + wifi_pass, WIFI_PASS_SIZE)) + vTaskDelete(NULL); + + ESP_EARLY_LOGI(TAG, "Wi-Fi SSID: <<%s>>", wifi_ssid); + ESP_EARLY_LOGI(TAG, "Wi-Fi Password: <<%s>>", wifi_pass); + + + 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); + + if (CONFIG_LOG_MAXIMUM_LEVEL > CONFIG_LOG_DEFAULT_LEVEL) { + /* If you only want to open more logs in the wifi module, you need to make the max level greater than the default level, + * and call esp_log_level_set() before esp_wifi_init() to improve the log level of the wifi module. */ + //esp_log_level_set("wifi", CONFIG_LOG_MAXIMUM_LEVEL); + } + + ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); + wifi_init_sta(wifi_ssid, wifi_pass); + + vTaskDelete(NULL); +} + + +int get_wifi_creds(char *uname, size_t usz, char *pw, size_t psz) { + int nzec = 0; + FILE *fp = fopen(SD_PATH("config/wifi.conf"), "rb"); + + int i; + + if (!fp) { + perror("fopen"); + ESP_EARLY_LOGE(TAG, "cannot obtain wifi ssid and password"); + nzec = 1; + goto err_no_fclose; + } + + i = 0; + while ( + i < usz - 1 + && fread(&uname[i], sizeof(char), 1, fp) + && uname[i] != '\n') + ++i; + + if (uname[i] == '\n') + uname[i] = '\0'; + else { + ESP_EARLY_LOGE(TAG, "invalid wifi config, endl after ssid missing"); + nzec = 1; + goto err_fclose; + } + + i = 0; + while ( + i < psz - 1 + && fread(&pw[i], sizeof(char), 1, fp) + && pw[i] != '\n') + ++i; + + if (pw[i] == '\n') + pw[i] = '\0'; + else { + ESP_EARLY_LOGW(TAG, "wifi password might be truncated"); + pw[psz - 1] = '\0'; + } + + +err_fclose: + fclose(fp); +err_no_fclose: + return nzec; +} + + +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(TAG, "retry to connect to the AP"); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + ESP_LOGI(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(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(char *username, char *password) { + 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 = username, + .password = password, + */ + /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8). + * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value + * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to + * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. + */ + .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, + .sae_pwe_h2e = ESP_WIFI_SAE_MODE, + .sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER, + }, + }; + strncpy((char *) wifi_config.sta.ssid, username, 32); + strncpy((char *) wifi_config.sta.password, password, 64); + 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_EARLY_LOGI(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_EARLY_LOGI(TAG, "connected to ap"); + } else if (bits & WIFI_FAIL_BIT) { + ESP_EARLY_LOGI(TAG, "Failed to connect to SSID"); + } else { + ESP_EARLY_LOGE(TAG, "UNEXPECTED EVENT"); + } +} diff --git a/main/task_wifi.h b/main/task_wifi.h new file mode 100644 index 0000000..87008fb --- /dev/null +++ b/main/task_wifi.h @@ -0,0 +1,8 @@ +#pragma once + +#ifndef __TASK_WIFI_H__ +#define __TASK_WIFI_H__ + +void task_wifi_time(void *pvParams); + +#endif -- 2.47.3