1. 程式人生 > >ESP32無線模組開發

ESP32無線模組開發

最近在做一款低功耗裝置,SoC選用上海樂鑫科技的一款ESP32 wifi模組。樂鑫官網

ESP32簡介

ESP32是集成了2.4GHz WiFi和藍芽雙模組的單晶片方案,專為移動裝置、可穿戴裝置和物聯網應用而設計。在功能簡單的使用環境下具有很好的實用性,且操作簡單,ESP32提供針對不同環境下的低功耗方案,功能框圖如下:
1
ESP32提供了1296K片上儲存器地址空間,19704K片外儲存器地址空間。
* 片上儲存包括:448K的內部ROM,520K的內部SRAM和少量的RTC Memory
* 片外儲存器包括:最大支援16M片外SPI Flash和最大支援8M的片外SPI SRAM。

ESP32提供了低功耗管理功能,可配置裝置進入省點模式,具體模式如下圖所示:
2

不同模式下的功耗參考值:
4

樂鑫官方提供了詳細的設計資料和軟硬體參考用例,資源下載樂鑫官方資料下載連結

軟體開發環境

搭建軟體開發環境,主要分為以下三步:

  • esp32開發板
  • esp-if SDK開發包
  • 韌體燒寫工具

esp32開發板

可根據樂鑫官方提供的硬體設計參考自己設計開發板,樂鑫提供了整合的開發板,檢視連結,效果圖如下所示
5

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燒寫工具下載連結
5
執行 ESPFlashDownloadTool_v3.4.4.exe 如下圖所示,選擇esp32,連線串列埠,開始下載韌體
6
7

專案功能開發

功能需求如下:

(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手冊進行相應配置。