一、整体系统架构┌─────────────────────────────────────────────┐ │ Host MCU (dsPIC33 / STM32) │ │ │ │ ┌────────────┐ UART ┌──────────────┐ │ │ │ FreeRTOS │◀───────▶│ ESP8266 │ │ │ │ App Task │ │ AT Firmware │ │ │ └─────┬──────┘ └──────┬───────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────┐ ┌──────────────┐ │ │ │ MQTT API │ │ WiFi / TCP │ │ │ │ (Publish/ │ │ TLS(可选) │ │ │ │ Subscribe) │ │ │ │ │ └────────────┘ └──────────────┘ │ └─────────────────────────────────────────────┘ESP8266 只做通信业务逻辑全部在 MCU 端FreeRTOS二、FreeRTOS 任务划分任务优先级作用AT_Cmd_TaskHigh发送 AT 指令 解析响应AT_Recv_TaskHigh串口接收 UR 解析MQTT_Client_TaskMediumMQTT 连接 / 保活App_Publish_TaskLow业务数据上报App_Subscribe_TaskLow下行控制三、ESP8266 AT 指令基础ESP8266 固件 ≥ AT v2.2.0 才支持 MQTT常用 AT 指令ATRST ; 复位 ATCWMODE1 ; Station 模式 ATCWJAPSSID,PASSWORD ; 连接 WiFi ATCIPMUX0 ; 单连接 ATCIPSTARTTCP,broker.emqx.io,1883 ATMQTTUSERCFG0,1,client_id,user,password,0,0, ATMQTTCONN0,broker.emqx.io,1883,1 ATMQTTPUB0,topic,payload,1,0 ATMQTTSUB0,topic,1四、AT 驱动层设计FreeRTOS 安全写法1、AT 命令结构体typedefstruct{constchar*cmd;constchar*expect;uint32_ttimeout_ms;}at_cmd_t;2、AT 发送接口线程安全SemaphoreHandle_t at_mutex;boolAT_SendCmd(constat_cmd_t*at){xSemaphoreTake(at_mutex,portMAX_DELAY);HAL_UART_Transmit(huart1,(uint8_t*)at-cmd,strlen(at-cmd),100);HAL_UART_Transmit(huart1,(uint8_t*)\r\n,2,10);bool retAT_WaitResponse(at-expect,at-timeout_ms);xSemaphoreGive(at_mutex);returnret;}五、ESP8266 MQTT 封装1、MQTT 客户端结构体typedefstruct{charbroker[64];uint16_tport;charclient_id[32];charuser[32];charpassword[32];}mqtt_client_t;2、MQTT 连接boolMQTT_Connect(mqtt_client_t*cfg){charcmd[128];sprintf(cmd,ATMQTTUSERCFG0,1,\%s\,\%s\,\%s\,0,0,\\,cfg-client_id,cfg-user,cfg-password);if(!AT_SendCmd((at_cmd_t){cmd,OK,2000}))returnfalse;sprintf(cmd,ATMQTTCONN0,\%s\,%d,1,cfg-broker,cfg-port);returnAT_SendCmd((at_cmd_t){cmd,OK,5000});}3、MQTT 发布带 QoSboolMQTT_Publish(constchar*topic,constchar*payload,intqos){charcmd[256];sprintf(cmd,ATMQTTPUB0,\%s\,\%s\,%d,0,topic,payload,qos);returnAT_SendCmd((at_cmd_t){cmd,OK,3000});}4、MQTT 订阅boolMQTT_Subscribe(constchar*topic,intqos){charcmd[128];sprintf(cmd,ATMQTTSUB0,\%s\,%d,topic,qos);returnAT_SendCmd((at_cmd_t){cmd,OK,3000});}六、FreeRTOS 示例任务MQTT 客户端任务voidMQTT_Client_Task(void*arg){mqtt_client_tmqtt{.brokerbroker.emqx.io,.port1883,.client_idesp8266_freertos,.user,.password};while(1){if(!MQTT_Connect(mqtt)){vTaskDelay(pdMS_TO_TICKS(5000));continue;}MQTT_Subscribe(/device/ctrl,1);while(1){// 心跳MQTT_Publish(/device/ping,online,1);vTaskDelay(pdMS_TO_TICKS(30000));}}}业务发布任务如电源数据voidApp_Publish_Task(void*arg){charpayload[128];while(1){floatvoutRead_Voltage();floatioutRead_Current();snprintf(payload,sizeof(payload),{\v\:%.2f,\i\:%.2f},vout,iout);MQTT_Publish(/device/telemetry,payload,1);vTaskDelay(pdMS_TO_TICKS(1000));}}参考代码 基于Freertos的ESP8266 AT指令实现MQTTwww.youwenfan.com/contentcsv/72586.html七、ESP8266 主动推送URC处理ESP8266 会主动发MQTTSUBRECV:0,/device/ctrl,5,hello必须单独一个高优先级任务解析voidAT_Recv_Task(void*arg){uint8_tch;while(1){if(HAL_UART_Receive(huart1,ch,1,10)HAL_OK){Parse_AT_URC(ch);}}}voidParse_AT_URC(uint8_tch){staticcharbuf[256];staticuint16_tidx0;buf[idx]ch;if(strstr(buf,MQTTSUBRECV)){// 提取 topic / payloadHandle_MQTT_Command(buf);idx0;}}八、常见问题问题原因解决MQTT 断线ESP8266 自动掉线定时ATMQTTCONN?检查数据乱码波特率不匹配115200 8N1卡死AT 阻塞所有 AT 必须超时丢包URC 覆盖环形缓冲区OTA 失败Flash 不够用 ESP-12F九、推荐 AT 固件版本ESP8266 AT v2.2.0关闭回显ATE0
基于 FreeRTOS + ESP8266(AT 指令)+ MQTT的实现方案
一、整体系统架构┌─────────────────────────────────────────────┐ │ Host MCU (dsPIC33 / STM32) │ │ │ │ ┌────────────┐ UART ┌──────────────┐ │ │ │ FreeRTOS │◀───────▶│ ESP8266 │ │ │ │ App Task │ │ AT Firmware │ │ │ └─────┬──────┘ └──────┬───────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────┐ ┌──────────────┐ │ │ │ MQTT API │ │ WiFi / TCP │ │ │ │ (Publish/ │ │ TLS(可选) │ │ │ │ Subscribe) │ │ │ │ │ └────────────┘ └──────────────┘ │ └─────────────────────────────────────────────┘ESP8266 只做通信业务逻辑全部在 MCU 端FreeRTOS二、FreeRTOS 任务划分任务优先级作用AT_Cmd_TaskHigh发送 AT 指令 解析响应AT_Recv_TaskHigh串口接收 UR 解析MQTT_Client_TaskMediumMQTT 连接 / 保活App_Publish_TaskLow业务数据上报App_Subscribe_TaskLow下行控制三、ESP8266 AT 指令基础ESP8266 固件 ≥ AT v2.2.0 才支持 MQTT常用 AT 指令ATRST ; 复位 ATCWMODE1 ; Station 模式 ATCWJAPSSID,PASSWORD ; 连接 WiFi ATCIPMUX0 ; 单连接 ATCIPSTARTTCP,broker.emqx.io,1883 ATMQTTUSERCFG0,1,client_id,user,password,0,0, ATMQTTCONN0,broker.emqx.io,1883,1 ATMQTTPUB0,topic,payload,1,0 ATMQTTSUB0,topic,1四、AT 驱动层设计FreeRTOS 安全写法1、AT 命令结构体typedefstruct{constchar*cmd;constchar*expect;uint32_ttimeout_ms;}at_cmd_t;2、AT 发送接口线程安全SemaphoreHandle_t at_mutex;boolAT_SendCmd(constat_cmd_t*at){xSemaphoreTake(at_mutex,portMAX_DELAY);HAL_UART_Transmit(huart1,(uint8_t*)at-cmd,strlen(at-cmd),100);HAL_UART_Transmit(huart1,(uint8_t*)\r\n,2,10);bool retAT_WaitResponse(at-expect,at-timeout_ms);xSemaphoreGive(at_mutex);returnret;}五、ESP8266 MQTT 封装1、MQTT 客户端结构体typedefstruct{charbroker[64];uint16_tport;charclient_id[32];charuser[32];charpassword[32];}mqtt_client_t;2、MQTT 连接boolMQTT_Connect(mqtt_client_t*cfg){charcmd[128];sprintf(cmd,ATMQTTUSERCFG0,1,\%s\,\%s\,\%s\,0,0,\\,cfg-client_id,cfg-user,cfg-password);if(!AT_SendCmd((at_cmd_t){cmd,OK,2000}))returnfalse;sprintf(cmd,ATMQTTCONN0,\%s\,%d,1,cfg-broker,cfg-port);returnAT_SendCmd((at_cmd_t){cmd,OK,5000});}3、MQTT 发布带 QoSboolMQTT_Publish(constchar*topic,constchar*payload,intqos){charcmd[256];sprintf(cmd,ATMQTTPUB0,\%s\,\%s\,%d,0,topic,payload,qos);returnAT_SendCmd((at_cmd_t){cmd,OK,3000});}4、MQTT 订阅boolMQTT_Subscribe(constchar*topic,intqos){charcmd[128];sprintf(cmd,ATMQTTSUB0,\%s\,%d,topic,qos);returnAT_SendCmd((at_cmd_t){cmd,OK,3000});}六、FreeRTOS 示例任务MQTT 客户端任务voidMQTT_Client_Task(void*arg){mqtt_client_tmqtt{.brokerbroker.emqx.io,.port1883,.client_idesp8266_freertos,.user,.password};while(1){if(!MQTT_Connect(mqtt)){vTaskDelay(pdMS_TO_TICKS(5000));continue;}MQTT_Subscribe(/device/ctrl,1);while(1){// 心跳MQTT_Publish(/device/ping,online,1);vTaskDelay(pdMS_TO_TICKS(30000));}}}业务发布任务如电源数据voidApp_Publish_Task(void*arg){charpayload[128];while(1){floatvoutRead_Voltage();floatioutRead_Current();snprintf(payload,sizeof(payload),{\v\:%.2f,\i\:%.2f},vout,iout);MQTT_Publish(/device/telemetry,payload,1);vTaskDelay(pdMS_TO_TICKS(1000));}}参考代码 基于Freertos的ESP8266 AT指令实现MQTTwww.youwenfan.com/contentcsv/72586.html七、ESP8266 主动推送URC处理ESP8266 会主动发MQTTSUBRECV:0,/device/ctrl,5,hello必须单独一个高优先级任务解析voidAT_Recv_Task(void*arg){uint8_tch;while(1){if(HAL_UART_Receive(huart1,ch,1,10)HAL_OK){Parse_AT_URC(ch);}}}voidParse_AT_URC(uint8_tch){staticcharbuf[256];staticuint16_tidx0;buf[idx]ch;if(strstr(buf,MQTTSUBRECV)){// 提取 topic / payloadHandle_MQTT_Command(buf);idx0;}}八、常见问题问题原因解决MQTT 断线ESP8266 自动掉线定时ATMQTTCONN?检查数据乱码波特率不匹配115200 8N1卡死AT 阻塞所有 AT 必须超时丢包URC 覆盖环形缓冲区OTA 失败Flash 不够用 ESP-12F九、推荐 AT 固件版本ESP8266 AT v2.2.0关闭回显ATE0