ESP8266 连接 MQTT
主控芯片:MM32F2377 (MB-039)
WiFi 适配器:ESP8266
开发环境:IAR 7.80.4
MQTT 模拟服务器:MQTT.fx
MQTT
MQTT is an OASIS standard messaging protocol for the Internet of Things (IoT). It is designed as an extremely lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth. MQTT today is used in a wide variety of industries, such as automotive, manufacturing, telecommunications, oil and gas, etc.
—— mqtt.org
MQTT(Message Queuing Telemetry Transport) 消息队列遥测传输协议,是一个基于客户端-服务器的消息发布/订阅传输协议。主要的概念有5个:
- Broker 代理:MQTT 服务器
- Publish 发布者:客户端
- Subscribe 订阅者:客户端,可订阅多个 topic
- Topic 主题:消息的类型,订阅主题之后就可以收到该 topic 的消息内容即 payload
- Payload 消息内容:具体的内容
MQTT 模拟服务器:
- EMQ MQTT X
- MQTT.fx
MQTT 模拟服务器客户端使用
我在这里使用的是第二个 MQTT.fx,用这个客户端模拟一下 MQTT 的 Publish/Subscribe。
- 首先在 EMQ 官网上找到 MQTT 接入信息,主要是 Broker 和 TCP 端口号 在接下来的模拟服务器使用中,Broker Address 可以直接用
broker-cn.emqx.io
,也可以到查询网上查找对应的 IP 地址:47.111.117.220
EMQ 分为在国内有专门的服务器,连接更方便一些,国外的 Broker Address 是broker.emqx.io
- 打开 MQTT.fx,点击齿轮状的设置按钮,填写 Broker Address,Port 等,再到 User Credentials 里填写用户名和密码,OK,Connect
- 连接成功后,发布消息:填 topic,我这里 topic 叫 esp8266,以 json 格式进行发送,点击 Publish
- 去订阅消息,切换到 Subscribe,订阅 esp8266 这个 topic,然后再发布消息,就可以在这里看到了
ESP8266 + MQTT
ESP8266 的介绍以及基本使用可查看上一篇 CSDN 「Rose Island」MM32F3277 + ESP8266 使用指南(1. 实现 TCP Client 透传)。
首先需要确认 AT 指令集具有 MQTT 指令:
- 乐鑫官方 AT 下载地址
- Ai-thinker AT 下载地址 (选择 ESP8266 MQTT 默认透传 AT 固件)
具体的 MQTT AT 指令集可查阅:
- ESP MQTT AT Commands
ESP8266 MQTT 配置指令
- 配置 STA 模式:
AT+CWMODE=1
- 连接路由器:
AT+CWJAP="wifiName","wifiPsd"
- 配置 MQTT 属性:
AT+MQTTUSERCFG=0,1,"clientID","username","password",0,0,""
- 连接制定的 MQTT broker:
AT+MQTTCONN=0,"47.111.117.220",1883,0
- 查询 MQTT 连接状态:
AT+MQTTCONN?
- 订阅 topic 数据:
AT+MQTTSUB=0,"topicName",1
- 发布 topic 数据:
AT+MQTTPUB=0,"topicName","payload",1,0
MM32F3277 + ESP8266 + MQTT
这里放的是与 MQTT 相关的函数,ESP8266 连网和 TCP 连接等函数可见「Rose Island」MM32F3277 + ESP8266 使用指南(1. 实现 TCP Client 透传)。
esp8266.c
/// @brief Configure ESP8266 MQTT parameters./// @param clientId: Client ID num./// @param username: MQTT server username to log in MQTT broker./// @param psd: MQTT server password to log in MQTT broker./// @param scheme: Verification methods./// @retval None.voidESP8266_MQTT_Init(char* clientId,char* username,char* psd, ESP8266_MQTT_Scheme_Typedef scheme){
ESP8266_MQTT_InitStruct.ipAddr.mqttIPAddr0 = ESP8266_MQTT_HOST_IPADDR_0;
ESP8266_MQTT_InitStruct.ipAddr.mqttIPAddr1 = ESP8266_MQTT_HOST_IPADDR_1;
ESP8266_MQTT_InitStruct.ipAddr.mqttIPAddr2 = ESP8266_MQTT_HOST_IPADDR_2;
ESP8266_MQTT_InitStruct.ipAddr.mqttIPAddr3 = ESP8266_MQTT_HOST_IPADDR_3;
ESP8266_MQTT_InitStruct.port =(uint32_t)ESP8266_MQTT_PORT;
ESP8266_MQTT_InitStruct.clientID = clientId;
ESP8266_MQTT_InitStruct.username = username;
ESP8266_MQTT_InitStruct.password = psd;
ESP8266_MQTT_InitStruct.scheme = scheme;
ESP8266_MQTT_InitStruct.mqttStatus = NO_INIT;}/// @brief Connect with MQTT server./// @param clientId: Client ID num./// @param username: MQTT server username to log in MQTT broker./// @param psd: MQTT server password to log in MQTT broker./// @param scheme: Verification methods./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_Connect_MQTT(char* clientId,char* username,char* psd, ESP8266_MQTT_Scheme_Typedef scheme){ESP8266_MQTT_Init(clientId, username, psd, scheme);char*cmd =(char*)malloc(256);sprintf(cmd,"AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", clientId, username, psd);if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){printf("Error: Fail to Configure MQTT \n");return ESP8266_ERROR;}else{
ESP8266_MQTT_InitStruct.mqttStatus = USERCFG_SET;printf("OK: Configure MQTT successfully \n");}sprintf(cmd,"AT+MQTTCONN=0,\"%d.%d.%d.%d\",%d,0", ESP8266_MQTT_HOST_IPADDR_0, ESP8266_MQTT_HOST_IPADDR_1, ESP8266_MQTT_HOST_IPADDR_2, ESP8266_MQTT_HOST_IPADDR_3, ESP8266_MQTT_PORT);if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){
ESP8266_MQTT_InitStruct.mqttStatus = DISCONNECTED;printf("Error: Fail to Connect MQTT \n");return ESP8266_ERROR;}else{
ESP8266_MQTT_InitStruct.mqttStatus = CONNECTED;printf("OK: Connect MQTT successfully \n");}return ESP8266_OK;}/// @brief Check MQTT client state./// @param None./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_Check_MQTT(){char*cmd ="AT+MQTTCONN?";if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){// printf("Error: Fail to Connect MQTT \n");return ESP8266_ERROR;}else{// printf("OK: Connect MQTT successfully \n");}return ESP8266_OK;}/// @brief Subscribe topic from MQTT server./// @param subTopic: Subscribed topic name./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_MQTT_SUB(char* subTopic){char*cmd =(char*)malloc(strlen("AT+MQTTSUB=0,\"%s\",1")+strlen(subTopic));sprintf(cmd,"AT+MQTTSUB=0,\"%s\",1", subTopic);if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){
ESP8266_MQTT_InitStruct.mqttStatus = CONNECTED_NO_SUB;printf("Error: Fail to Subscribe topic \n");return ESP8266_ERROR;}else{
ESP8266_MQTT_InitStruct.mqttStatus = CONNECTED_AND_SUB;printf("OK: Subscribe topic successfully \n");}return ESP8266_OK;}/// @brief Unsubscribe topic from MQTT server./// @param subTopic: Unsubscribed topic name./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_MQTT_UNSUB(char* subTopic){char*cmd =(char*)malloc(strlen("AT+MQTTUNSUB=0,\"\"")+strlen(subTopic));sprintf(cmd,"AT+MQTTUNSUB=0,\"%s\"", subTopic);if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){
ESP8266_MQTT_InitStruct.mqttStatus = CONNECTED_NO_SUB;printf("Error: Fail to Subscribe topic \n");return ESP8266_ERROR;}else{
ESP8266_MQTT_InitStruct.mqttStatus = CONNECTED_AND_SUB;printf("OK: Subscribe topic successfully \n");}return ESP8266_OK;}/// @brief Publish topic to MQTT server./// @param subTopic: Publish topic name./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_MQTT_PUB(char* pubTopic,char* data){char*cmd =(char*)malloc(strlen("AT+MQTTPUB=0,\"\",\"\",1,0")+strlen(pubTopic)+strlen(data));sprintf(cmd,"AT+MQTTPUB=0,\"%s\",\"%s\",1,0", pubTopic, data);if(ESP8266_Send_AT_Command_Times(cmd,"OK",0xffff,2)){printf("Error: Fail to Publish topic \n");return ESP8266_ERROR;}else{printf("OK: Publish topic successfully \n");}return ESP8266_OK;}/// @brief Disconnect with MQTT server./// @param None./// @retval ESP8266 OK or ERROR.
ESP8266_Error_Typedef ESP8266_MQTT_CLEAN(){char*cmd ="AT+MQTTCLEAN=0";if(ESP8266_Send_AT_Command_Times(cmd,"OK\r\n",0xffff,2)){printf("Error: Fail to Disconnect MQTT \n");return ESP8266_ERROR;}else{
ESP8266_MQTT_InitStruct.mqttStatus = NO_INIT;printf("OK: Disconnect MQTT successfully \n");}return ESP8266_OK;}/// @brief Send key-value to MQTT./// @param dataSend: The whole key-value./// @param deviceId: Device id./// @param deviceType: Device type./// @param dataType: Data type./// @param dataValue: Data value./// @retval None.voidESP8266_Data_Send(char*dataSend,char*deviceId,char*deviceType,char*dataType,float dataValue){sprintf(dataSend,"{\r\n\"device_id\":\"%s\",\r\n\"device_type\":\"%s\",\r\n\"data_type\":\"%s\",\r\n\"data_value\":\"%.2f\"\r\n}",
deviceId, deviceType, dataType, dataValue);printf("data sent is %s \n", dataSend);}
esp8266.h
typedefenum{
NO_INIT =(uint8_t)0,
USERCFG_SET =(uint8_t)1,
CONNCFG_SET =(uint8_t)2,
DISCONNECTED =(uint8_t)3,
CONNECTED =(uint8_t)4,
CONNECTED_NO_SUB =(uint8_t)5,
CONNECTED_AND_SUB =(uint8_t)6} ESP8266_MQTT_Status_Typedef;typedefenum{
NO_TLS =(uint8_t)1,
TLS_NO_CA =(uint8_t)2,
TLS_SERVICE_CA =(uint8_t)3,
TLS_CLIENT_CA =(uint8_t)4,
TLS_SERVICE_CLIENT_CA =(uint8_t)5,
WS_TCP =(uint8_t)6,
WSS_NO_CA =(uint8_t)7,
WSS_SERVICE_CA =(uint8_t)8,
WSS_CLIENT_CA =(uint8_t)9,
WSS_SERVICE_CLIENT_CA =(uint8_t)10} ESP8266_MQTT_Scheme_Typedef;#defineESP8266_MQTT_CLIENTIP"mm32f3270"#defineESP8266_MQTT_USERNAME"mm32"#defineESP8266_MQTT_PSD"mm32psd"#defineESP8266_MQTT_HOST"broker-cn.emqx.io"#defineESP8266_MQTT_HOST_IPADDR_047#defineESP8266_MQTT_HOST_IPADDR_1111#defineESP8266_MQTT_HOST_IPADDR_2117#defineESP8266_MQTT_HOST_IPADDR_3220#defineESP8266_MQTT_PORT1883#defineESP8266_MQTT_TOPIC"esp8266"typedefstruct{uint8_t mqttIPAddr0;uint8_t mqttIPAddr1;uint8_t mqttIPAddr2;uint8_t mqttIPAddr3;}ESP8266_MQTT_IPADDR_Typedef;typedefstruct{
ESP8266_MQTT_IPADDR_Typedef ipAddr;uint32_t port;char* clientID;char* username;char* password;
ESP8266_MQTT_Scheme_Typedef scheme;
ESP8266_MQTT_Status_Typedef mqttStatus;} ESP8266_MQTT_Typedef;
ESP8266_MQTT_Typedef ESP8266_MQTT_InitStruct;
Conclusion
🙏🙏🙏🙏🙏🙏🙏
版权归原作者 Rose Island 所有, 如有侵权,请联系我们删除。