ESP32無線模組開發
最近在做一款低功耗裝置,SoC選用上海樂鑫科技的一款ESP32 wifi模組。樂鑫官網。
ESP32簡介
ESP32是集成了2.4GHz WiFi和藍芽雙模組的單晶片方案,專為移動裝置、可穿戴裝置和物聯網應用而設計。在功能簡單的使用環境下具有很好的實用性,且操作簡單,ESP32提供針對不同環境下的低功耗方案,功能框圖如下:
ESP32提供了1296K片上儲存器地址空間,19704K片外儲存器地址空間。
* 片上儲存包括:448K的內部ROM,520K的內部SRAM和少量的RTC Memory
* 片外儲存器包括:最大支援16M片外SPI Flash和最大支援8M的片外SPI SRAM。
ESP32提供了低功耗管理功能,可配置裝置進入省點模式,具體模式如下圖所示:
不同模式下的功耗參考值:
樂鑫官方提供了詳細的設計資料和軟硬體參考用例,資源下載樂鑫官方資料下載連結。
軟體開發環境
搭建軟體開發環境,主要分為以下三步:
- esp32開發板
- esp-if SDK開發包
- 韌體燒寫工具
esp32開發板
可根據樂鑫官方提供的硬體設計參考自己設計開發板,樂鑫提供了整合的開發板,檢視連結,效果圖如下所示
esp-if SDK開發包
(1)下載原始碼
SDK原始碼下載連結esp-if,目錄樹如下所示:
[email protected]_sdk$ tree -L 1
.
├── add_path.sh
├── components
├── CONTRIBUTING.rst
├── docs
├── examples
├── Kconfig
├── LICENSE
├── make
├── README.md
└── tools
5 directories, 5 files
(2)配置環境變數,在~/.bashrc檔案末尾增加:
export IDF_PATH=/home/test/share/code/esp32/source
export PATH=/home/test/share/code /esp32/toolchain/xtensa-esp32-elf/bin:$PATH
(3)編譯原始碼和example
進入examples/wifi/wpa2_enterprise/目錄
# 編譯選項配置
make menuconfig
# 開始編譯
make
韌體燒寫工具
下載ESP32燒寫工具下載連結
執行 ESPFlashDownloadTool_v3.4.4.exe 如下圖所示,選擇esp32,連線串列埠,開始下載韌體
專案功能開發
功能需求如下:
(1)裝置啟動後初始狀態自動進入AP模式,熱點為esp_xxx(可選mac地址後4個位元組),無密碼
(2)客戶端軟體支援配置AP連線,併發送路由器wifi資訊到裝置
(3)裝置接收到wifi資訊後,退出AP模式,進入station模式開始連線wifi
(4)裝置無操作時進入睡眠模式,間隔30s喚醒
(5)裝置支援外部按鍵喚醒,喚醒後自動連線wifi
部分程式碼如下(參考SDK的example):
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = "test_ap",
.password = "12345678",
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EXAMPLE_EAP_ID, strlen(EXAMPLE_EAP_ID)) );
if (EXAMPLE_EAP_METHOD == EAP_PEAP || EXAMPLE_EAP_METHOD == EAP_TTLS) {
ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EXAMPLE_EAP_USERNAME, strlen(EXAMPLE_EAP_USERNAME)) );
ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EXAMPLE_EAP_PASSWORD, strlen(EXAMPLE_EAP_PASSWORD)) );
}
ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_enable() );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void wpa2_enterprise_task(void *pvParameters)
{
tcpip_adapter_ip_info_t ip;
memset(&ip, 0, sizeof(tcpip_adapter_ip_info_t));
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
false, true, portMAX_DELAY);
ESP_LOGI(TAG, "Connected to AP");
if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip) == 0) {
ESP_LOGI(TAG, "~~~~~~~~~~~");
ESP_LOGI(TAG, "IP:"IPSTR, IP2STR(&ip.ip));
ESP_LOGI(TAG, "MASK:"IPSTR, IP2STR(&ip.netmask));
ESP_LOGI(TAG, "GW:"IPSTR, IP2STR(&ip.gw));
ESP_LOGI(TAG, "~~~~~~~~~~~");
}
//esp_wifi_set_ps(WIFI_PS_MODEM);
/* test */
//socket_svr_task();
//http_test_task();
uint64_t sleep_time = 30;
esp_deep_sleep(sleep_time * 1000000);
}
void app_main()
{
nvs_flash_init();
initialise_wifi();
xTaskCreate(&wpa2_enterprise_task, "wpa2_enterprise_task", 4096, NULL, 5, NULL);
}
更多功能可根據sdk手冊進行相應配置。