【ESP8266】ESP8266的MQTT客户端搭建教程
来源:互联网 发布:淘宝66大促 编辑:程序博客网 时间:2024/05/21 22:40
前言
MQTT是IBM开发的一个即时通讯协议,面向M2M和物联网的连接,采用轻量级发布和订阅消息传输机制,并且有可能成为物联网的重要组成部分。
ESP8266是一款物美价廉的Wi-Fi芯片,集成Tensilica L106 钻石系列的32 位处理器和片上SRAM,多达17 个GPIO口,并拥有IIC、IIS、UART、PWM、IR遥控等片上资源。
ESP8266还提供官方的软件开发开发包(SDK),目前最新版本是「ESP8266 NONOS SDK V2.0.0」。
这篇文章主要讲解如何使用ESP8266作为MQTT客户端,并连上在本地电脑搭建的MQTT服务器。
开发环境
首先简单说明一下博主的开发环境:
- ESP8266开发环境:ESP8266 IDE 2.0
- ESP8266 SDK版本:esp8266_nonos_sdk_v2.0.0_16_08_10_0
- MQTT服务器:Apollo 1.7.1(本地搭建)
- 操作系统:64位 Win10系统
- ESP8266开发板:NodeMCU(4MB Flash)
导入工程
如果读者和博主使用的开发环境一样,那么步骤1~4就好理解了,不是的话直接看图片和步骤5:
1. 在IDE环境中通过「File」->「Import」;
2. 弹窗中选择「C/C++」->「Existing Code as Makefile project」;
3. 下一步「Browse…」,编译器选择「Cygwin GCC」;
4. 之后导入的工程目录如上图,其中给「dirver_lib」文件下面的Makeflie添加bak后缀或删除掉,免得编译通不过。
5. 从「example」文件夹中拷贝esp_mqtt_proj文件夹到主目录,点击编译按钮,如果成功就完成这一步骤了。
工程目录图
代码分析
示例工程中最重要的是这两个文件:user目录下的user_main.c和inlcude目录下的mqtt_config.h。
其中user_main.c不用说了,玩过ESP8266的朋友都知道这是放主代码的地方,其中user_init函数是SDK提供开发者放置初始化代码的地方。下面主要分析mqtt_config.h。
mqtt_config.h
代码清单
#ifndef __MQTT_CONFIG_H__#define __MQTT_CONFIG_H__#define CFG_HOLDER 0x00FF55A4 /* Change this value to load default configurations */#define CFG_LOCATION 0x79 /* Please don't change or if you know what you doing */#define MQTT_SSL_ENABLE/*DEFAULT CONFIGURATIONS*/#define MQTT_HOST "192.168.1.100" //or "mqtt.yourdomain.com"#define MQTT_PORT 1883#define MQTT_BUF_SIZE 1024#define MQTT_KEEPALIVE 120 /*second*/#define MQTT_CLIENT_ID "DVES_%08X"#define MQTT_USER "DVES_USER"#define MQTT_PASS "DVES_PASS"#define STA_SSID "DVES_HOME"#define STA_PASS "yourpassword"#define STA_TYPE AUTH_WPA2_PSK#define MQTT_RECONNECT_TIMEOUT 5 /*second*/#define DEFAULT_SECURITY 0#define QUEUE_BUFFER_SIZE 2048#define PROTOCOL_NAMEv31 /*MQTT version 3.1 compatible with Mosquitto v0.15*///PROTOCOL_NAMEv311 /*MQTT version 3.11 compatible with https://eclipse.org/paho/clients/testing/*/#endif // __MQTT_CONFIG_H__
在这个文件中,有几个宏定义可能需要修改的
- MQTT_HOST,MQTT服务器地址
- MQTT_PORT,MQTT服务器端口
- MQTT_USER,MQTT服务器用户名
- MQTT_PASS,MQTT服务器密码
- STA_SSID,WI-FI帐号
- STA_PASS,WI-FI密码
还有一个最重要的宏定义——CFG_HOLDER,因为这个MQTT示例在ESP8266运行过一次后会把这些信息保存到FLASH中,如果要继续修改这些信息,记得要修改CFG_HOLDER这个宏定义,改成另一个数值即可。
CFG_HOLDER作的用是:在CFG_Load
函数中,如果发现从FLASH读取出来的CFG_HOLDER
数值和宏定义的不一样,则会更新这些信息,并保存到FLASH中。不修改CFG_HOLDER
的话可能会发觉明明用户名和密码都正确但是就是连接不上去。
修改代码及测试
修改代码
根据上面分析,下面我们就可以修改示例代码:
1. 把STA_SSID和STA_PASS修改为自己的WiFI名和密码;
2. 修改MQTT_USER和MQTT_PASS为对应的MQTT服务器的用户名和密码,Apollo服务器默认是admin和password;
3. 修改MQTT_HOST和MQTT_PORT为MQTT服务器IP和PORT,目前是使用本地的MQTT服务器,所以是修改为自己电脑的IP和61613端口,PORT是整型值;
4. 根据MQTT服务器的协议不同,可能需要使用MQTT v3.1.1版本,所以把PROTOCOL_NAMEv31注释掉,使用PROTOCOL_NAMEv311。源码的PROTOCOL_NAMEv311前面没有#define,自己加上就行。
5. 最后,修改CFG_HOLDER,以让这些配置生效,直接给原来CFG_HOLDER定义的数值加1即可。
编译下载
编译,查看Console窗口,如果输出
那说明代码已经编译成功。另外要注意,ESP8266 SDK v2.0版本生成的eagle.irom0text.bin烧写起始地址是0x10000,而之前的版本烧写地址是0x40000;eagle.flash.bin还是0x00000。由于博主使用的是4MB Flash的ESP8266,所以也建议读者先确定手头的ESP8266是不是4MB Flash(即32Mbit Flash,注意单位!4MB=32Mbit,Flash一般是以bit计算!)
另外如果Problems窗口报Errors的,只要Console窗口编译通过,就可以不用管。
下载配置参考图片:
提醒:blank.bin和default.bin烧写一次就行,另外也要留意不同的Flash大小,blank.bin和default.bin烧写地址也不同。
上电测试
如果前面一切顺利,打开串口,设置波特率为115200,上电后前面的乱码不用管,之后串口打印信息如下,省略了一部分信息:
load …
default configuration
MQTT_InitConnection
MQTT_InitClient
WIFI_INIT……(省略)
connected with [你的WiFi名], channel 6
dhcp client start…
STATION_IDLE
STATION_IDLE
ip:[WiFi分配给ESP8266的IP],mask:255.255.255.0,gw:[WiFi网关IP]
TCP: Connect to ip [MQTT服务器IP:PORT]
MQTT: Connected to broker [MQTT服务器IP:PORT]
MQTT: Sending, type: 1, id: 0000
TCP: Sent
TCP: data received 4 bytes
MQTT: Connected to [MQTT服务器IP:PORT]
MQTT: Connected
MQTT: queue subscribe, topic”/mqtt/topic/0”, id: 1
MQTT: queue subscribe, topic”/mqtt/topic/1”, id: 2
MQTT: queue subscribe, topic”/mqtt/topic/2”, id: 3
MQTT: queuing publish, length: 23, queue size(66/2048)
MQTT: queuing publish, length: 25, queue size(91/2048)
MQTT: queuing publish, length: 25, queue size(118/2048)
……
其中加粗带方括号的字段根据测试环境不同而不同。
同时看源码和串口信息可知,ESP8266向MQTT服务器订阅了三个主题,假设使用的是本地搭建的MQTT服务器,那么查看MQTT服务器后台就可以看到:
同时在后台的Connects页面也可以看到ESP8266的链接:
MQTT本地服务器搭建教程Windows版链接在后面。
另外博主已经用ESP8266的MQTT连接上了OneNET云,连接该云需要注释掉下面这条语句,在user_init
函数下。
MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);
原因是OneNET不支持,否则连接不上。
其他
【MQTT服务器】
- 下载地址:http://activemq.apache.org/apollo/download.html
- 在Windows下搭建本地的MQTT服务器教程:http://blog.csdn.net/yannanxiu/article/details/52703946
【ESP8266 IDE】由于上面提供的ESP8266 IDE下载链接已经失效,笔者这里自己上传了一个,供大家下载:
链接: https://pan.baidu.com/s/1c2tBHW8
密码: qyjs【示例代码】本博客示例代码下载地址:http://download.csdn.net/detail/u012163234/9687996
【ESP8266资料】ESP8266官网资源链接:http://espressif.com/zh-hans/products/hardware/esp8266ex/resources
评论统一回复
上电乱码
评论区很多朋友回复上电后打印乱码,我都不知道你们的乱码是怎样的?请确保已经修改了WiFi帐号和密码。
上电启动信息默认波特率是76800bps,进入user_init
后串口被初始化为115200bps。
如果反复打印STATION_IDLE ,说明没有连上WiFi。
load …
default configuration
MQTT_InitConnection
MQTT_InitClient
WIFI_INITSystem started …
mode : sta(18:fe:34:a1:33:0e)
add if0
STATION_IDLE
STATION_IDLE
STATION_IDLE
scandone
no your_wifi_ssid found, reconnect after 1s
reconnect
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
scandone
no your_wifi_ssid found, reconnect after 1s
reconnect
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
scandone
no your_wifi_ssid found, reconnect after 1s
reconnect
STATION_NO_AP_FOUND
scandone
STATION_IDLE
STATION_IDLE
STATION_IDLE
STATION_IDLE
scandone
no your_wifi_ssid found, reconnect after 1s
另外一定要注意:
ESP8266 SDK v2.0版本生成的文件烧写地址:
烧写错误会导致芯片不断的重启!请仔细阅读「编译下载」小节。
安全连接
关于MQTT的安全连接,在配置文件中和这两个宏定义有关:
//第6行左右#define MQTT_SSL_ENABLE//第25行左右#define DEFAULT_SECURITY 0
其中我查看源码,宏定义MQTT_SSL_ENABLE
是SSL连接的预编译,如果不定义MQTT_SSL_ENABLE
则表示不支持SSL(最好看源码理解)。 DEFAULT_SECURITY
是SSL是否使能,0为禁能,1为使能。
esp_mqtt_proj/mqtt/mqtt.c文件下的MQTT_Connect
函数部分源码:
void ICACHE_FLASH_ATTRMQTT_Connect(MQTT_Client *mqttClient){ //省略…… if (mqttClient->security) { #ifdef MQTT_SSL_ENABLE espconn_secure_connect(mqttClient->pCon); #else INFO("TCP: Do not support SSL\r\n"); #endif } else { espconn_connect(mqttClient->pCon); } //省略……}
其中mqttClient->security
由DEFAULT_SECURITY
赋值。在esp_mqtt_proj/modules/config.c的CFG_Load
函数里。
sysCfg.security = DEFAULT_SECURITY; /* default non ssl */
最后会在user_init
函数初始化
MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.security);
本文章最后编辑时间:2016年12月
- 【ESP8266】ESP8266的MQTT客户端搭建教程
- ESP8266的MQTT客户端搭建教程(基于NONS_SDK_v2.0)
- 基于ESP8266,NodeMCU的自动升级的MQTT客户端
- 【ESP8266】基于ESP8266的MicroPython连接MQTT服务器
- ESP8266和MQTT
- ESP8266下载电路的搭建
- ESP8266
- ESP8266
- 搭建esp8266+ardunio-IDE的开发环境
- esp8266环境搭建
- Esp8266接线教程
- ESP8266模块使用教程
- ESP8266移植MQTT连接中移ONENET
- ESP8266(WIFI chip): transplantation of MQTT protocal
- ESP8266学习笔记4:ESP8266的SmartConfig
- 【ESP8266】基于ESP8266的MicroPython入门笔记
- ESP8266学习笔记4:ESP8266的SmartConfig
- ESP8266学习笔记4:ESP8266的SmartConfig
- java基础实训--简易版答答租车系统
- HTTP://WWW.MSIDEVS.NET - 软件开发超级网
- 2016年11月8日,有感
- 关于Android调用JNI出现的 java.lang.UnsatisfiedLinkError
- maven 使用nexus 搭建私服
- 【ESP8266】ESP8266的MQTT客户端搭建教程
- Android App专项测试-压力测试笔记
- Adnroid四大组件z之Activity的学习
- <!DOCTYPE>声明
- python中Crypto的注意事项
- 学生管理系统学习(三)
- LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
- C++ 计算机存储补码
- 老鸟的Python入门教程