<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_A/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节演示一下基本控制篇中使用阿里云物联网平台实现远程控制的最终功能.
这一节实现Android扫码绑定Air202并通过阿里云物联网平台实现远程通信控制(动态免预注册)
请用户按照此节的说明进行操作,然后完成测试.
动态注册需要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.打开这节的APP工程和单片机工程
2. 登录自己的云平台点击产品的查看
3.打开动态注册按钮
4.查看自己产品的ProductSecret; ProductKey;
5.修改单片机程序里面的参数 ProductSecret; ProductKey;
6.修改Android程序里面的参数 ProductSecret; ProductKey;
配置规则引擎(如果前面章节配置过,不需要再配置)
1.规则引擎 ,云产品流转,创建规则
2.选择编写 SQL
3.添加操作
4.注意①自己填写 ${TargetDevice}
5.启动规则
硬件准备工作
1.请使用杜邦线连接如下:
白线 A3 --- TX
黑线 A2 --- RX
2.当前拨动开关如下:(让单片机的串口1和电脑USB连接)
3.把修改完的单片机程序下载到单片机,并打开串口调试助手
串口1在程序里面作为了日志打印输出口
用户可以打开串口调试助手观察日志
Android准备工作
1.重新安装APP,运行APP会弹出注册页面.
注:接入的设备的名字做成了需要用户去填写
2.填写 111111(随意哈) 后点击 注册设备
3.注册成功将会跳转到主页(允许权限)
4.在平台上可以看到在相应的产品下面注册了设备
开始整体测试
1.打开APP,点击右上角菜单,选择添加设备 "扫一扫"
5.扫描成功以后,自动跳转到主页面,并添加了一个设备
设备显示的信息为Air202的IMEI号
4.点击显示的设备,进入设备控制页面
页面显示温湿度数据和继电器状态
5.控制继电器
整体通信流程说明
APP和单片机各自作为阿里云的设备接入阿里云服务器.
APP接入的名字为用户注册时填写的名字;
单片机接入的名字为模组的IMEI;
APP 扫码的时候添加的模组的IMEI.
假设APP注册的设备的名字为: 111111
假设模组的IMEI为: 868900000000000
APP发布的主题: /a1m7er1nJbQ/111111/user/update
这个主题发给云平台以后,经过了转发规则里面的SQL语句
注: /a1m7er1nJbQ/+/user/update (里面的 + 代表任意)
APP发布的主题为 /a1m7er1nJbQ/111111/user/update 所以,符合条件.
然后就提取这个主题里面的消息.
APP发布的消息为:(以控制继电器为例子)
{"TargetDevice":"868900000000000","DeviceName":"111111","data":"switch","bit":"1","status":"1"}
注:
TargetDevice 字段的值是APP添加的设备的名字
DeviceName 字段的值是APP本身设备的名字.
然后下面的配置是对提取的消息进行操作
发布到另一个 Topic /a1kalhdMH2Z/${TargetDevice}/user/get
${TargetDevice}意思是提取消息里面字段为 TargetDevice 的字段值,然后替换上面的 ${TargetDevice}
咱的消息是 {"TargetDevice":"868900000000000","DeviceName":"111111","data":"switch","bit":"1","status":"1"}
所以最终消息转发给下面的主题(也就是单片机订阅的主题)
/a1kalhdMH2Z/868900000000000/user/get
然后单片机就收到了消息 {"TargetDevice":"868900000000000","DeviceName":"111111","data":"switch","bit":"1","status":"1"}
单片机接收到消息以后,提取 "DeviceName":"111111"
然后用自己的发布主题发布消息
发布的主题: /a1kalhdMH2Z/868900000000000/user/update
发布的消息: {"TargetDevice":"111111","DeviceName":"868900000000000","data":"switch","bit":"1","status":"1"}
TargetDevice 字段的值改为了 111111
DeviceName 字段的值为单片机设备的名字 868900000000000
消息发给了服务器,然后经过转发规则,同理 ,消息便会转发给了APP
最后APP 提取消息里面的数据,就完成了通信
一型一密(免预注册): 免预注册就是不用在云端自己注册设备,设备连接上网络以后设备自己去注册.
这样子的话,每个设备烧录同样的程序就可以,不用再配置什么三元组了!
不过每个设备程序里面的需要写上产品的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
Android程序详细说明
1.基本目录说明
ActivityDeviceControl: 设备控制
ActivityRegDevice: 设备注册
aly_hmac: 计算MQTT密码
DataBaseLitepal: Litepal数据库存储
MyMqttClient: 封装的正常使用的MQTT接口
RegisterDeviceForMqtt: 注册接口
SharedPreferenceHelper: 封装的 SharedPreferences ,用于存储记录注册信息
google.zxing: google的扫码包
2.如果SharedPreferences 里面没有记录的注册信息,跳转到注册页面
3.点击按钮注册设备,并把注册信息存储以后跳转到主页面
4.获取注册的数据,并执行连接
5.组合参数连接MQTT服务器
6.启动扫码
7.扫描到二维码(设备的IMEI号)以后执行以下程序(携带着扫码信息传给主页面)
8.在主页的 onNewIntent 接收并存储设备信息
9.点击相应的设备以后,把设备的信息传递给控制页面
10.控制页面组合APP这个设备本身发布和订阅的主题
11.组合发布给设备的消息
12.在定时里面请求设备数据,和订阅主题
13.接收处理数据
14.控制继电器