前言

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(基于NONS_SDK_v2.0)作为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)

提醒

阅读本教程时,如果有使用esp8266_nonos_sdk_v2.0.0的开发经验,会更轻松的使用本教程。如果遇到代码编译出错、烧写下载不行以及下载后出现异常的问题,请先参考其他资料再继续本文。

导入工程

本教程基于ESP8266 IDE 2.0,如果读者使用一样的环境,那么步骤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文件夹到主目录,点击编译按钮,如果成功就完成这一步骤了。

工程目录图。注意红色方块内的文件。

MQTT代码使用简析

示例工程中最重要的是这两个文件: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_SSIDSTA_PASS修改为自己的WiFI名和密码;
  2. 修改MQTT_USERMQTT_PASS为对应的MQTT服务器的用户名和密码,Apollo服务器默认是adminpassword
  3. 修改MQTT_HOSTMQTT_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烧写地址也不同。

另外,给NodeMCU烧写固件的时候,SPI MODE选项可能要选DIO。详细细节参考这里。
其他的ESP8266开发板一般则选择默认的QIO就行了。

上电测试

如果前面一切顺利,打开串口,设置波特率为115200,上电后前面的乱码不用管,之后串口打印信息如下,省略了一部分信息:

load ...
default configuration
MQTT_InitConnection
MQTT_InitClient
WIFI_INIT……(省略)connected with <WiFi名>, channel 6
dhcp client start...
STATION_IDLE
STATION_IDLE
ip:<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协议的Will字段,否则可能连接不上。

其他

  • 【MQTT服务器】

    • 在Windows下搭建本地MQTT服务器教程
    • MQTT服务器Apollo下载地址:http://activemq.apache.org/apollo/download.html
  • 【ESP8266 IDE】

    • 由于上面提供的ESP8266 IDE下载链接已经失效,笔者这里自己上传了一个,供大家下载:链接: https://pan.baidu.com/s/1c2tBHW8 密码: qyjs
  • 【示例代码】本博客ESP8266端代码下载地址:

    • CSDN: http://download.csdn.net/detail/u012163234/9687996
  • 【ESP8266资料】

    • ESP8266官网资源

评论统一回复

上电乱码

评论区很多朋友回复上电后打印乱码,我都不知道你们的乱码是怎样的?请确保已经修改了WiFi帐号和密码。同时请确定自己的ESP8266是否是4MB Flash(32Mbit Flash)。(评论区出现好几个这样的情况:第一次烧写后重启成功,之后重启芯片就不行的情况,如果有读者知道原因的希望告知下,谢谢。另,我估计绝对不是本教程的问题。)

上电启动信息默认波特率是76800bps,进入user_init后串口被初始化为115200bps。

如果反复打印STATION_IDLE ,说明没有连上WiFi。

load ...
default configuration
MQTT_InitConnection
MQTT_InitClient
WIFI_INITSystem started ...
mode : sta(18:fe:34:**:**:**)
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版本生成的文件烧写地址:

bin文件 烧写地址
eagle.flash.bin 0x00000
eagle.irom0text.bin 0x10000

烧写错误会导致芯片不断的重启!请仔细阅读「编译下载」小节。

另外v2.0以下版本的SDK(不包括v2.0)eagle.irom0text.bin是烧写在0x40000,请自行参考其他资料。

安全连接

关于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_ATTR
MQTT_Connect(MQTT_Client *mqttClient)
{//省略……if (mqttClient->security){#ifdef MQTT_SSL_ENABLEespconn_secure_connect(mqttClient->pCon);#elseINFO("TCP: Do not support SSL\r\n");#endif}else{espconn_connect(mqttClient->pCon);}//省略……
}

其中mqttClient->securityDEFAULT_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);

关于烧写后第一次启动正常,之后不断重启的问题

在makefile文件里面把SPI_SIZE_MAP?=0改为SPI_SIZE_MAP?=4。

参见评论区33楼。

update:2018-03-05

关于连接阿里云百度云等

因为这些云平台的mqtt_namemqtt_pass比较长,而MQTTconfig.h中保存到Flash中的结构体的这些字段不够长,这样就会导致连接不上云平台。解决办法就是手动增大数组大小。(感谢评论区35楼评论者的提醒)

// esp_mqtt_proj/include/module/config.h
typedef struct{uint32_t cfg_holder;uint8_t device_id[32];uint8_t sta_ssid[64];uint8_t sta_pwd[64];uint32_t sta_type;uint8_t mqtt_host[64];uint32_t mqtt_port;uint8_t mqtt_user[32];uint8_t mqtt_pass[32];uint32_t mqtt_keepalive;uint8_t security;
} SYSCFG;

update:2018-04-04

【ESP8266】ESP8266的MQTT客户端搭建教程(基于NONS_SDK_v2.0)相关推荐

  1. ESP8266的MQTT客户端搭建教程(基于NONS_SDK_v2.0)

    前言 MQTT是IBM开发的一个即时通讯协议,面向M2M和物联网的连接,采用轻量级发布和订阅消息传输机制,并且有可能成为物联网的重要组成部分. ESP8266是一款物美价廉的Wi-Fi芯片,集成Ten ...

  2. UG二次开发教程(基于NX12.0/VS2015版本)

    ** UG二次开发教程(基于NX12.0/VS2015版本) 安装教程 ** UG NX12.0安装 NX12.0 安装包下载地址: 链接:https://pan.baidu.com/s/1I0CCF ...

  3. Discuz论坛网站搭建教程,从0开始学会搭建网站

    Linux系统使用宝塔面板搭建网站并开启SSL和使用CDN加速网站,网站搭建教程,下面教程以Discuz X3.4网站程序为例. 视频教程:https://www.bilibili.com/video ...

  4. SVN服务端和客户端搭建教程

    综述 SVN服务器搭建, 有很多方法, 可以直接使用Subversion进行安装, 不过, Subversion本身并没有提供界面显示, 那么, 我们将使用如下方法搭建SVN服务端和客户端: 服务器: ...

  5. java做h5小游戏服务端_神藏西游H5游戏源码服务端+客户端+搭建教程

    源码预览 源码介绍 教程如下: 1.cd / 把下载好的文件传到服务器根目录下面 2.打开Xshell 安装java 输入 sh sd 回车 输入1 回车 3.安装宝塔 输入 sh sd 回车 输入2 ...

  6. Ngrok服务器+客户端搭建教程

    https://www.jianshu.com/p/f5c2a55e77bd 注意,云服务器要对相关端口放开,系统的防火墙也要放开 有一些端口是被运营商屏蔽了的,比如4444,不能用的

  7. ANT安装与环境变量搭建教程(win7)

    ANT安装与环境变量搭建教程(基于windows7) ANT安装与环境变量搭建教程基于windows7 一安装ant 二配置环境变量 进入环境变量配置界面 在系统变量中依次配置变量名和值如下表 三验证 ...

  8. 基于Domoticz智能家居系统(十七)DIY一款基于MySensors的ESP8266+NRF24L01的MQTT(WIFI)和RF无线网关(三)一个简单MySensors客户端的验证实验

    DIY一款基于MySensors的ESP8266+NRF24L01的MQTT(WIFI)和RF无线网关(三)一个简单MySensors客户端的验证实验 一个简单MySensors客户端的验证实验 一. ...

  9. 基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验

    基于Domoticz智能家居系统(十四)用ESP8266做MQTT客户端实验 用ESP8266做MQTT客户端 一些前期的准备 第一步 设置ESP8266开发板的BSP的搜索引擎链接 第二步 下载安装 ...

最新文章

  1. UE如何使用正则表达式
  2. 在Visual Studio中使用Git [关闭]
  3. SqlServer注意事项总结,高级程序员必背。
  4. CentOS7中NAT网卡设置静态IP
  5. 怎样对java网站进行简单修改_用Java写一个简单的毕业设计,功能就增删改查的一些基本功能就可以,需要哪些技术?...
  6. as本地仓库更改_将gitee仓库连接GitHub Desktop。新建更改仓库并上传至gitee。
  7. python 生成器_Python生成器中的GeneratorExit
  8. jquery中的ajax方法参数——$.ajax()方法详解
  9. mysql中in的使用
  10. 《HTML 5与CSS 3 权威指南(第3版·上册)》——1.2 HTML 5深受欢迎的理由
  11. bzoj 3824: [Usaco2014 Dec]Guard Mark【状压dp】
  12. spring AOP 代理(静态与动态+使用cglib实现)
  13. CRC校验算法详解及代码实现
  14. 华为获颁中国首个5G基站设备进网许可证:可支持中国规模部署;IBM推出新一代企业平台Z15;Testin最新AI产品发布……...
  15. webpack安装问题(已解决)
  16. 软件性能测试pdf,软件性能测试报告模板.pdf
  17. java服务监控并发送邮件_详解Spring Boot Admin监控服务上下线邮件通知
  18. 先定一个能达到的小决心,比方读个一本书 ——《小决心》读后感 @阿狸不歌
  19. 智慧城市同城V4 v1.7.1
  20. mysql 签到_签到功能,用mysql还是redis?

热门文章

  1. 【梁小国】教你怎么签自己的名字
  2. el-select被嵌套太多层导致选不中
  3. 04 turtle库 | 发送小心心
  4. 做转子力学分析,你选APDL还是Workbench仿真?
  5. sharepoint 2010 获取讨论板话题的所有评论回复信息 Get all replies
  6. VMware workstation安装虚拟机--Windows XP
  7. 【洛谷 1516】青蛙的约会
  8. Qt crator警告This does noy seem to be a “Debug“ build
  9. Actor模型的本质:究竟是要解决什么问题
  10. 2018 ICPC 沈阳站