【一】
说起学习物联网,相信大家最先想到的应该就是ESP8266了吧?这个模块可以连网(就是连接你家中的路由器),也可以作为一个热点来让你的手机连接它,是不是很奇妙?
学习方法:
1、多去各大论坛查资料去B站找相关的视频;
2、学会举一反三,让你点亮一个LED,就要会灭一个led;
3、多动手,程序不是写出来的,是调出来和改出来的。
乐鑫官方的AT指令有将近100条,但常用的就十几条,理解起来也非常简单,现在举例一些常用指令,并使用这些指令一步一步的通过TCP连接到远程的服务器实现收发数据,更多AT指令可以查阅《ESP8266 AT指令集手册》。
从上图可以看出,我们发送了一个AT,模块回复了AT OK,即模块将发送过来的指令原封不动的先复述了一遍后接着发送有效回复,我们称这种复述为回显,关闭回显(发送ATE0)后如再次发送AT,则只回复OK。如下图所示:
WIFI模式有两种,一种叫AP模式,一种叫Station模式,AP就是我们平时所说的热点,如WIFI路由器,开了热点的手机,或者是公共热点等,这些AP设备可以允许其他设备(如手机,笔记本电脑等)输入热点名和密码(也可不设置密码)后接入,Station则是前面说的连接AP的设备,如:手机,笔记本电脑等,当ESP8266设置为AP模式时,其他设备可以接入该热点,最多支持4台Station设备接入。AP模式也是ESP8266默认的模式。
设置ESP8266流程如下:
1、首先发送AT+CWMODE?查询模块当前处于哪一种模式,下图可以知道AT+CWMODE=2就是热点模式。
3、我们现在自定义设置我们ESP8266的热点名和密码,来看看我们电脑能不能连接我们所设置的好的ESP8266模块。
1、设置WIFI模式为AP模式
2、设置AP热点属性
AT+CWSAP=AT+CWSAP_DEF="ESP8266-XSD","12345678",5,3
1、设置WIFI模式为Station
2、连接到家中路由器AT+CWJAP="liuyao","liuyao1001"
下图为连接过程的串口输出:
现在我们的ESP8266已经与家中的路由器连接上了,现在我们如果想获取连接的这个ESP8266的IP可以使用AT+CIPSTA?指令,返回的是路由器分配给ESP8266的局域网IP以及网关地址和子网掩码。
TCP实现局域网内的设备通信时先要让ESP8266连接到家中的热点。该条指令可以指定建立连接的协议类型,通常使用的有两种:TCP和UDP。
接下来,发送AT指令建立TCP连接,成功连接会提示CONNECT,接着使用发送指令:AT+CIPSEND=14,其中15是发送数据的长度,该指令发送完成后,接收窗口会显示 > ,我们接着在发送窗口发送"I m TCP Client",TCP Server端会收到该信息,接着再通过TCP Server发送"I m TCP Server",串口接收端会打印Client收到的数据。
哈哈,我相信很多初学者学到这里也不是很清楚。我这里简单说一下,我们的用ESP8266是不是要让它连到家中的网啊,那在这里我们的网络调试助手的TCP Server就是我们要连接的网络。
有人又要说了,我要连家中路由器的网啊,为啥要连网络调试助手的网啊?这是因为如果你连家中的网,请问你如何给你家的路由器发送数据啊!你怎么知道路由器接收到了数据啊!路由器又咋给你发送数据啊!你又咋接收数据啊!我们这里用网络调试助手的目的就是让网络调试助手来代替路由器局域网。TCP Server就是服务端的意思也是就是服务器。至于为啥用串口调试助手我就不用说了吧,只有你在串口助手上调试好了,我们才用单片机的串口结合ESP8266共同代替客服端,也就不需要调试助手了。
所以说,我们一定要在串口调试助手上把相关的数据调通了,把原理过程搞懂了之后我们再去搞单片机程序,再去搭建你的服务器而不是用网络调试助手代替了。怎么样现在明白了吧!
前面在使用TCP进行数据发送时,在每次发送数据之前都要指定发送数据的长度,而且在接收到数据之后,还会有+IPD,< len >的前缀,这样很不方便进行数据的处理,因此我们可以使用AT+CIPMODE=1指令开启透传模式,开启透传模式后只需要在第一次发送数据时使用ATD+CIPSEND指令来告诉ESP8266开始透传发送,随后我们直接发送想要的数据即可,在接收到数据时,也没有了+IPD,< len >前缀。
下面就是ESP8266连接当前环境的热点,与服务器建立TCP连接,开启透传模式传输数据的过程,所有的字符和标点必须是英。
(1)设置WIFI模式为Station:AT+CWMODE=1
(2)连家中路由器:AT+CWJAP="liuyao","liuyao1001"
(3)TCP:AT+CIPSTART="TCP","192.168.0.103",8080
(4)开启透传模式:AT+CIPMODE=1
(5)开始透传发送:AT+CIPSEND
(6)串口调试助手发送:hello I m TCP Client!
(7)网络调试助手发送:hello I m TCP Server!
前面使用了AT+CWJAP指令来主动连接家中的WIFI,但是在大多数的物联网产品中,缺少输入WIFI密码的输入设备,如:键盘,更不能将程序交给用户去修改家中的WIFI热点名和密码,在真正的项目开发中使用最多的方法就是通过一颗按键来使设备进入某种模式,并使用手机将当前WIFI的密码告知该设备来实现WIFI配网,这种模式就是SmartConfig。在该模式下,ESP8266会监听指定端口的UDP广播包,如果收到符合规定格式的广播包后会对其进行解析并获得WIFI的SSID和PWD,然后自动连接获取到的WIFI热点,从而实现WIFI配网。
我们说到了ESP8266的AT指令集的使用。本来今天要讲一下MQTT协议的,但考虑到物联网知识体系的完整性,决定还是先说一下物联网智能家居的控制过程和流程,以及关于MQTT协议中的订阅和发布是什么意思。就算是下一章的前奏吧,请大家耐心看完
简单地说,我们最终实现的目的,是要用STM32+ESP8266外加传感器和继电器来控制家中的开关,以及得到家中的各个电器的运行状态。其原理是家里的电器先接带STM32+ESP8266+继电器的智能插座,智能插座再接家里的插座,这样只要控制ESP8266的这个插座(类似中介)就能控制家里的任何电器。
下面这张图就是控制方式,通过家用的路由器将各个电器和手机联系起来了,手机可以通过路由器控制各个挂载在路由器上的器件,这是比较常用的模式。
一般来说,把手机叫做上位机,控制器叫做下位机,难道这就是我们常说的物联网吗?准确地说,这是不对的。毕竟只能围绕着这个路由器,有一定的局限性。
比如,你到公司才想起忘了关家里的灯,那么只能跑回家,运气好的话,在楼下就能连到家里的路由器,然后再通过手机app关灯。这时候你想,如果能在任何地方控制家里的电器该多好,要是真有这样的功能,比如你冬天回家前可以先把家里的空凋打开……
我们这个项目就是ESP8266连接家中的路由器的网,手机连接的是4/5G网,这样你就能在家中设备不断电、不断网的情况下,在任意地方来控制你家中的用电器设备了。
一、理论知识
那么,怎么样才能让你在任何地方控制家里的电器(当然提前还是要有网)?
我们先来看下面这张图,跟原来不一样的地方是用云服务器代替了家里的路由器,就这么简单!
那么,什么是云服务器?云服务器又在哪?你就把它当作天上的一朵云就好了(阿里云、腾讯云),反正就是不管你的手机,还是别的什么设备,只要能连网就可以连接云服务器。
那么,连上服务器后,是不是就能直接控制了?当然可以!
刚学单片机的小伙伴肯定玩过串口实验,从单片机发送字母xiaoshidi,串口调试助手就收到字母xiaoshidi,觉得很有趣。但有时候你会发现,如果你的串口通信的函数写的不好,或者有误的时候,就会出现通信错误,比如接收的数据是乱码等,那么它的可靠性就不是很好了。
到底什么叫可靠性不好呢?比如这边发过去的时候是xiaoshidi,运气不好的话,那边只可能收到的是shidi,这样就会出事。所以,我们也不能直接向云服务器发送个简单指令去控制下位机,需要有一定的约定。
比如,事先告诉服务器我要发送9个字母过来了,云服务器收到后就知道了,如果接收xiaoshidi,一般来说是正确接收了;如果只收到shidi,说明丢了4个字母,这就是我们常说的丢包。那么,这样的约定就是我们常说的协议!
有句话叫“没有物联网协议就没有智能安全”,其实关键就是协议,在物联网中常用的就是MQTT协议。那么,为什么不用我们常见的http协议呢?只能自己百度了。这边简单介绍一下MQTT协议的原理,因为只要会MQTT,就能玩转物联网。
我们先来看个例子:
为什么能收到呢?是因为我关注它了,我想这些玩微博的小伙伴都知道。
下面,我再用图表示一下:
通过这样的控制方式,就可以解决在单位也能开/关家里电灯的问题了。不过前提是,手机和单片机都能连上云服务器(手机可以用家里的网或者4G就可以连到云服务器,单片机可以通过家里的WIFI就可以连到云服务器)。
这时可能有人会问,在微博里像“晓艳考研”那么有名,有很多人都会关注,比如小雅、小李等等,只要“晓艳考研”发布消息了,关注的人都能收到。
有的小伙伴脑子转的溜,感觉这样控制是有问题的。因为这样的话,手机是统一控制了家里的电器,总不能都一起开、一起关吧?
关于MQTT理论,我们先说到这儿,其实还有很多玩法,比如在微博里“晓艳考研”也关注了我呢?这个有什么用?这样可以用控制器采集信息上传到我们的手机了!那就可以采集家中的环境数据上发到你的手机。
二、实现部分
根据下面这张图,我们要做三部分:单片机、云服务器、手机。
一般来说,单片机也叫作控制器,或者下位机。我们这里用的是STM32单片机。
这时有人会问,为什么不用51单片机,或者arduino?因为现在用STM32的人太多了,arduino又体现不出你是一个电子信息专业的,51就不用说了。
可能又有人说,你为啥不用esp32,本来就可以当一块单片机,搞个STM32岂不是太麻烦?
此言差矣!我们这里是把ESP8266当做一个模块使用,我仅仅用STM32的串口就可以控制它连网。但如果单单只用ESP32的话,就大大增加了开发的难度,也就是我们通常说的SDK开发,而且学习的同时,又能巩固单片机的知识,搞SDK确实不适合初学者。
最后,我们的MQTT协议转换成C语言代码已经有前辈写好了,我们的目的就是学会它,学会反向学习,才能增加你对新事物的学习兴趣。MQTT协议是现成的,拿来用即可!
在理论部分提到的MQTT协议是整个物联网的核心,所以单片机、手机和云服务器都要有这协议。这就好比三个中国人在聊天,一个日本人过来听,他根本听不懂,因为他没有“中文”这个能力。所以,控制器也要有这个解析协议的能力。
服务器可以理解成一台普通的电脑,只是它的性能比较稳定不容易死机。目前服务器有很多,做得比较大的像腾讯云、阿里云等等,购买服务器也是个坑,大家需谨慎!前期的话,大家学习不用买,登录生活物联平台用现成的,后面我会讲到。
一般把手机也叫上位机,上位机还有电脑、平板等等,实验中是用手机发送命令来控制我们的单片机。那么手机能打开直接能操作吗?显然不能,需要编写相应的程序界面。
如果你是安卓手机,可以用android studio软件编写相应的app程序。当然,前期的话,大家不要去想着做一个app,难度还是蛮大的。
【三】
在学习MQTT之前,我们要明白MQTT通讯是通过很多的报文组成的,这就好比二战时期发电报进行两军之间的通信。这个报文呢,主要由三部分组成:固定报文+可变报文+有效载荷,这是官方起的名字,你可以把它理解为开头+正文+结尾,这样就好理解多了是吧?!
基本在MQQTT中,所有的报文都由这三部分组成。比如今天要说的Connect控制报文,顾名思义就是客户端(ESP8266)请求与服务端(阿里云服务器)建立连接的报文。
啥意思呢?这就好比你第一次去你女朋友家,你要首先打一个电话(Connect控制报文)征得叔叔阿姨的同意啊!叔叔阿姨同意之后(服务器确认建立连接)你才能去对吧,如果不同意或者电话没打通你就不能去你女朋友家啊,就算去了也不招待见对吧!
客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是connect报文(因为客户端和服务端必须要建立连接后才能进行通信)。
1、CONNECT控制报文主要由三部分组成:固定报头、可变报头、有效载荷。
2、假设我们得到了固定报头是“liuyao”、可变报头是“iloveyou”、有效载荷是“zhuxiaoya”。我们要把这些字母转换成对应的16进制。然后再把它们串联起起来就得到。
最终固定报头:综上可得固定报头为:10 ??(??我们在后面的实验会提到,先不着急)。
综上,我们可得有效报头为:00 04 4D 51 54 54 04 C2 00 64
{
"ProductKey": "a10zwkUxQUS",
"DeviceName": "LY-1",
"DeviceSecret": "d8b9915513b05d4de32fbed04566edd8"
}
客户端ID : *|securemode=3,signmethod=hmacsha1|
用户名 : *
密码 : clientId*deviceName*productKey#
服务器地址:a10zwkUxQUS.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883
客户端ID :LY-1|securemode=3,signmethod=hmacsha1|
用户名 :LY-1&a10zwkUxQUS
密码:clientIdLY-1deviceNameLY-1productKeya10zwkUxQUS
经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87
客户端ID :LY-1|securemode=3,signmethod=hmacsha1|
用户名 :LY-1&a10zwkUxQUS
经过哈希加密 :7a03368e740ff9efb8318c6ba2a0260f2a596f87
客户端ID:LY-1|securemode=3,signmethod=hmacsha1| 转换为(16进制):
4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73
69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 一共38个字节就是0x26
最终结果:把00 26加到最前面
00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C
73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C
用户名:LY-1&a10zwkUxQUS转换为(16进制):
4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53 一共16个字节就是0x10
最终结果:把00 10加到最前面
00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53
经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87 转换为(16进制)
37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31
38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37 一共40个字节就是0x28
最终结果:把00 28加到最前面
00 28 37 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33
31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
最终可得:
这样我们就得到了有效载荷:
00 26 4C 59 2D 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 33 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 31 7C 00 10 4C 59 2D 31 26 61 31 30 7A 77 6B 55 78 51 55 53 00 2837 61 30 33 33 36 38 65 37 34 30 66 66 39 65 66 62 38 33 31 38 63 36 62 61 32 61 30 32 36 30 66 32 61 35 39 36 66 38 37
固定报头+可变报头+有效载荷
服务器地址:a10zwkUxQUS.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883
推荐阅读
添加微信回复“进群”
拉你进技术交流群!
国产芯|汽车电子|物联网|新能源|电源|工业|嵌入式…..
在公众号内回复您想搜索的任意内容,如问题关键字、技术名词、bug代码等,就能轻松获得与之相关的专业技术内容反馈。快去试试吧!
如果您想经常看到我们的文章,可以进入我们的主页,点击屏幕右上角「三个小点」,点击「设为星标」。
欢迎扫码关注