> 技术文档 > W5500io-M模组MQTT协议连接OneNet平台 (微信小程序控制方案) _w5500 mqtt

W5500io-M模组MQTT协议连接OneNet平台 (微信小程序控制方案) _w5500 mqtt

目录

1 前言

2 项目环境

2.1 硬件环境

2.2 软件环境

3.硬件连接和方案

3.1 方案图示

3.2 W5500硬件连接

4 注册OneNet的账号以及建立物模型

4.1 创建产品

4.2 创建物模型

4.3 获取基本信息

4.4 token密钥生成

4.5 物模型Topic

5 修改代码

6 数据上报

7 命令下发

8 上位机

8.1 获取属性最新数据

8.2 下发指令设置

8.3 小程序控制演示


1 前言

        MQTT是一种轻量级通信协议,基于TCP/IP,采用发布-订阅模式,广泛应用于物联网领域。

        MQTT的工作原理围绕着三个核心部分:发布者(Publishers)、代理(Broker,也称服务器)和订阅者(Subscribers)。发布者负责发送消息到特定的主题(Topic),代理则接收这些消息并将其转发给所有订阅了该主题的订阅者。这种模式允许设备间异步通信,且设备不需要直接了解彼此的存在,从而降低了系统的复杂性。

W5500io-M 是炜世推出的高性能SPI转以太网模块,具有以下特点:

  • 极简设计:集成MAC、PHY、32KB缓存及RJ45网口,通过4线SPI接口直连主控,3.3V供电,紧凑尺寸适配嵌入式场景 。
  • 简单易用:用户无需再移植复杂的TCP/IP协议栈到MCU中,可直接基于应用层数据做开发。
  • 资料丰富:提供丰富的MCU应用例程和硬件参考设计,可直接参考使用,大大缩短研发时间,硬件兼容W5100sIO-M模组,方便方案开发与迭代。
  • 应用广泛:在工业控制、智能电网、充电桩、安防消防、新能源、储能等地方都有广泛应用。

产品链接:商品详情

2 项目环境

2.1 硬件环境

  1. W5500io-M
  2. STM32F103VCT6 EVB
  3. 网络连接线
  4. 杜邦线若干
  5. 交换机或路由器

2.2 软件环境

  1. OneNET物联网开放平台。
  2. 微信开发者平台
  3. 飞思创串口助手
  4. 例程链接w5500.com/w5500.html

3.硬件连接和方案

3.1 方案图示

3.2 W5500硬件连接

 //W5500_SCS--->STM32_GPIOD7/*W5500的片选引脚*/ //W5500_SCLK--->STM32_GPIOB13/*W5500的时钟引脚*/ //W5500_MISO--->STM32_GPIOB14/*W5500的MISO引脚*/  //W5500_MOSI--->STM32_GPIOB15/*W5500的MOSI引脚*/  //W5500_RESET--->STM32_GPIOD8/*W5500的RESET引脚*/  //W5500_INT--->STM32_GPIOD9/*W5500的INT引脚*/

4 注册OneNet的账号以及建立物模型

        注册账号在这不进行赘述下面我们看如何建立模型

4.1 创建产品

4.2 创建物模型

        物模型的建立根据自己的需要建立

4.3 获取基本信息

 注册账号以及建立物模型在此不在赘述,下面查看项目和设备的基本信息参数

获得产品ID设备名称以及密钥

        1.产品ID:iP20B5FpF6

        2.设备名称:d2

        3.设备密钥:TFU3bT***********************=

4.4 token密钥生成

        在设备与 OneNet 平台进行通信时,token 作为设备或应用程序的身份凭证。只有拥有有效 token 的设备或应用,才能被平台识别和认证,从而建立起安全的连接,确保只有授权的设备和应用可以访问平台资源。token密钥生成需要token工具,可以通过链接跳转下载OneNET - 中国移动物联网开放平台

        1.res字段:products/{产品id}/devices/{设备名},key为设备级key。将{产品id}替换成自己产品的id,{设备名}替换成自己的设备名。

        2.et字段:填写访问过期的时间。可以在此网站获取时间戳(Unix timestamp)转换工具 - 在线工具。

        3.key字段:填写自己的设备的密钥。

        4.填写完成后点击generate即可得到token密钥

4.5 物模型Topic

        1.设置直连设备属性: $sys/iP20B5FpF6/d2/thing/property/set

        2.直连设备属性设置响应: $sys/iP20B5FpF6/d2/thing/property/set_reply

        3.直连设备上报属性 : $sys/iP20B5FpF6/d2/thing/property/post

        4.直连设备上报属性响应 :$sys/iP20B5FpF6/d2/thing/property/post/reply

5 修改代码

        找到do-mqtt.c文件,把上述中的产数更换为自己OneNet的参数,这些参数我们在上面都有讲到,可以自行替换。

// 定义MQTT连接参数结构体并初始化mqttconn mqtt_params = { .mqttHostUrl = \"mqtts.heclouds.com\", // MQTT服务器的URL地址 .server_ip = {0,}, // 服务器IP地址(此处未使用,保留默认值) .port = 1883, // 连接端口号,1883为MQTT默认非加密端口 .clientid = \"d2\", // MQTT客户端ID,需保持唯一性 .username = \"iP20B5FpF6\",  // MQTT用户名,通常为产品ID .passwd = \"vers=md5&sign=YT2N73HSjmyy%2BbQEFMDjMw%3D%3D\", // 用户密码,包含签名认证信息 .pubtopic = \"$sys/iP20B5FpF6/d2/thing/property/post\", // 发布属性数据的主题 .pubtopic_reply = \"$sys/iP20B5FpF6/d2/thing/property/post/reply\", // 属性数据发布响应主题 .subtopic = \"$sys/iP20B5FpF6/d2/thing/property/set\", // 订阅属性设置的主题 .subtopic_reply = \"$sys/iP20B5FpF6/d2/thing/property/set_reply\", // 属性设置响应主题 .pubQoS = QOS0, // 发布消息的服务质量等级(0:最多一次) .willtopic = \"/wizchip/will\", // 遗嘱消息主题,客户端异常断开时发布 .willQoS = QOS0, // 遗嘱消息的服务质量等级 .willmsg = \"wizchip offline!\", // 遗嘱消息内容 .subQoS = QOS0, // 订阅消息的服务质量等级};

        下方代码6上报到服务器物模型的数据以及标识符,标识符要与服务器物模型相同,数值为本地传感器采集到的数据,由单片机进行处理,然后把数值填写到value的后面,然后就可以把本地数据上传到服务器

case PUB_MESSAGE:{ // 准备发布的MQTT消息 pubmessage.qos = QOS0; // 设置服务质量等级为QoS0(最多一次) // 构建JSON格式的负载数据,包含温度值26 pubmessage.payload = \"{\\\"id\\\":\\\"123\\\",\\\"version\\\":\\\"1.0\\\",\\\"params\\\":{\\\"temp\\\":{\\\"value\\\":26}}}\"; pubmessage.payloadlen = strlen(pubmessage.payload); // 计算负载长度 // 发布消息到指定主题 ret = MQTTPublish(&c, (char *)&(mqtt_params.pubtopic), &pubmessage); // 检查发布结果 if (ret != SUCCESSS) { run_status = ERR; // 发布失败,设置错误状态 } else { // 发布成功,打印主题和消息内容 printf(\"publish:%s,%s\\r\\n\\r\\n\", mqtt_params.pubtopic, (char *)pubmessage.payload); run_status = KEEPALIVE; // 设置为保持连接状态 } break;}

6 数据上报

        此时把代码下载进入单片机。串口显示如下,此时显示MQTT连接成功,数据上报成功,然后我们查看OneNet服务器端

        服务器端显示本地上传的数据,此时本地数据就可正常上报到服务器了

7 命令下发

        如果想在远端控制本地的设备需要怎么办,我们可以在单片机中加入解析json数据的代码,然后在服务器下发指令,达到相应的效果。此段代码为解析服务器解析下发的指令,可以根据服务器下发指令是开灯还是关灯来操作本地的LED,如果想在服务器操作其他本地器件,则可根据上述代码进行添加。

void json_decode(char *msg){ int ret; char replymsg[128] = {0}; // 存储响应消息的缓冲区 cJSON *id = NULL; // 消息ID节点 cJSON *jsondata = NULL; // 根JSON对象 cJSON *params = NULL; // 参数节点 cJSON *LED = NULL; // LED控制节点 // 解析JSON消息 jsondata = cJSON_Parse(msg); if (jsondata == NULL) { printf(\"json parse fail.\\r\\n\"); // 解析失败处理 return; } // 提取关键数据节点 id = cJSON_GetObjectItem(jsondata, \"id\"); // 提取消息ID params = cJSON_GetObjectItem(jsondata, \"params\"); // 提取参数部分 // 处理LED控制命令 LED = cJSON_GetObjectItem(params, \"led\"); if (LED->valueint) // 判断LED控制值(1表示关闭) { printf(\"LED OFF\\r\\n\"); // TODO: 实际硬件控制代码 - 关闭LED } else // 0表示开启 { printf(\"LED ON\\r\\n\"); // TODO: 实际硬件控制代码 - 开启LED } // 构建响应消息 pubmessage.qos = QOS0;// 设置QoS等级为0 sprintf(replymsg, \"{\\\"id\\\":\\\"%s\\\",\\\"code\\\":200,\\\"msg\\\":\\\"success\\\"}\", id->valuestring); // 构建成功响应 printf(\"reply:%s\\r\\n\", replymsg);  // 打印响应内容 // 发布响应消息 pubmessage.payload = replymsg; pubmessage.payloadlen = strlen(replymsg); ret = MQTTPublish(&c, mqtt_params.subtopic_reply, &pubmessage); // 发布响应到指定主题 // 处理发布结果 if (ret != SUCCESSS) { run_status = ERR; // 发布失败设置错误状态 } else { printf(\"publish:%s,%s\\r\\n\\r\\n\", mqtt_params.subtopic_reply, (char *)pubmessage.payload); // 打印发布信息 } // 释放JSON解析资源 cJSON_Delete(jsondata);}

        由此可以看到,在服务器下发指令可以被正确解析并执行,此时说明数据下发与是正确的。

8 上位机

        使用服务器进行查看和下发指令可能不太方便,我们可以使用微信小程序作为上位机更加直观的观看和控制,如图所示

        小程序进行获取信息和下发指令是通过微信小程序的 wx.request 方法向 OneNet 提供的 HTTP API 发送请求,获取目标设备的最新属性数据(模拟值),再通过解析收到的数据将他们渲染到页面中。我的小程序源码链接提取码:2oqz ,导入微信开发者平台根据代码面的标注提示进行更改自己可以根据需求进行更改。

8.1 获取属性最新数据

        接口功能:根据产品id和设备名,查询设备最新属性功能点数据

        接口地址:https://iot-api.heclouds.com/thingmodel/query-device-property

        API说明:

        请求方式:GET

        http query 请求参数:

参数

类型

是否必选

描述

product_id

string

产品 ID,平台生成唯一 ID

device_name

string

设备名称

        返回数据:

参数名称

类型

描述

code

int

调用成功或失败时,返回的 code 码

msg

string

调用成功或失败时,返回的 msg 信息

request_id

string

调用 API 生成的请求标识

data

-

调用成功时,返回的业务数据

data.list

array

设备属性数据集合

        微微信小程序向OneNET云平台发送”设备属性最新数据查询“请求。

        OneNET云平台返回查询结果给微信小程序。

        可以看到图中读取到led和温度的数值

8.2 下发指令设置

        接口功能:根据产品ID和设备名,设置该设备的属性期望值,当设备在线后将下发该期望值到设备。

        接口地址:https://iot-api.heclouds.com/thingmodel/set-device-desired-property

        API说明:

        请求方式:POST

        http body 请求参数:

参数

类型

是否必选

描述

product_id

string

产品 ID,平台生成唯一 ID

device_name

string

设备名称

params

object

设置的属性期望值,数据格式为 json 对象,形式为 key-value,key 为属性功能点标识,value 为属性值,取值符合物模型定义的数据类型和取值范围,例如 {\"switch\": true}

返回数据:

参数名称

类型

描述

code

int

调用成功或失败时,返回的 code 码

msg

string

调用成功或失败时,返回的 msg 信息

request_id

string

调用 API 生成的请求标识

data

-

调用成功时,返回的业务数据

        图中可以看到指令设置成功

8.3 小程序控制演示

        当点击开灯时,通过下发指令的过程,单片机会执行开灯的操作,并在串口打印出来。

        当点击关灯时,通过下发指令,单片机会执行关灯的操作,并在串口打印出来。

        我们再看一下信息获取展示。我进行手动修改温度来表示温度变化,6value进行修改

case PUB_MESSAGE:{ // 准备发布的MQTT消息 pubmessage.qos = QOS0; // 设置服务质量等级为QoS0(最多一次) // 构建JSON格式的负载数据,包含温度值26 pubmessage.payload = \"{\\\"id\\\":\\\"123\\\",\\\"version\\\":\\\"1.0\\\",\\\"params\\\":{\\\"temp\\\":{\\\"value\\\":30}}}\"; pubmessage.payloadlen = strlen(pubmessage.payload); // 计算负载长度 // 发布消息到指定主题 ret = MQTTPublish(&c, (char *)&(mqtt_params.pubtopic), &pubmessage); // 检查发布结果 if (ret != SUCCESSS) { run_status = ERR; // 发布失败,设置错误状态 } else { // 发布成功,打印主题和消息内容 printf(\"publish:%s,%s\\r\\n\\r\\n\", mqtt_params.pubtopic, (char *)pubmessage.payload); run_status = KEEPALIVE; // 设置为保持连接状态 } break;}

        此时我们查看小程序上面的温度也发生了变化,功能完好

        感谢您的观看,如您对本文有不清楚的地方或想了解更多产品信息的,欢迎私信或在评论区留言,我们会及时回复您!