1. ESP32与开发环境搭建

ESP32作为一款性价比极高的物联网开发板,凭借双核处理器、WiFi/蓝牙双模通信和丰富的外设接口,已经成为智能家居网关的首选方案。我实际测试过多种开发方式,发现VSCode+PlatformIO的组合最能提升开发效率。这个方案不仅支持代码自动补全和语法检查,还能一键管理第三方库依赖,比传统的Arduino IDE更适合复杂项目开发。

安装过程非常简单:首先从官网下载VSCode,安装完成后在扩展商店搜索PlatformIO插件。这里有个小技巧 - 建议同时安装C/C++扩展,可以获得更好的代码提示。PlatformIO初始化时会自动下载工具链,如果遇到网络问题,可以尝试修改platformio.ini中的下载源:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
platform_packages = 
    platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git

2. FreeRTOS多任务系统实战

2.1 任务创建与管理

FreeRTOS的多任务特性让ESP32可以同时处理传感器采集、网络通信等并行需求。创建任务时需要注意堆栈大小设置 - 太大会浪费内存,太小会导致栈溢出。我的经验值是简单任务给2048字节,复杂任务建议4096字节以上:

void sensorTask(void *pvParameters) {
    for(;;) {
        float temp = readTemperature();  // 模拟传感器读取
        xQueueSend(tempQueue, &temp, portMAX_DELAY);
        vTaskDelay(pdMS_TO_TICKS(1000)); // 1秒间隔
    }
}

void setup() {
    tempQueue = xQueueCreate(5, sizeof(float));
    xTaskCreate(sensorTask, "Sensor", 4096, NULL, 1, NULL);
}

2.2 任务间通信

项目中我常用三种通信方式:

  1. 队列:适合生产者-消费者模式,如传感器数据传递
  2. 信号量:资源互斥访问,如SPI总线控制
  3. 事件组:多任务同步触发,如系统状态通知

这里有个实际案例:当WiFi连接成功后,通过事件组同时唤醒数据处理和上传任务:

EventGroupHandle_t wifiEventGroup;
const int WIFI_CONNECTED_BIT = BIT0;

void wifiTask(void *pvParameters) {
    connectToWiFi();
    xEventGroupSetBits(wifiEventGroup, WIFI_CONNECTED_BIT);
}

void dataTask(void *pvParameters) {
    xEventGroupWaitBits(wifiEventGroup, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, portMAX_DELAY);
    // 开始处理数据
}

3. WiFi智能网关开发

3.1 双模网络配置

智能家居网关需要同时支持AP和STA模式:当无法连接路由器时自动切换为热点模式。这个功能通过以下代码实现:

void initWiFi() {
    WiFi.mode(WIFI_AP_STA);
    WiFi.softAP("ESP32-Gateway", "password");
    WiFi.begin("home_ssid", "home_password");
    
    if(WiFi.waitForConnectResult() != WL_CONNECTED) {
        startCaptivePortal(); // 启动网页配置界面
    }
}

3.2 网页控制界面

基于ESPAsyncWebServer库可以构建响应式控制页面。我推荐使用SPIFFS存储网页资源,比硬编码HTML更易维护:

AsyncWebServer server(80);

void setup() {
    SPIFFS.begin();
    server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("index.html");
    server.on("/api/led", HTTP_POST, [](AsyncWebServerRequest *request){
        String state = request->arg("state");
        digitalWrite(LED_PIN, state == "on" ? HIGH : LOW);
        request->send(200, "text/plain", "OK");
    });
    server.begin();
}

4. 低功耗优化技巧

4.1 动态频率调整

ESP32支持80/160MHz CPU频率调节。在网关空闲时段降低频率可显著减少功耗:

#include "esp_pm.h"

void setCpuFrequency() {
    esp_pm_config_t pm_config = {
        .max_freq_mhz = 80, // 日常使用80MHz
        .min_freq_mhz = 10, // 空闲时降至10MHz
        .light_sleep_enable = true
    };
    esp_err_t ret = esp_pm_configure(&pm_config);
}

4.2 深度睡眠唤醒

对于电池供电的场景,我通常使用定时唤醒+GPIO中断的组合方案。这个配置下整机功耗可以降至10μA以下:

#define BUTTON_PIN 0

void setup() {
    esp_sleep_enable_timer_wakeup(3600 * 1000000); // 每小时唤醒一次
    esp_sleep_enable_ext0_wakeup(BUTTON_PIN, LOW); // 按键唤醒
    esp_deep_sleep_start();
}

在实际部署中发现,启用RF校准功能会额外消耗约20mA电流。对于固定安装的设备,可以在platformio.ini中关闭该功能:

build_flags = 
    -DCONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=n

更多推荐