智能家居、物联网 通信模块方案实现(P2P方式)
本课程将教大家如何去实现物联网的基本通信,嵌入式设备 和 手机APP 的通信。以及云平台的工作原理。
前言
目前物联网的架构大概分为有网关 和 无网关两大类型。对于有网关的系统,网络通信由网关承担,其他设备通过 各类有线、无线通信方式和智能网关进行数据交换。从而简介的达到物联网的效果。
还有一种场景是无网关模式。所有的设备都进行网络通信,数据交换。
对于无网关模式,大多数都需要实现联网功能。目前最常见的两种联网方式:
wifi 模块,例如 ESP8266。但是wifi需要附件有无线热点,一般适用于家庭、或者一些公共场合。
- 采用 GSM 模块 ,此场景一般适用于室外、工业等无人场合。尤其是5G的到来,更是推动了物联网的发展。
但是目前没办法做到每个设备都有一个独立的IP,故而无法简单地实现设备端的点对点通信。
为了实现手机APP 和 设备的数据交换。我们需要借助云平台。事实上云平台的通信过程很简单。设备A 和设备 B 分别在 服务器上登记。当设备A要发送数据给设备B 时,只需要把数据发给服务器,然后告知服务器把数据转发给 设备 B 即可。
目前市场上有很多云平台。我们可以选用一款免费的云平台。比如腾讯物联云、旗点云等。
关于腾讯云平台的使用可以参考官网。但是腾讯云平台的一个问题就是所有数据都要经过腾讯云平台处理。不利于后期的发展。
旗点云则是可以开放云平台源码,并能够部署在自己的服务器上。可以参考官网:
C语言开发包:
下载 C 语言开发包、Android 开发包。
下载链接:http://106.13.62.194/download/qdy/01demo/
1、C 语言开发包
下载后我们可以看到这些文件:
其中 client_demo.c 是一个在linux 上跑的demo 程序。
(1)设置设备ID、厂家ID、密码。
可以使用标准
set_name(device_id, strlen(device_id) + 1);
set_custmoer("test", strlen("test") + 1);
set_passwd(1234);
(2)设置我们的发送函数
set_net_send(my_send);
其中,my_send 就是根据实际情况的网络数据包发送函数。例如在linux 的socket 编程模型中是这样的:
事实上它就是调用socket的标准接口函数 sendto 函数了。
使用 set_net_send(my_send) 的方式去设置我们的网络发送函数,一个好处就是良好的可移植性。只需要在不同的平台设置成对应的发送函数即可。
(3)登录到服务器
login(&servaddr);
这是一个标准的函数模型。我们可以看看:
它通过 使用 __compages_head 接口函数构造数据包。数据类型是 _aff_client_login_ 登录请求。然后填写上 device id 和 密码(1234)、厂家ID(test)。最后数据发送给服务器请求登录。
(4)数据包接收处理
通过 recvfrom 接收到数据包后,通过调用 qdy_recv_data 的接口函数对数据包进行协议解析处理。最后会跑到 qdy_resolve_recv_data 函数中,我们来看下这个函数的原型:
我们可以看到数据是谁发送给我们,也可以看到数据的内容:
recv_proto->src_name :谁发送的数据包
recv_data : 数据的内容
(5)数据发送
int qdy_send_data(char *name, char *data, int len)
name : 设备ID
data :数据
len : 数据长度
可以看到整个过程比较简单。
(6)STM32 移植
对此,我们可以把整个C语言开发包导入到 STM 32 单片机中。使用SIM800 GSM 模块进行通信。
我们可以直接把 三个 .c文件直接导入到项目工程中
只需要简单的修改 client_demo.c 文件即可。把里面的 socket 相关的通信 替换成 SIM800A 的AT 通信接口函数。
修改如下:
把 send 网络发送函数设置成AT 指令发送函数
把其中的所有socket 通信的函数 换成对应的AT 指令发送函数
2、Android 平台开发包。
SDK 包是一个简单的手机测试程序。我们来看下Android代码怎么写吧。
其实只需要使用到三个类:
QiDiSendData 发送数据包类
QiDiRecvData 接收数据包类
QiDiConfig 旗点云的协议封装
(1)登录函数
使用 QiDiSendData 类构造一个 QiDiConfig.AFF_CLIENT_LOGIN 的登录数据包。然后通过 udp 接口函数发送给服务器即可。
类: QiDiSendData 用来构造旗点云数据包,参数分别是:
协议:
设备ID:
密码:
厂家ID:
(2)同步函数
同样的,使用 QiDiSendData 构造一个 QiDiConfig.AFF_CLIENT_SYNC 同步数据包即可
(3)发送数据包
也是使用 QiDiSendData 构造一个 QiDiConfig.AFF_CLIENT_SEND_DATA 类型的数据包. 然后使用 sendData.SetSendData 设置我们要发送的数据包。填入的参数分别是 发送给谁,数据内容。
最后通过 UDP 把数据发送给服务器即可。
(4)接收数据
使用UDP接收数据后,把数据内容 传给 QiDiRecvData 类进行解析
并根据 recvData.GetAff() 的类型判断是否为数据包。
如果是,则对数据进行处理
使用 GetSrcName 可以获取到是谁发送过来的数据包
使用 GetData 可以获取到数据包内容。