<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_A/aly.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节演示一下基本控制篇中使用阿里云物联网平台实现远程控制的最终功能.
这一节实现微信小程序扫码绑定Air202并通过阿里云物联网平台实现远程通信控制(动态免预注册)
这节涉及到的知识点为:自定义Topic,规则引擎.
微信小程序和Air202各自以单个的设备接入物联网平台,然后使用自身的自定义Topic发布和接收消息.
消息经过规则引擎使得二者之间通信.
请用户按照此节的说明进行操作,然后完成测试.
动态注册需要SSL,默认的固件不支持SSL,需要刷固件
1.提醒
为防止烧录过程中被STM32复位,把boot0接3.3V,然后复位下STM32,不要让STM32工作!
为防止烧录过程中被STM32复位,把boot0接3.3V,然后复位下STM32,不要让STM32工作!
为防止烧录过程中被STM32复位,把boot0接3.3V,然后复位下STM32,不要让STM32工作!
2.打开软件
3.把开发板连接电脑
4.调整波动开关,让模组的烧录口和软件通信,然后复位下模组
5.点击AT 选择切换为SSL版本
6.点击下载
测试准备
1.打开这节的微信小程序工程和单片机工程
2. 登录自己的云平台点击产品的查看
3.打开动态注册按钮
4.查看自己产品的ProductSecret; ProductKey;
5.修改单片机程序里面的参数 ProductSecret; ProductKey;
6.修改微信小程序里面的参数 ProductSecret; ProductKey;
配置规则引擎(如果前面章节配置过,不需要再配置)
1.规则引擎 ,云产品流转,创建规则
2.选择编写 SQL
3.添加操作
4.注意①自己填写 ${TargetDevice}
5.启动规则
硬件准备工作
1.请使用杜邦线连接如下:
白线 A3 --- TX
黑线 A2 --- RX
2.当前拨动开关如下:(让单片机的串口1和电脑USB连接)
3.把修改完的单片机程序下载到单片机,并打开串口调试助手
串口1在程序里面作为了日志打印输出口
用户可以打开串口调试助手观察日志
微信小程序准备工作
1.在微信小程序平台上设置域名白名单(推荐)
域名为自己设备连接的MQTT服务器的IP地址:
2.如果不设置域名白名单也可以在软件上选择忽略校验域名
3.点击编译预览,微信扫码安装到手机
4.运行APP会弹出注册页面.
注:这个步骤是让微信小程序在物联网平台上注册个设备,让微信小程序接入云平台.
设备的名字做成了需要用户去填写,用户如果做产品的话可以用用户的手机号替代.
5.填写 222222(随意哈) 后点击 注册设备
3.注册成功将会跳转到主页
4.在平台上可以看到在相应的产品下面注册了设备
开始整体测试
1.点击小程序下方的添加设备按钮
2.选择 扫码添加
3.扫描GPRS模块上的二维码
4.扫描成功以后,自动跳转到主页面,并添加了一个设备(设备显示的信息为Air202的IMEI号)
5.点击设备进入设备控制页面,页面显示温湿度数据和继电器状态
整体通信流程说明
微信小程序和单片机各自作为阿里云的设备接入阿里云服务器.
微信小程序接入的名字为用户注册时填写的名字;
单片机接入的名字为模组的MAC地址;
微信小程序 配网绑定的时候添加的模组的MAC地址.
假设微信小程序注册的设备的名字为: 222222
假设模组的IMEI为: 868900000000000
APP发布的主题: /a1m7er1nJbQ/222222/user/update
这个主题发给云平台以后,经过了转发规则里面的SQL语句
注: /a1m7er1nJbQ/+/user/update (里面的 + 代表任意)
微信小程序发布的主题为 /a1m7er1nJbQ/222222/user/update 所以,符合条件.
然后就提取这个主题里面的消息.
微信小程序发布的消息为:(以控制继电器为例子)
{"TargetDevice":"868900000000000","DeviceName":"222222","data":"switch","bit":"1","status":"1"}
注:
TargetDevice 字段的值是微信小程序添加的设备的名字
DeviceName 字段的值是微信小程序本身设备的名字.
然后下面的配置是对提取的消息进行操作
发布到另一个 Topic /a1m7er1nJbQ/${TargetDevice}/user/get
${TargetDevice}意思是提取消息里面字段为 TargetDevice 的字段值,然后替换上面的 ${TargetDevice}
咱的消息是 {"TargetDevice":"868900000000000","DeviceName":"222222","data":"switch","bit":"1","status":"1"}
所以最终消息转发给下面的主题(也就是单片机订阅的主题)
/a1m7er1nJbQ/868900000000000/user/get
然后单片机就收到了消息 {"TargetDevice":"868900000000000","DeviceName":"222222","data":"switch","bit":"1","status":"1"}
单片机接收到消息以后,提取 "DeviceName":"222222"
然后用自己的发布主题发布消息
发布的主题: /a1m7er1nJbQ/868900000000000/user/update
发布的消息: {"TargetDevice":"222222","DeviceName":"868900000000000","data":"switch","bit":"1","status":"1"}
TargetDevice 字段的值改为了 222222
DeviceName 字段的值为单片机设备的名字 868900000000000
消息发给了服务器,然后经过转发规则,同理 ,消息便会转发给了微信小程序
最后微信小程序 提取消息里面的数据,就完成了通信
一型一密(免预注册): 免预注册就是不用在云端自己注册设备,设备连接上网络以后设备自己去注册.
这样子的话,每个设备烧录同样的程序就可以,不用再配置什么三元组了!
不过每个设备程序里面的需要写上产品的ProductKey 和 ProductSecret 的值,这两个值是固定的.
主要是区分开你注册的时候注册到哪个产品下.
然后设备通过https或者mqtt接口注册设备,
注册的时候服务器会返回ClientID和DeviceToken 等参数
最后按照平台规定的组合MQTT参数
MQTT连接的方式注册设备:
拼接注册返回的参数连接MQTT:
单片机程序详细说明
1.串口使用情况
程序使用串口2和模组通信
串口1作为日志输出口
串口1接收数据采用缓存管理+空闲中断
串口1发送数据采用环形队列+中断发送
串口2接收数据采用缓存管理+空闲中断
串口2发送数据采用中断发送
2.串口2的空闲中断是使用定时器自定义的,为了兼容GSM模组程序
3.串口1打印串口2接收的数据
判断串口2接收的数据以后,直接把数据插入串口1环形队列
4.串口1打印串口2发送的数据
在串口2调用发送数据的地方,把发送的数据插入串口1环形队列
5.串口2接收的数据,传递给配置函数和MQTT数据处理函数
7.正常运行配置函数 ConfigModuleNoBlock
8.获取模组的IMEI,后面作为注册设备的名字
9.如果没有注册设备,则执行注册,如果已经注册,则跳过注册步骤执行连接
10. ① 打包注册协议,并发送, 发送数据指令给模组
11. ② 发送数据
12. ③ 解析注册返回的应答数据
注:此函数组合拼接了mqtt的ClientID 和 mqtt的密码并存储到flash.
13.注册完成以后使用注册的信息接入MQTT
14.执行连接成功回调函数,在里面订阅主题,并发送数据给已经绑定的APP设备
提示:为使设备可以同时发送数据给与其绑定的APP,代码中使用了 BufferRankOrder 记录APP设备名称
设备发送数据的时候轮训把数据发给和自己绑定的APP.
关于为啥要用数组记录APP设备的信息?
必须有数组去记录APP信息,因为如果多个人同时在控制,设备必须把数据返回给每一个控制的APP.
如果谁控制就返回给谁数据,就会出现谁控制谁的页面有变化,其他人的控制页面没有变化的尴尬局面.
所以需要把数据返回给所有的APP
但是也不能把所有的APP信息都记录下来,因为不合理.
需要把这些APP做个优先等级排序.经常控制的要靠前,不经常的靠后,基本上没影了的放到最后,直至丢弃
注:关于 BufferRankOrder https://www.cnblogs.com/yangfengwu/p/14164215.html
假设有5个APP和单片机通信,APP设备的名字分别为: "111111","222222","333333","444444","555555"
假设这5个设备依次和单片机通信,1-5 (谁最后和单片机通信就把谁放到第一个位置.)
那么这些名字在BufferRankOrder内存里面的排序 "555555","444444","333333","222222","111111"
哪个APP不经常和设备通信,那么这个APP最终将会被挤掉.最终只留下经常和设备通信的.
15.接收处理消息
16.定时发送温湿度数据给APP
17.如果继电器状态改变,发送继电器状态数据给APP
微信小程序详细说明
1.MQTT参数放在了public里面,方便其它文件调用
2.程序运行的时候,如果有存储的注册信息则执行连接MQTT,如果没有注册,则跳转到注册页面.
3.注意,无论有没有注册都会执行连接MQTT,MQTT内部函数如下
没有注册的时候之后不停的进入此函数,因为没有连接信息,所以并不执行连接.
4.用户输入设备名称点击注册后执行注册程序
5.发送注册命令以后,接收服务器的注册信息,并存储到手机,然后初始化MQTT的连接参数,跳转到主页.
6.初始化参数以后,host和ClientID不再为空,MQTT就可以正常的执行连接
7.点击--添加设备--扫码添加,启动扫描页面
8.扫码成功以后,携带着扫描信息跳转到主页面
11.跳转到主页以后,先执行onLoad获取存储设备信息,然后调用onShow把设备显示在页面
12.点击设备时,携带着所点击设备的名称跳转到控制页面
13.在控制页面获取跳转的设备的名称,组合微信小程序自身设备的订阅的发布的主题
根据跳转的设备的名称组合发送的数据.
14.调用MQTT函数订阅自身的主题
15.订阅成功以后启动定时器每隔3S发送一次查询所有数据命令
16.点击按钮发送控制继电器命令
17.处理接收的数据
18.细节说明1
因为平台上设备离线的遗嘱或者相应的topic没有对基础用户开放,
所以每隔3S发送一次请求设备数据,是为了知道设备是不是还在线.
发送一次请求所有数据命令会置位下面的标志
如果设备回复了,会清除这个标志
如果设备没有回复,则再下次发送查询指令的时候会提示设备离线
19.细节说明2
请求所有数据里面也有开关数据,如果先发送了请求所有数据命令
然后用户接着点击了控制开关,控制开关的那个页面会显示到控制继电器吸合的状态
设备会先返回设备关状态,然后再返回设备开状态
就会看到按钮从开状态变为关状态,然后再变为开状态.
所以在用户点击按钮之后3S内,不处理查询指令里面开关状态