【一】
说起学习物联网,相信大家最先想到的应该就是ESP8266了吧?这个模块可以连网(就是连接你家中的路由器),也可以作为一个热点来让你的手机连接它,是不是很奇妙?
虽然ESP8266程序和相关的产品已经十分成熟了,但还是有一些刚入门的小伙伴不知道怎么学。比如,如何用一个ESP8266加上STM32单片机做一个小产品?这个学习的路线又是怎样的?我们应该如何入门?对此,我建议:1、先单独学习ESP8266模块,搞懂他的AT指令集,通过串口调试助手和网络调试助手单独把这个模块搞明白。2、学习mqtt协议,为啥第二步要学习mqtt协议呢?因为我们esp8266是要连接服务器的,简单地说mqtt就是ESP8266与服务器之间的通信协议,这个协议不难,我已经写好了笔记到时候在这个公众号直接发布就可以了。3、就是要学习android studio自己做一个app。既然是物联网控制,当然有app了,虽然阿里云还有机智云有直接可以用的app,但作为一个电子爱好者,不能仅限于云智能。今天,就带你用STM32和ESP8266做一个比如温湿度显示,并在手机app上实时。
学习方法:
1、多去各大论坛查资料去B站找相关的视频;
2、学会举一反三,让你点亮一个LED,就要会灭一个led;
3、多动手,程序不是写出来的,是调出来和改出来的。
ESP8266 01S简介:
使用AT功能之前,模块内必须有AT的固件,每个模块的生产厂商都会对乐鑫官方的AT固件做一些修改和删减,但是其最核心的AT指令功能都是相同的。我们买的ESP8826模块一般都有刷好的固件,所以不用自己刷固件。
ESP-01S WiFi模块是一款低功耗高性价比的嵌入式无线网络控制模块。可满足智能电网、楼宇自动化、安防、智能家居、远程医疗等物联网应用的需求。该模块核心处理器ESP8266在较小尺寸封装中集成了业界领先的Tensilica L106超低功耗32位微型MCU,带有16位精简模式,主频支持80MHz和160MHz,支持RTOS,板载天线。该模块支持完整的TCP/IP协议栈。用户可以使用该模块为现有的设备添加联网功能,也可以构建独立的网络控制器。
(1)模块供电电压为直流3.3V、电流为500mA以上。
(2)Wi-Fi模块IO最大输出电流为12mA。
(3)Wi-Fi模块NRST管脚低电平有效;EN使能管脚高电平有效。
(4)Wi-Fi模块进入升级模式:GPIO0处于低电平,然后模块复位上电;Wi-Fi模块进入正常工作模式:GPIO0处于高电平,模块复位上电。
(5)Wi-Fi模块的RXD接外部MCU的TXD,Wi-Fi模块的TXD接外部MCU的RXD。
ESP8266刷固件:
刷固件可以用杜邦线,也可以用刷固件的模块(淘宝上几块钱就可以买到),如下图所示:
AT指令控制ESP8266模组:
乐鑫官方的AT指令有将近100条,但常用的就十几条,理解起来也非常简单,现在举例一些常用指令,并使用这些指令一步一步的通过TCP连接到远程的服务器实现收发数据,更多AT指令可以查阅《ESP8266 AT指令集手册》。
总结AT指令的构成就是,每条指令要以AT开始,后面跟要查询(读)或者要设置(写)的参数,例如查询WIFI模式对应的指令为AT+CWMODE?,设置WIFI模式为AT+CWMODE=3。另外,要求的回车换行符结尾是说要在待发送的数据后面追加 ,即十六进制的0x0D 0x0A。注意:在使用串口调试助手发送AT指令时,只需要在待发送指令后面加回车即可,大家可以勾选“按十六进制发送”,观察数据后面是否追加了0x0D 0x0A。
1、测试模块是否正常
该指令通常在开机后查询模块是否正常启动,如果回复OK,则表示为正常启动。
2、开启/关闭回显
从上图可以看出,我们发送了一个AT,模块回复了AT OK,即模块将发送过来的指令原封不动的先复述了一遍后接着发送有效回复,我们称这种复述为回显,关闭回显(发送ATE0)后如再次发送AT,则只回复OK。如下图所示:
3、设置AP模式及AP参数
WIFI模式有两种,一种叫AP模式,一种叫Station模式,AP就是我们平时所说的热点,如WIFI路由器,开了热点的手机,或者是公共热点等,这些AP设备可以允许其他设备(如手机,笔记本电脑等)输入热点名和密码(也可不设置密码)后接入,Station则是前面说的连接AP的设备,如:手机,笔记本电脑等,当ESP8266设置为AP模式时,其他设备可以接入该热点,最多支持4台Station设备接入。AP模式也是ESP8266默认的模式。
设置ESP8266流程如下:
1、首先发送AT+CWMODE?查询模块当前处于哪一种模式,下图可以知道AT+CWMODE=2就是热点模式。
2、然后我们发送AT+CWMODE=2,让模块处于热点模式下,同时我们的电脑上也会显示热点名称。
3、我们现在自定义设置我们ESP8266的热点名和密码,来看看我们电脑能不能连接我们所设置的好的ESP8266模块。
1、设置WIFI模式为AP模式
2、设置AP热点属性
AT+CWSAP=AT+CWSAP_DEF="ESP8266-XSD","12345678",5,3
其含义为:热点名为ESP8266-XSD,密码为12345678,使用通道5,加密方式为 WPA2_PSK,这里的通道对应的就是不同的射频频率,如果同一空间内存在相同通道的WIFI信号,将会产生干扰,影响上网质量,因此可以设置通道来避免这种干扰,常用的通道有1 6 11,因为这三个通道互不产生干扰。设置效果如下图所示:
连接数量可以限制Station设备的接入数量,广播或者不广播SSID就是指是否隐藏热点名,使热点更加安全。此外,AT+CWSAP=AT+CWSAP_DEF表示设置的参数会存储的flash,还有另外一个类似指令AT+CWSAP=AT+CWSAP_ CUR,该条指令表示设置的参数重启后失效,即不保存到flash中。其他的AT指令也有类似的后缀。
4、设置为Station模式
该模式是平时应用最多的模式,因为物联网设备需要连接到家中路由才可以接入外网,此时设备就作为Station连接到AP热点。设置Station并连接AP流程如下:
1、设置WIFI模式为Station
2、连接到家中路由器AT+CWJAP="liuyao","liuyao1001"
下图为连接过程的串口输出:
这时候我们进入家中的路由器,就能看到我们的ESP8266模块连接到了家中的路由器。如果想要断开连接,可以使用AT+CWQAP,就可以断开ESP8266与路由器的连接。
现在我们的ESP8266已经与家中的路由器连接上了,现在我们如果想获取连接的这个ESP8266的IP可以使用AT+CIPSTA?指令,返回的是路由器分配给ESP8266的局域网IP以及网关地址和子网掩码。
5、使用TCP实现局域网内的设备通信
建立TCP连接(AT+CIPSTART)
TCP实现局域网内的设备通信时先要让ESP8266连接到家中的热点。该条指令可以指定建立连接的协议类型,通常使用的有两种:TCP和UDP。
我们先打开网络调试助手,并将其设置为TCP Server端,具体设置如下:
接下来,发送AT指令建立TCP连接,成功连接会提示CONNECT,接着使用发送指令:AT+CIPSEND=14,其中15是发送数据的长度,该指令发送完成后,接收窗口会显示 > ,我们接着在发送窗口发送"I m TCP Client",TCP Server端会收到该信息,接着再通过TCP Server发送"I m TCP Server",串口接收端会打印Client收到的数据。
下面就是ESP8266连接当前环境的热点,与服务器建立TCP连接,传输数据的过程,所有的字符和标点必须是英。(1)设置WIFI模式为Station:AT+CWMODE=1(2)连家中路由器:AT+CWJAP="liuyao","liuyao1001"(3)TCP:AT+CIPSTART="TCP","192.168.0.103",8080(4)提示发送数据长度为14:AT+CIPSEND=14(5)串口调试助手发送:I m TCP Client(6)网络调试助手发送:I m TCP Server
这一步很多人可能很懵,不知道为啥要这样做,你这个搞的串口调试助手还有网络调试助手还有啥TCP Server到底是啥意思啊?
哈哈,我相信很多初学者学到这里也不是很清楚。我这里简单说一下,我们的用ESP8266是不是要让它连到家中的网啊,那在这里我们的网络调试助手的TCP Server就是我们要连接的网络。
有人又要说了,我要连家中路由器的网啊,为啥要连网络调试助手的网啊?这是因为如果你连家中的网,请问你如何给你家的路由器发送数据啊!你怎么知道路由器接收到了数据啊!路由器又咋给你发送数据啊!你又咋接收数据啊!我们这里用网络调试助手的目的就是让网络调试助手来代替路由器局域网。TCP Server就是服务端的意思也是就是服务器。至于为啥用串口调试助手我就不用说了吧,只有你在串口助手上调试好了,我们才用单片机的串口结合ESP8266共同代替客服端,也就不需要调试助手了。
所以说,我们一定要在串口调试助手上把相关的数据调通了,把原理过程搞懂了之后我们再去搞单片机程序,再去搭建你的服务器而不是用网络调试助手代替了。怎么样现在明白了吧!
开启透传传输(AT+CIPMODE=1)
前面在使用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!
如果想要退出透传发送模式,先发送+++(0x2B 0x2B 0x2B),注意没有换行符,接着使用AT+CIPMODE=0指令退出透传模式,恢复到默认传输模式。如果不退出透传模式,那么在透传模式下就不能发送AT指令了,它会默认为字符串发送。
6、使用SmartConfig为设备配网
前面使用了AT+CWJAP指令来主动连接家中的WIFI,但是在大多数的物联网产品中,缺少输入WIFI密码的输入设备,如:键盘,更不能将程序交给用户去修改家中的WIFI热点名和密码,在真正的项目开发中使用最多的方法就是通过一颗按键来使设备进入某种模式,并使用手机将当前WIFI的密码告知该设备来实现WIFI配网,这种模式就是SmartConfig。在该模式下,ESP8266会监听指定端口的UDP广播包,如果收到符合规定格式的广播包后会对其进行解析并获得WIFI的SSID和PWD,然后自动连接获取到的WIFI热点,从而实现WIFI配网。
智能配网需要三个设备:家中的路由器、WIFI模块、手机。模块处于station模式,手机连接好家中的wifi。这个具体的工作的原理是:我们需要将wifi配置为station模式。因为默认的是ap模式,然后要保证手机连接到家中的路由器热点。手机上面的第一行是我们手机此时连接的这个热点名,下面第一行需要用户去手动的输入路由器热点对应的密码,下面会有一个按键就写着叫配网(连接),那么当我们点击这个配网之后,手机则会以UDP的这种传输的方式。向某个端口号或某个IP地址当中去广播。广播内容是厂商自己封装的一个数据帧结构,广播的时候就不用去指定具体的IP地址,每个模组可能默认是不同的。只要指定账号,当我按下配网的这个按钮之后,此时它会UDP广播的形式向外连续的去发送一串儿厂商约定好的一个数据帧结构,比如说前面对应的是厂商的这个ID,后面跟的是这个热点名,后面跟着的是这个热点密码等。当然,也可以对它进行一些加密处理,如果此时我们通过按下这个。用点上面的某个按键,比如说是配置了我们这个wifi模组,进入了smartconfig这个配网模式。这个时候wifi模块会处于一个监听的状态。比如udp的协议监听8080端口上面这个数据。如果我收到了这一块儿有效的数据,那么他会将这里面有用的热点名和密码摘出来,然后使用类似透传模式这种功能,内部的将它连接到指定的热点上面,就实现了一键配网的过程。知道了ESP8266模块如何用了之后,接下来我们就要用STM32和ESP8266来实现与服务器的之间的数据收发!
我们说到了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,就能玩转物联网。
我们先来看个例子:
比如,我在微博里关注了“晓艳考研”,那么当“晓艳考研”发了一条微博后,我就能收到。
为什么能收到呢?是因为我关注它了,我想这些玩微博的小伙伴都知道。
下面,我再用图表示一下:
好了,到这边其实已经把MQTT协议的原理讲清楚了。“晓艳考研”相当于手机,我相当于单片机(控制器),如下图所示:这样的话,就实现了手机控制单片机的功能!在微博中,只有我关注“晓艳考研”这个号,才能收到对方发来的微博,那么在MQTT中,单片机订阅手机的这个主题才能收到手机发送的指令!这样一来,如果单片机再通过继电器接家里的电器,手机就可以控制家里任何电器的开关了!
通过这样的控制方式,就可以解决在单位也能开/关家里电灯的问题了。不过前提是,手机和单片机都能连上云服务器(手机可以用家里的网或者4G就可以连到云服务器,单片机可以通过家里的WIFI就可以连到云服务器)。
这时可能有人会问,在微博里像“晓艳考研”那么有名,有很多人都会关注,比如小雅、小李等等,只要“晓艳考研”发布消息了,关注的人都能收到。
在MQTT协议中也是如此,只要单片机1、单片机2、单片机3等都订阅了手机这个主题,那么只要手机发指令,就能控制各个单片机,那么也就是能控制家里的各个电器。
有的小伙伴脑子转的溜,感觉这样控制是有问题的。因为这样的话,手机是统一控制了家里的电器,总不能都一起开、一起关吧?
在微博有个功能,叫@。虽然我、小雅、小李都关注了“晓艳考研”,但“晓艳考研”在发布消息的时候还能@我,那么在MQTT协议中也是一样,也能@某个控制器。这样的话,就能单独控制某个功能了。
关于MQTT理论,我们先说到这儿,其实还有很多玩法,比如在微博里“晓艳考研”也关注了我呢?这个有什么用?这样可以用控制器采集信息上传到我们的手机了!那就可以采集家中的环境数据上发到你的手机。
二、实现部分
根据下面这张图,我们要做三部分:单片机、云服务器、手机。
1、单片机
一般来说,单片机也叫作控制器,或者下位机。我们这里用的是STM32单片机。
这时有人会问,为什么不用51单片机,或者arduino?因为现在用STM32的人太多了,arduino又体现不出你是一个电子信息专业的,51就不用说了。
可能又有人说,你为啥不用esp32,本来就可以当一块单片机,搞个STM32岂不是太麻烦?
此言差矣!我们这里是把ESP8266当做一个模块使用,我仅仅用STM32的串口就可以控制它连网。但如果单单只用ESP32的话,就大大增加了开发的难度,也就是我们通常说的SDK开发,而且学习的同时,又能巩固单片机的知识,搞SDK确实不适合初学者。
最后,我们的MQTT协议转换成C语言代码已经有前辈写好了,我们的目的就是学会它,学会反向学习,才能增加你对新事物的学习兴趣。MQTT协议是现成的,拿来用即可!
在理论部分提到的MQTT协议是整个物联网的核心,所以单片机、手机和云服务器都要有这协议。这就好比三个中国人在聊天,一个日本人过来听,他根本听不懂,因为他没有“中文”这个能力。所以,控制器也要有这个解析协议的能力。
2、服务器
服务器可以理解成一台普通的电脑,只是它的性能比较稳定不容易死机。目前服务器有很多,做得比较大的像腾讯云、阿里云等等,购买服务器也是个坑,大家需谨慎!前期的话,大家学习不用买,登录生活物联平台用现成的,后面我会讲到。
3、手机
一般把手机也叫上位机,上位机还有电脑、平板等等,实验中是用手机发送命令来控制我们的单片机。那么手机能打开直接能操作吗?显然不能,需要编写相应的程序界面。
如果你是安卓手机,可以用android studio软件编写相应的app程序。当然,前期的话,大家不要去想着做一个app,难度还是蛮大的。
【三】
在学习MQTT之前,我们要明白MQTT通讯是通过很多的报文组成的,这就好比二战时期发电报进行两军之间的通信。这个报文呢,主要由三部分组成:固定报文+可变报文+有效载荷,这是官方起的名字,你可以把它理解为开头+正文+结尾,这样就好理解多了是吧?!
基本在MQQTT中,所有的报文都由这三部分组成。比如今天要说的Connect控制报文,顾名思义就是客户端(ESP8266)请求与服务端(阿里云服务器)建立连接的报文。
啥意思呢?这就好比你第一次去你女朋友家,你要首先打一个电话(Connect控制报文)征得叔叔阿姨的同意啊!叔叔阿姨同意之后(服务器确认建立连接)你才能去对吧,如果不同意或者电话没打通你就不能去你女朋友家啊,就算去了也不招待见对吧!
00:22
客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是connect报文(因为客户端和服务端必须要建立连接后才能进行通信)。
1、CONNECT控制报文主要由三部分组成:固定报头、可变报头、有效载荷。
2、假设我们得到了固定报头是“liuyao”、可变报头是“iloveyou”、有效载荷是“zhuxiaoya”。我们要把这些字母转换成对应的16进制。然后再把它们串联起起来就得到。
1、固定报头
固定报头包含两个字节,第一个字节是固定的:0x10,第二个字节是是剩余长度字段,剩余长度等于可变报头的长度(10字节)加上有效载荷的长度。
最终固定报头:综上可得固定报头为:10 ??(??我们在后面的实验会提到,先不着急)。
2、可变报头
可变报头有四部分组成,协议名、协议级别、连接标志、保持连接。大家不要纠结为啥由这四部分组成,这是人家写这个协议的人规定的,你只要搞清楚这四部分对应的编码是啥就可以了,其余的四个字:不要纠结。
2.1 协议名
2.2 协议级别
2.3 连接标志
2.4 保持连接
2.5 总结
2.6 最终可变报头
综上,我们可得有效报头为:00 04 4D 51 54 54 04 C2 00 64
3、有效载荷
有效载荷由三部分组成:客服端标识符、用户名、密码组成。
3.1 原始数据
我们在阿里云物联网平台上创建一个设备后,会得下面这三个数据,这三个数据非常重要。
{ "ProductKey":"a10zwkUxQUS", "DeviceName":"LY-1", "DeviceSecret":"d8b9915513b05d4de32fbed04566edd8" } 阿里云服务器地址(华东2) : *.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883
客户端ID :*|securemode=3,signmethod=hmacsha1| 用户名:*&# 密码: clientId*deviceName*productKey#
3.2 加工后的数据
服务器地址:a10zwkUxQUS.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 客户端ID :LY-1|securemode=3,signmethod=hmacsha1| 用户名:LY-1&a10zwkUxQUS 密码:clientIdLY-1deviceNameLY-1productKeya10zwkUxQUS 经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87 哈希加密在线计算网站:http://encode.chahuo.com/之后要将客服端ID、用户名、经过哈希加密后的密码转换成16进制。
客户端ID :LY-1|securemode=3,signmethod=hmacsha1| 用户名:LY-1&a10zwkUxQUS 经过哈希加密:7a03368e740ff9efb8318c6ba2a0260f2a596f87