最近在做一款低功耗设备,SoC选用上海乐鑫科技的一款ESP32 wifi模组。乐鑫官网。
ESP32是集成了2.4GHz WiFi和蓝牙双模块的单芯片方案,专为移动设备、可穿戴设备和物联网应用而设计。在功能简单的使用环境下具有很好的实用性,且操作简单,ESP32提供针对不同环境下的低功耗方案,功能框图如下:
ESP32提供了1296K片上存储器地址空间,19704K片外存储器地址空间。
* 片上存储包括:448K的内部ROM,520K的内部SRAM和少量的RTC Memory
* 片外存储器包括:最大支持16M片外SPI Flash和最大支持8M的片外SPI SRAM。
ESP32提供了低功耗管理功能,可配置设备进入省点模式,具体模式如下图所示:
乐鑫官方提供了详细的设计资料和软硬件参考用例,资源下载乐鑫官方资料下载链接。
搭建软件开发环境,主要分为以下三步:
可根据乐鑫官方提供的硬件设计参考自己设计开发板,乐鑫提供了集成的开发板,查看链接,效果图如下所示
(1)下载源码
SDK源码下载链接esp-if,目录树如下所示:
Linux@esp32_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手册进行相应配置。