物联网,启动!基于OneNET平台实现物联网功能
本帖最后由 宇岚 于 2025-7-17 14:51 编辑#申请原创# #技术资源#
背景
随着时代的发展,“智慧生活”一词逐渐被频繁提及;智慧生活平台是依托云计算技术的存储,在家庭场景功能融合、增值服务挖掘的指导思想下,采用主流的互联网通信渠道,配合丰富的智能家居产品终端,构建享受智能家居控制系统带来的新的生活方式,简单来讲,就是利用物联网实现嵌入式设备自动化;简介物联网(Internet of Things,简称 IoT),是通过传感器、通信技术、计算设备等将物理世界中的物体连接到互联网,实现物与物、物与人之间的数据交互和智能控制的系统。而OneNET是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,实现方法简单,功能多样,最重要的是,基础功能免费!实现原理IoT平台主要通信方式为MQTT协议,MQTT协议中主要参与者有三位,发布者(Publisher)、服务器(Broker)以及订阅者(Subscriber),消息结构则是分为主体(Topic)和负载(Payload)两部分;MQTT协议运行工作,简单来讲,就是发布者凭借服务器在平台发布作品,订阅者在平台订阅作品;协议结构MQTT协议中主要参与者有三位,发布者(Publisher)、服务器(Broker)以及订阅者(Subscriber),消息结构则是分为主体(Topic)和负载(Payload)两部分;Broker(代理服务器):MQTT 系统中负责接收和分发消息的服务器,是 MQTT 系统的核心组件。Publisher(发布者):向 Broker 发布消息的客户端,可以选择一个或多个主题进行消息发布。Subscriber(订阅者):订阅感兴趣的主题,并接收相关消息的客户端。Topic(主题):用来标识消息的分类和结构。Publisher 将消息发布到特定的主题上,Subscriber 订阅特定的主题以接收相关消息。Payload(负载):消息订阅者所具体接收的内容。
协议通信过程MQTT协议通信过程如下:
[*]客户端连接:Publisher 或 Subscriber 通过 TCP/IP 连接到 Broker。
[*]客户端注册:客户端发送 CONNECT 报文到 Broker,包含客户端的身份认证信息、协议版本号等。
[*]会话建立:Broker 接收到 CONNECT 报文后,根据客户端的身份认证信息进行验证,并为客户端创建对应的会话。
[*]主题订阅:Subscriber 发送 SUBSCRIBE 报文到 Broker,指定订阅的主题。
[*]订阅确认:Broker 收到 SUBSCRIBE 报文后,在订阅列表中将 Subscriber 加入,并返回 SUBACK 报文给 Subscriber。
[*]消息发布:Publisher 发送 PUBLISH 报文到 Broker,包含消息的主题和内容。
[*]消息分发:Broker 收到 PUBLISH 报文后,根据主题将消息分发给订阅了该主题的所有 Subscriber。
[*]消息传递:Subscriber 收到经过分发的消息后,进行相应的处理。
[*]客户端断开:客户端发送 DISCONNECT 报文到 Broker,表明断开连接。
其中,MQTT定义了三种消息质量等级,用于确保消息的可靠传递:
第一种消息格式为:最多一次(At Most Once):消息发布后,不进行任何确认和重传机制,消息可能会丢失或重复;
第二种消息格式为:至少一次(At Least Once):消息发布后,接收者必须返回一个确认消息(PUBACK)给发布者,如果发布者没有收到确认消息,则会重传消息,确保至少一次的消息传递;
第三种消息格式为:只有一次(Exactly Once):消息发布和传递过程中进行了多次握手和确认,确保消息只被传递一次。
最后我们来讨论一下MQTT协议通信的数据报文格式:
固定报头(Fixed header),第一个字节高4位是MQTT控制报文的类型 + 第一个字节低4位用于指定控制报文类型的标志位(只在PUBLISH发布消息时用到) + 剩余长度1~4个字节(剩余长度字段最大4个字节)可变报头(Variable header),可变报头的内容根据报文类型的不同而不同;有效载体(Payload),某些 MQTT 控制报文在报文的最后部分包含一个有效载荷;
实现步骤
OneNet平台建设
①搜索OneNet,进入网站,登录并进入开发者中心;
https://cdn.nlark.com/yuque/0/2025/png/53372109/1742868739608-07af1341-0919-499c-b326-4b6aef03836c.png②创建产品,点击“产品开发”,创建你的产品,并填写产品信息;
https://cdn.nlark.com/yuque/0/2025/png/53372109/1742869208858-7a381375-5a2b-4604-8f9f-6244062913d6.png说明:所属地区随意,不会影响使用,节点类型根须自身需求选择,接入协议选择MQTT;连接方式可以选择蜂窝或者WiFi,相对简单;开发方案选择自定义方案;③创建设备,选择谁被接入管理,点击设备管理,为产品添加设备,填写设备信息;
https://cdn.nlark.com/yuque/0/2025/png/53372109/1748423588023-8801f69b-bd91-4df5-9005-b92d2b7742b1.png④收集三元组,分别为产品ID、access_key以及设备名称,这三个重要数据要写入代码中,需准确无误;https://cdn.nlark.com/yuque/0/2025/png/53372109/1748423203329-1ef57e43-ece0-491e-a733-cc0fcd151094.png⑤添加产品属性,添加数据流,注意:数据流名称必须与上传的名称相同;也可以添加任何数据流,上传数据时,平台会自动创建同名数据流;https://cdn.nlark.com/yuque/0/2025/png/53372109/1742870981075-55038248-7699-448e-9a9a-709ad37eaec6.pnghttps://cdn.nlark.com/yuque/0/2025/png/53372109/1742871034242-33c0d2f7-f678-4ae1-a8ab-a012a19aa835.png至此,代理(Breaker)建设完毕,等待发布者或订阅者传输信息;
OneNet平台连接前准备
平台建设步骤中,准备收集好的三元组,在连接平台之前需要登陆密钥,这个密钥需要通过token算法得到,不过不用担心,官方已经准备好了计算工具下载连接;
工具中需要输入以下内容:res : products/产品ID/devices/设备名称et : 时间戳,可直接网站搜索获取,注意:此时填写的必须比当前时间晚,即填写“未来”的某个时间key:三元组中获取的access_key;③进入OneNET文档中心,查找服务器接入地址与端口,这个地址与端口会在连接时用上;https://cdn.nlark.com/yuque/0/2025/png/53372109/1748393891624-32fdc6da-5165-4f4d-bc29-e89011bcfbe6.png
一切准备好后,开始着手准备连接OneNET平台;
OneNet平台连接调试
MQTT.fx是一款基于Eclipse Paho,使用Java语言编写的MQTT协议客户端工具。支持通过Topic订阅和发布消息,用来前期和物理云平台调试非常方便;①下载MQTT.fx软件,推荐使用1.7.1版本,免费切资源丰富;下载好之后打开,进入设置界面;
②进入设置界面,填入Broker Address,Broken Point,修改通信版本
③修改用户信息,第二、三步非常重要,请多次核实确保填入信息无误;④设置好之后保存,点击“Connect”进行连接,状态灯显示绿色则连接正确;
此时,进入OneNET工作台,想要连接的设备已经处于在线状态;
⑤调试订阅消息功能,指令格式:$sys/产品ID/设备名称/dp/post/json/+
⑥调试发布消息功能,指令格式:$sys/产品ID/设备名称/dp/post/json ;并且发布消息内容根据一下格式进行修改;
成功收到消息后,能看到此时来自平台的消息;
根据以上格式,改变数据内容,多发送几次;⑦进入平台操作界面,进入设备详情;点击数据流,即可看到刚才上传的数据名称以及其数据,别忘了打开实时刷新;
点击数据,还能根据数据变化绘制曲线图;以上则是MQTT.fx与OneNET平台连接的全过程;
MCU与OneNet平台连接
硬件分析首先来说说项目使用的硬件,主控选型上采用极海半导体推出的工业级基础拓展型MCU:APM32e030R8T6,这款MCU集成搭载 Arm® Cortex®-M0 + 内核,工作主频 72MHz;而本人则是有幸能拿到极海家最新出品的MicroE030开发板;
其次Wifi模块是不可或缺的部分;通过WIFI连接互联网,以实现基于OneNet平台的物联网功能;本次项目采用ESP8266作为WIFI模块;
ESP8266模块拥有一套完整的AT指令集,不需要你懂Wifi的知识,只需要利用串口进行相关的数据收发即可;常用的基础AT指令:
指令说明返回结果
AT测试AT是否OKOK
AT+RST复位指令OK
AT+CWMODE = 1设置模块WIFI模式,设置为Station模式OK
AT+CWDHCP=1设置DHCP模式,设置为开启CWDHCPOK
AT+CWJAP=\"账号,\"密码\"设置模块的AP信息,连接WIFIGOT IP
AT+CIPSTART="ip","网关","子网掩码"设置 Station 的 IP 地址OK
AT+CIPSEND=xxx通过WIFI向IP发送数据SEND OK
此模块引出了8个引脚,其解释和连线如下:
引脚名称描述
VCC供给电压5V
RSTPA4
ENPA5
TXD(RX)PA3
RXD(TX)PA2
IO0悬空
IO2悬空
GND地线
按照连线,硬件准备完毕
软件分析
模块硬件初始化:配置PA4复位引脚和PA5使能引脚,并且初始化USART模块;
<span style="color: rgb(38, 38, 38); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Segoe UI"; background-color: rgb(248, 248, 248); font-size: 14px; font-variant-ligatures: none; text-wrap-mode: nowrap;">void ESP8266_GPIO_Init(void)</span>模块初始化:
1.硬件模块复位,需将RST引脚拉低200ms以上,再拉高并保持高电平;2.发送指令”AT“,保证模块通信无误;3.发送指令”AT+CWMODE“,配置WIFI为Station模式;//wifi模式4.发送指令”AT+CWDHCP ”,配置WIFI开启DHCP;5.发送指令“AT+CWJAP ”,配置WIFI模块连接服务器的账号和密码;#define ESP8266_WIFI_INFO "AT+CWJAP=\"Maxxx Pro\",\"12345678\"\r\n" //WIFI名称与密码
其中,Wifi发送函数与接收含函数如下:
<blockquote>_Bool ESP8266_SendCmd(char *cmd, char *res,short timeout)//发送函数在Wifi连接成功之后,就需要连接OneNet平台,回应Success,则表示连接成功,此时OneNet平台设备状态应该为绿色在线;
<blockquote>#define PROID<span style="white-space:pre"> </span>"rPt76ojBtN"<span style="white-space:pre"> </span><span style="white-space:pre"> </span>//产品ID数据发送前,需要将数据打包为OneNet平台可识别格式;
unsigned char OneNet_FillBuf1(char *buf)
{
char text= " " ;
memset(text, 0, sizeof(text));
strcpy(buf, "{\"id\":123,\"dp\":{");
memset(text, 0, sizeof(text));
sprintf(text, "\"Temperature\":[{\"v\":%1f}],", Temperature);
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"Heart_Rate\":[{\"v\":%d}],", hrAvg); //心率
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"Blood_Oxygen\":[{\"v\":%d}],", spo2Avg); //心率
strcat(buf, text);
//
memset(text, 0, sizeof(text));
sprintf(text, "\"Longitude\":[{\"v\":%5f}],", longitude_sum); //经度
strcat(buf, text);
memset(text, 0, sizeof(text));
sprintf(text, "\"Latitude\":[{\"v\":%5f}]",latitude_sum);//纬度
strcat(buf, text);
strcat(buf, "}}");
return strlen(buf);
}然后,数据需要符合MQTT报文结构,即可利用Wifi模块发送;
//==========================================================
// 函数名称: MQTT_PacketSubscribe
//
// 函数功能: Subscribe消息组包
//
// 入口参数: pkt_id:pkt_id
// qos:消息重发次数
// topics:订阅的消息
// topics_cnt:订阅的消息个数
// mqttPacket:包指针
//
// 返回参数: 0-成功 其他-失败
//
// 说明:
//==========================================================
uint8 MQTT_PacketSubscribe(uint16 pkt_id, enum MqttQosLevel qos, const int8 *topics[], uint8 topics_cnt, MQTT_PACKET_STRUCTURE *mqttPacket)
{
uint32 topic_len = 0, remain_len = 0;
int16 len = 0;
uint8 i = 0;
if(pkt_id == 0)
return 1;
//计算topic长度-------------------------------------------------------------------------
for(; i < topics_cnt; i++)
{
if(topics == NULL)
return 2;
topic_len += strlen(topics);
}
//2 bytes packet id + topic filter(2 bytes topic + topic length + 1 byte reserve)------
remain_len = 2 + 3 * topics_cnt + topic_len;
//分配内存------------------------------------------------------------------------------
MQTT_NewBuffer(mqttPacket, remain_len + 5);
if(mqttPacket->_data == NULL)
return 3;
/*************************************固定头部***********************************************/
//固定头部----------------------头部消息-------------------------------------------------
mqttPacket->_data = MQTT_PKT_SUBSCRIBE << 4 | 0x02;
//固定头部----------------------剩余长度值-----------------------------------------------
len = MQTT_DumpLength(remain_len, mqttPacket->_data + mqttPacket->_len);
if(len < 0)
{
MQTT_DeleteBuffer(mqttPacket);
return 4;
}
else
mqttPacket->_len += len;
/*************************************payload***********************************************/
//payload----------------------pkt_id---------------------------------------------------
mqttPacket->_data = MOSQ_MSB(pkt_id);
mqttPacket->_data = MOSQ_LSB(pkt_id);
//payload----------------------topic_name-----------------------------------------------
for(i = 0; i < topics_cnt; i++)
{
topic_len = strlen(topics);
mqttPacket->_data = MOSQ_MSB(topic_len);
mqttPacket->_data = MOSQ_LSB(topic_len);
strncat((int8 *)mqttPacket->_data + mqttPacket->_len, topics, topic_len);
mqttPacket->_len += topic_len;
mqttPacket->_data = qos & 0xFF;
}
return 0;
}最后即可通过函数实现MQTT订阅和发布
//==========================================================
// 函数名称: OneNET_Publish
//
// 函数功能: 发布消息
//
// 入口参数: topic:发布的主题
// msg:消息内容
//
// 返回参数: 无
//
// 说明:
//==========================================================
void OneNET_Publish(const char *topic, const char *msg)
{
MQTT_PACKET_STRUCTURE mqtt_packet = {NULL, 0, 0, 0}; //协议包
// UsartPrintf(USART_DEBUG, "Publish Topic: %s, Msg: %s\r\n", topic, msg);
if(MQTT_PacketPublish(MQTT_PUBLISH_ID, topic, msg, strlen(msg), MQTT_QOS_LEVEL0, 0, 1, &mqtt_packet) == 0)
{
ESP8266_SendData(mqtt_packet._data, mqtt_packet._len); //向平台发送订阅请求
MQTT_DeleteBuffer(&mqtt_packet); //删包
}
}
//==========================================================
// 函数名称: OneNET_Subscribe
//
// 函数功能: 订阅
//
// 入口参数: 无
//
// 返回参数: 无
//
// 说明:
//==========================================================
void OneNET_Subscribe(void)
{
MQTT_PACKET_STRUCTURE mqtt_packet = {NULL, 0, 0, 0}; //协议包
char topic_buf;
const char *topic = topic_buf;
snprintf(topic_buf, sizeof(topic_buf), "$sys/%s/%s/cmd/#", PROID, DEVICE_NAME);
// UsartPrintf(USART_DEBUG, "Subscribe Topic: %s\r\n", topic_buf);
if(MQTT_PacketSubscribe(MQTT_SUBSCRIBE_ID, MQTT_QOS_LEVEL0, &topic, 1, &mqtt_packet) == 0)
{
ESP8266_SendData(mqtt_packet._data, mqtt_packet._len); //向平台发送订阅请求
MQTT_DeleteBuffer(&mqtt_packet); //删包
}
}
至此,MCU即可实现利用传感器获取数据,通过WIFI模块上传OneNet平台,根据获取数据进行其他操作;
总结
本篇文章讨论了如何使用OneNet作为物联网平台,并给出详细搭建和调试步骤,并使用APME030R8T6作为主控MCU实现IoT数据交互功能;
资料文章涉及内容较为浅显,若读者对相关知识有兴趣,可跳转至下方资料深入学习MQTT学习资料:
MQTT协议https://blog.csdn.net/weixin_44788542/article/details/129690265?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522f90e144d7df6261ab98db9b525c062d7%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=f90e144d7df6261ab98db9b525c062d7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-129690265-null-null.142^v102^pc_search_result_base6&utm_term=MQTT&spm=1018.2226.3001.4187OneNet物联网文档中心
https://open.iot.10086.cn/doc/aiot/fuse/search?kw=token&path=new_platform
密钥计算助手token
https://open.iot.10086.cn/college/video/onenet-portal/2024-04-19/17134946071850.exe
不得不说干货满满,从 MQTT 讲到 OneNET 平台,再到用APM32E030的 上手实操,一条龙全给整明白了
高亮加精华 安排
学习了。
这是把MQTT的协议跑在了E030上面了吧!
如果把其安排在ESP8266 可以吗?
页:
[1]