之前的文章记录到了GPIO的输入、输出、复用I2C通信,模拟单总线通信,到这已经可以做很多“电子垃圾”了,有了温湿度,有了IO控制,一个将数据上传到云端实时显示,以及利用云平台运城控制的想法油然而生,于是写bug的时光又开始了,本文利用Hi3861接入OneNET云端,模拟上传大棚的温湿度,并可以通过远程开关控制继电器。
OneNET物联网专网已经应用于环境监控、远程抄表、智慧农业、智能家电、智能硬件、节能减排、车联网、工业控制、物流跟踪等多种商业领域。1物联网开放平台OneNET通过打造接入平台、能力平台、大数据平台能力满足物联网领域设备连接、协议适配、数据存储、数据安全、大数据分析等平台级服务需求。2
OneNET平台具有丰富的接口,官方提供了如NB-IoT(LWM2M)、MQTT、EDP、Modbus、HTTP等协议接口,可以满足多种应用场景的使用需求。而且平台还提供了丰富的功能,本文就使用到了设备接入、数据可视化View的功能。
有关OneNET的详细介绍可以去官方平台简介查看。
本文使用MQTT协议接入,MQTT也是一个软件层的协议,和笔者之前介绍的Modbus同属于一个层次,是用来解决数据怎么传,怎么打包,怎么给数据包内做好断句和数据位的定义,使得通信双方能够根据这个协议的定义去解析出数据包中的数据,从而实现通信的目的。
这些软件层的协议理论上是可以搭载在任何一个硬件层协议之上的,拿STM32接入OneNET举例,常用方案是STM32使用串口通信与ESP8266这类无线模组连接,无线模组就需要按照MQTT或者HTTP的通信格式发送和接收数据包。
由于Hi3861自带联网功能,所以就不需要再外挂ESP8266这类联网模块。
笔者使用的是旧版的平台,可以直接从这个连接进入OneNET旧平台。
进入后,如果之前有创建过产品就可以在下方看见。
这里直接创建一个新的鼠标挪到左侧全部产品,选择多协议接入。
等待弹出一个新建页面如下:
点击添加产品,在右侧输入产品信息,大部分根据自己的想法写就行,需要注意的是技术参数选择wifi、MQTT旧版、无操作系统。
创建完毕后就可以看见自己的产品了,点击产品来到概况页,这里需要注意一下产品ID和Master_key,Master_key需要短信验证才能查看。
至此,产品就已经创建好了,接下来还需要创建一下设备。
1.点击左侧设备列表,然后再点击添加设备;
2.在右侧添加设备信息,最后点击添加即可;
3.添加完成后点击详情;
4.在这里需要生一个APIKey,后面程序用的着。
至此就OneNET端就创建完毕了,接下来需要去配置Hi3861。
参考前面两篇的硬件连接方式进行OLED和DHT11的连接,然后再找一个GPIO脚用来控制继电器即可。
笔者的连接情况如下:
GPIO号 | 模块引脚 |
---|---|
GPIO9 | OLED SCL |
GPIO10 | OLED SDA |
GPIO8 | DHT11 DATA脚 |
GPIO12 | 继电器控制脚 |
接线图如下: | |
这里笔者使用了小熊派官方OneNET的SDK,接口函数操作起来和STM32的接入流程大致相似。
打开onenet联网示例,要将宏定义里面的产品信息、设备信息、Wifi名称以及密码修改为自己的;产品ID、Master_key可以在产品概况查到,Master_key需要接收用户手机验证码验证;设备ID、鉴权信息、APIkey在设备详情里面可以直接CV。
产品参数:
设备参数:
点击详情即可查看。
此步骤完成后可以先编译下载一下,复位后可以在串口调试助手上看见联网情况:
出现“WIFI connect succed!”表示联网成功,此时打开OneNET就可看见设备显示在线;
点击数据流就可以看见如下图的三个数据,分别是温度湿度和光照强度,只不过此时数据都是0。这是因为小熊派的代码是基于他们智慧农业的解决方案来的,他们使用的是SHT20和光照来采集温度和光照强度,没有接模块自然没有读数了,笔者没有买这个模块,所以用了自己手头的DHT11来代替。
小熊派在编写这个代码的时候都是模块化的代码,只需要稍作修改即可,由于要是用DHT11,和OLED;首先就需要导入这两个模块的.h文件,这个在之前的OLED显示和DHT11温湿度采集中已经介绍了,代码笔者后期整理后会上传可以自行下载,也可直接私聊获取。
代码片段:
//联网及数据传输
void MQTT_Report_Task(void)
{
WifiConnect(Wifi_SSID, Wifi_PASSWORD);//连接wifi
device_info_init(ONENET_INFO_DEVID, ONENET_INFO_PROID, ONENET_INFO_AUTH, ONENET_INFO_APIKEY, ONENET_MASTER_APIKEY);//初始化用户产品设备信息
onenet_mqtt_init();//OneNET 初始化函数,需要在使用 OneNET 功能前调用。
onenet_set_cmd_rsp_cb(onenet_cmd_rsp_cb);//接收到命令的回调函数
while (1)
{
onenet_mqtt_upload_digit("Temperature", (int)E53_IA1_Data.Temperature);//利用 mqtt 向 OneNET 平台发送温度数据。
onenet_mqtt_upload_digit("Humidity", (int)E53_IA1_Data.Humidity);//利用 mqtt 向 OneNET 平台发送湿度数据。
onenet_mqtt_upload_digit("Luminance", (int)E53_IA1_Data.Lux);//利用 mqtt 向 OneNET 平台发送光照强度数据。
sleep(1);
}
}
//参数采集任务
static void Sensor_Read_Task(void)
{
u8 ledflag=0;
u8 temperature=0;
u8 humidity=0;
while(DHT11_Init()) //DHT11初始化
{
printf("DHT11 Init Error!!\r\n");
usleep(1000000);
}
while (1)
{
if(DHT11_Read_Data(&temperature,&humidity)==0) //读取温湿度值
{
ledflag++;
if(ledflag>=150)
ledflag=0;
E53_IA1_Data.Lux=ledflag;
E53_IA1_Data.Humidity = humidity;
E53_IA1_Data.Temperature = temperature;
}
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_2, ledflag%2);//运行指示灯
sleep(2);
}
}
static void MQTT_Demo(void)
{
osThreadAttr_t attr;
attr.name = "MQTT_Report_Task";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 10240;
attr.priority = osPriorityNormal;
if (osThreadNew((osThreadFunc_t)MQTT_Report_Task, NULL, &attr) == NULL)
{
printf("Falied to create MQTT_Report_Task!\n");
}
attr.name = "Sensor_Read_Task";
if (osThreadNew((osThreadFunc_t)Sensor_Read_Task, NULL, &attr) == NULL)
{
printf("Falied to create Sensor_Read_Task!\n");
}
}
APP_FEATURE_INIT(MQTT_Demo);
通过上述代码即可实现温湿度的采集以及数据上传值OneNET端。
当然也可以自己做一个可视化界面,用来动态显示数据,类似下图的效果:
至此就完成了数据上传到OneNET端的操作,后面会再出一篇介绍可视化界面的搭建。
在小熊派的代码中,提供了下发命令的回调函数,其中recv_data接受的数据内容、recv_size是数据长度resp_data是返回给云端的数据内容resp_size是返回的数据长度。如下图所示,在下发命令的窗口下发数据就可以在Hi3861端接收到。
既然可以接收到数据,那么稍加改造就可通过指令来控制外设了。这里笔者使用了string.h内的strcmp函数来进行字符串比较,如果比较结果一致就可以控制相应的外设了。
代码如下:
void onenet_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
{
/* 申请内存 */
/* 解析命令 */
/* 执行动作 */
/* 返回响应 */
printf("recv data is %.*s\n", recv_size, recv_data);
// printf("recv data is %s",(char*)recv_data);
if (strcmp("RON",(char*)(recv_data))==0)//检测到接收数据中有对应字符串就执行
{
printf("ON\r\n");
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 1);//设置GPIO_2输出高电平点亮灯
}
if (strcmp("OFF",(char*)(recv_data))==0)
{
printf("OFF\r\n");
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_12, 0);//设置GPIO_2输出低电平关闭灯
}
*resp_data = NULL;
*resp_size = 0;
}
来看下实际使用效果,这里是笔者利用OneNET可视化平台做的一个应用,可以在各个终端上打开并实现控制,这里使用平板发送RON,就可以打开继电器;发送OFF即可关闭继电器。更多效果展示可以去笔者的B站视频查看——OpenHarmony南向开发日常–基于Hi3861与onenet的远程温湿度检测。
需要详细了解整个流程以及API接口的使用的可以参考小熊派官方文档:
BearPi-HM_Nano开发板WiFi编程开发——MQTT连接OneNet
有关Hi3861上传数据到OneNET端监控以及通过远程命令控制设备的介绍就记录到此,有不足之处欢迎批评指正。
OpenHarmony学习笔记——南向开发环境搭建
OpenHarmony学习笔记——编辑器访问Linux服务器进行编译
OpenHarmony学习笔记——点亮你的LED
OpenHarmony学习笔记——多线程的创建
OpenHarmony学习笔记——I2C驱动0.96OLED屏幕
OpenHarmony学习笔记——Hi3861使用DHT11获取温湿度
OpenHarmony学习笔记——Hi3861接入OneNET
手把手教你OneNET数据可视化
OpenHarmony学习笔记——Hi386+ASR-01的语音识别助手
中移动物联网用户超2000万 推OneNET平台招募计划 ↩︎
中国移动物联网开放平台—OneNet ↩︎