一、功能流程解析
1.初始化传感器
#define DHTPIN 4 // 根据 ESP32 实际引脚调整
#define DHTTYPE DHTesp::DHT11
#define RESET_PIN 0 // BOOT 按钮引脚
dht.setup(DHTPIN, DHTesp::DHT11);
2.启动独立采集任务
FreeRTOS 创建 dhtTask 任务(优先级 2),每 2秒执行一次:
调用 dht.getTempAndHumidity() 读取原始温湿度数据。
通过 isnan() 校验数据有效性,过滤异常值(如传感器断线)。
通过 esp_task_wdt_reset() 函数定期重置看门狗定时器,以防止系统超时。
//调用 dht.getTempAndHumidity() 读取原始温湿度数据。
TempAndHumidity data = dht.getTempAndHumidity();
//isnan部分,具体范围与阿里云平台有关
if (!isnan(data.temperature) && !isnan(data.humidity)) {
xSemaphoreTake(dataMutex, portMAX_DELAY);
sensorData.temperature = data.temperature;
sensorData.humidity = data.humidity;
xSemaphoreGive(dataMutex);
}
3.WiFi 连接
首次启动:
进入 AP 配网模式(SSID: AutoConnectAP),等待用户通过网页配置 WiFi
用户提交 SSID 和密码后,尝试连接目标热点。
非首次启动:
自动使用存储的凭证尝试重连。
若连接失败,触发 ESP.restart() 重启设备。
for(;;) {
// WiFi 连接管理
if (!netStatus.wifiConnected) {
if (!wifiManager.autoConnect("AutoConnectAP")) {
ESP.restart();//强制重启 ESP 设备
}
netStatus.wifiConnected = true;
}
4.MQTT 连接
调用 mqttClient.connect() 建立 MQTT 连接。
// MQTT 连接管理
if (!netStatus.mqttConnected && netStatus.wifiConnected) {
if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {// 尝试MQTT连接
netStatus.mqttConnected = true;// 连接成功则更新标志位
}
}
5.MQTT 发布
// 数据上报
if (netStatus.mqttConnected) {// 检查 MQTT 是否已连接
static uint32_t lastSend = 0;
if (millis() - lastSend > 5000) {// 每隔 5 秒触发一次
SensorData localData;
xSemaphoreTake(dataMutex, portMAX_DELAY);
memcpy(&localData, &sensorData, sizeof(SensorData));
xSemaphoreGive(dataMutex);
// 构建 JSON 数据
DynamicJsonDocument doc(200);
doc["id"] = millis();
doc["version"] = "1.0";
doc["method"] = "thing.event.property.post";
JsonObject params = doc.createNestedObject("params");
params["Temperature"] = localData.temperature;
params["Humidity"] = localData.humidity;
char payload[200];
serializeJson(doc, payload);
mqttClient.publish(TOPIC_PUBLISH, payload);
lastSend = millis();// 更新上次发送时间
}
mqttClient.loop();// 处理 MQTT 心跳和消息
}
二、阿里云iot平台相关
1.创建产品
品类选择自定义品类,产品名称随意。
2.添加设备
选择刚刚创建的产品,名字随意。
3.复制相关参数;
DHTesp dht;
// 共享数据结构
SemaphoreHandle_t dataMutex;
struct SensorData {
float temperature = 0;
float humidity = 0;
} sensorData;
struct NetworkStatus {
bool wifiConnected = false;
bool mqttConnected = false;
} netStatus;
void dhtTask(void *pvParameters);
void networkTask(void *pvParameters);
void setup() {
Serial.begin(115200);
// 初始化 DHT 传感器
dht.setup(DHTPIN, DHTesp::DHT11);
// 看门狗配置
esp_task_wdt_config_t wdt_config = {
.timeout_ms = 20000,
.trigger_panic = true
};
ESP_ERROR_CHECK(esp_task_wdt_reconfigure(&wdt_config));
ESP_ERROR_CHECK(esp_task_wdt_add(NULL));
// 创建互斥量
dataMutex = xSemaphoreCreateMutex();
// 创建任务
xTaskCreate(dhtTask, "DHT", 4096, NULL, 2, NULL);
xTaskCreate(networkTask, "Network", 8192, NULL, 1, NULL);
// MQTT 配置
mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
espClient.setTimeout(2000);
// 重置按钮初始化
pinMode(RESET_PIN, INPUT_PULLUP);
}
void loop() {
esp_task_wdt_reset();
delay(1000);
}
// DHT11 温湿度采集任务
void dhtTask(void *pvParameters) {
ESP_ERROR_CHECK(esp_task_wdt_add(NULL));
for(;;) {
TempAndHumidity data = dht.getTempAndHumidity();
if (!isnan(data.temperature) && !isnan(data.humidity)) {
xSemaphoreTake(dataMutex, portMAX_DELAY);
sensorData.temperature = data.temperature;
sensorData.humidity = data.humidity;
xSemaphoreGive(dataMutex);
}
esp_task_wdt_reset();
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
// 网络任务
void networkTask(void *pvParameters) {
WiFiManager wifiManager;
wifiManager.setTimeout(180);
// 检查重置按钮
if (digitalRead(RESET_PIN) == LOW) {
wifiManager.resetSettings();
ESP.restart();
}
for(;;) {
// WiFi 连接管理
if (!netStatus.wifiConnected) {
if (!wifiManager.autoConnect("AutoConnectAP")) {
ESP.restart();
}
netStatus.wifiConnected = true;
}
// MQTT 连接管理
if (!netStatus.mqttConnected && netStatus.wifiConnected) {
if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
netStatus.mqttConnected = true;
}
}
// 数据上报
if (netStatus.mqttConnected) {
static uint32_t lastSend = 0;
if (millis() - lastSend > 5000) {
SensorData localData;
xSemaphoreTake(dataMutex, portMAX_DELAY);
memcpy(&localData, &sensorData, sizeof(SensorData));
xSemaphoreGive(dataMutex);
// 构建 JSON 数据
DynamicJsonDocument doc(200);
doc["id"] = millis();
doc["version"] = "1.0";
doc["method"] = "thing.event.property.post";
JsonObject params = doc.createNestedObject("params");
params["Temperature"] = localData.temperature;
params["Humidity"] = localData.humidity;
char payload[200];
serializeJson(doc, payload);
mqttClient.publish(TOPIC_PUBLISH, payload);
lastSend = millis();
}
mqttClient.loop();
}
delay(10);
}
}