W55RP20 C语言开发实战:MQTT协议与OneNET物联网平台对接
本文为 WIZnet W55RP20 芯片 c语言 教程第 13篇,基于官方最新固件编写,代码均经过实际验证,可直接烧录运行。版权声明:本文为 WIZnet 官方原创技术文章,转载请注明出处。上一篇实战教程,我们完成了W55RP20芯片MQTT协议基础通信验证,实现了与阿里云服务器的消息收发。
本文为 WIZnet W55RP20 芯片 c语言 教程第 13篇,基于官方最新固件编写,代码均经过实际验证,可直接烧录运行。
版权声明:本文为 WIZnet 官方原创技术文章,转载请注明出处。
上一篇实战教程,我们完成了W55RP20芯片MQTT协议基础通信验证,实现了与阿里云服务器的消息收发。本篇内容我们聚焦工业级物联网场景,实现W55RP20通过MQTT协议与OneNET物联网平台对接,完成温湿度数据定时上传,掌握OneNET平台设备注册、MQTT连接配置、物模型数据格式封装等核心技能,适配工业级设备上云需求。
W55RP20集成硬件 TCP/IP 协议栈,搭配MQTT客户端库,通过C语言编程即可实现与OneNET平台的稳定通信,无需关心底层Socket细节,依托WIZnet官方驱动库和OneNET物模型规范,大幅降低嵌入式设备上云开发门槛,适用于智能监测、数据采集等各类物联网场景。
学完本文,你将掌握:
-
OneNET物联网平台设备注册、产品创建及MQTT连接参数获取
-
W55RP20连接OneNET平台的C语言实现(完整可运行代码)
-
OneNET物模型JSON payload构造(标准格式自动封装)
-
DNS解析优化、定时数据上传、心跳保活等稳定机制实现
-
OneNET平台数据查看、调试及常见问题排查方法
本节课核心目标:
-
完成OneNET平台产品创建、设备注册,获取MQTT连接参数
-
理解OneNET MQTT连接规范、物模型数据格式要求及鉴权原理
-
编译、下载完整C语言代码,实现W55RP20与OneNET平台连接
-
完成温湿度数据定时上传,在OneNET平台查看实时数据
-
掌握W55RP20与OneNET对接的常见故障快速排查方法
系列教程学习路径
本专栏共 16 篇,循序渐进覆盖 W55RP20-EVB-Pico 模块 C语言开发全流程:
-
第 1 篇:静态 IP 配置与网络基础
-
第 2 篇:DHCP 自动联网与网络诊断
-
第 3 篇:TCP Client 客户端通信
-
第 4 篇:TCP Server 服务端通信
-
第 5 篇:UDP 单播数据通信
-
第 6 篇:UDP 组播/广播数据通信
-
第 7 篇:DNS 域名解析
-
第 8 篇:NTP 从网络获取时间
-
第 9 篇:HTTP Client 客户端请求
-
第 10 篇:HTTP Server 服务端搭建
-
第 11 篇:HTTP 协议与 OneNET 平台数据上云
-
第 12 篇:MQTT 协议基础通信验证
-
第 13 篇:MQTT 协议与阿里云平台对接
-
第 14 篇:MQTT 协议与 OneNET 平台对接(本文)
-
第 15 篇:MQTT 协议与 ThingSpeak 平台对接
-
第 16 篇:Modbus 工业协议通信
建议收藏本专栏,跟随教程逐步学习,所有代码均会同步更新至官方 Gitee 仓库
目录
一、准备工作
1.1 软件准备
所需软件均为免费版本,按要求下载安装即可,无需额外付费,适配C语言开发需求,新增OneNET平台相关操作工具。
|
软件名称 |
版本要求 |
下载地址 |
说明 |
|
VS Code(搭配C/C++插件) |
最新稳定版 |
轻量级代码编辑器,支持C语言语法高亮、编译调试,新手友好 |
|
|
W55RP20-EVB-Pico 模块 C语言驱动库 |
最新稳定版 |
WIZnet 官方固件/驱动库下载 |
专为 W55RP20-EVB-Pico 模块编写,已集成 WIZnet 硬件驱动、TCP/IP协议栈及MQTT客户端库 |
|
串口调试助手(如SecureCRT) |
任意版本 |
官方下载或第三方工具 |
用于查看串口输出的运行日志、调试信息,定位连接和数据上传问题 |
|
OneNET物联网平台 |
在线版 |
创建产品、注册设备,获取MQTT连接参数,查看上传的温湿度数据 |
1.2 硬件准备

-
W55RP20-EVB-Pico × 1
-
Micro USB 数据线(必须支持数据传输,不能使用纯充电线)× 1
-
标准网线 × 1
-
开启 DHCP 功能的路由器 / 交换机 × 1(用于获取网络参数,实现 DNS 解析)
1.3 OneNET平台准备
在进行代码开发前,需先在OneNET平台完成产品创建和设备注册,获取MQTT连接所需的核心参数(产品ID、设备名称、Token),步骤如下:
-
登录OneNET物联网平台(需注册账号,个人版免费),进入「物联网核心套件」→「产 品」,点击「创建产品」;

-
产品配置:产品名称自定义(如W55RP20温湿度采集),协议选择「MQTT」,数据格式选择「JSON」,设备类型选择「直连设备」,点击「确认创建」;

-
添加设备:进入创建好的产品,点击「设备管理」→「添加设备」,设备名称自定义(如W5500_01),点击「确认」,完成设备注册;

-
获取连接参数:进入设备详情页,记录以下3个核心参数(后续替换到代码中):
-
产品ID(ONENET_PRODUCT_ID):产品详情页顶部获取,为字符串格式

-
设备名称(ONENET_DEVICE_NAME):创建设备时自定义的名称

-
Token(ONENET_MQTT_PASSWORD):使用密码生成工具:https://open.iot.10086.cn/doc/iot_platform/images/tools/token.exe
注注意Token有有效期,过期需重新生成 -
添加物模型(必做):进入产品「物模型定义」,添加「temp」(温度,浮点型)和「humi」(湿度,浮点型)两个属性,字段名需与代码中一致,用于在平台直观查看温湿度数据。

二、W55RP20 C语言开发环境搭建
2.1 驱动库配置
1. 下载W55RP20官方C语言驱动库,解压后得到核心文件(包含wizchip_conf.h、socket.h、mqtt_interface.h、MQTTClient.h等);
2. 打开VS Code,新建项目,将驱动库中的头文件(.h)放入项目include文件夹,源文件(.c)放入src文件夹;
3. 配置项目编译选项,指定编译器(如ARM GCC),关联驱动库文件,确保编译时能正常调用硬件驱动、网络接口和MQTT相关函数。
2.2 固件烧录
W55RP20-EVB-Pico 模块完全兼容树莓派 Pico 的 UF2 固件烧录方式,操作简单无需额外烧录器,新手可快速上手:
-
按住 RP2040 开发板上的 BOOTSEL 按键不放;
-
使用 Micro USB 数据线连接开发板与电脑;
-
待电脑识别出名为 RPI-RP2 的 U 盘后,松开 BOOTSEL 按键;
-
将编译生成的 UF2 固件文件拖拽到 U 盘中;
-
开发板会自动重启,固件烧录完成。
三、硬件连接与串口配置
3.1 硬件连接

W55RP20-EVB-Pico 模块连接分为两步,分别实现供电/调试和以太网连接,操作简单,无需复杂接线,与基础MQTT实战连接方式一致:
3.1.1 基础连接(供电+调试)
使用 Micro USB 数据线连接 RP2040 开发板与电脑,用于开发板供电、固件烧录和串口调试。
3.1.2 以太网连接
使用网线连接 W55RP20-EVB-Pico 模块的以太网接口与路由器的 LAN 口(或直接连接电脑网口,需手动配置电脑 IP 与开发板同网段)。
3.1.3 模块与开发板接线(分离式模块适用)
若使用分离式模块与开发板,需按以下引脚对应连接(SPI 通信):
【硬件预留】此处插入硬件连接示意图
3.2 串口调试配置
打开vscode串口调试助手,按以下参数配置,用于查看开发板运行日志和调试信息,定位OneNET MQTT连接和数据上传问题:
-
波特率:115200
-
数据位:8
-
停止位:1
-
校验位:无
-
流控:无
-
选择开发板对应的串口(通常显示为 COMx),点击打开串口。
四、OneNET MQTT协议规范解析
OneNET平台采用MQTT 3.1.1协议(与代码中配置一致),基于发布/订阅模式实现设备与平台的双向通信,与公共MQTT服务器相比,核心差异在于连接鉴权严格和物模型数据格式规范,这也是开发的重点和难点。
4.1 核心连接规范(必看)
-
MQTT版本:必须使用3.1.1版本(代码中配置为MQTTVersion = 4),与OneNET平台完全兼容;
-
服务器地址:固定为「studio-mqtt.heclouds.com」(OneNET MQTT官方域名),无需修改地域参数;
-
端口:使用1883(非加密端口,适合开发调试;生产环境可使用8883加密端口);
-
连接参数:ClientID=设备名称,Username=产品ID,Password=平台生成的Token,三者必须严格匹配,否则会连接失败。
4.2 物模型数据格式规范
OneNET平台要求设备上传的数据必须为指定JSON格式,核心包含id、version、params三个字段,示例如下:
{ "id":"123456789", "version":"1.0", "params":{ "temp":{ "value":35.7 }, "humi":{ "value":60.2 } } }
说明:
-
id:随机数或时间戳,用于标识一条消息,避免重复,代码中自动生成;
-
version:固定为「1.0」,表示物模型数据格式版本;
-
params:设备上传的具体数据,字段名(temp、humi)需与OneNET物模型中定义的属性名一致,value为具体数值;
-
无需手动添加time字段,代码中已优化为极简格式,确保平台正常解析。
4.3 标准主题格式(必配)
OneNET物模型通信需使用固定主题,无需自定义,替换产品ID和设备名称即可:
-
属性上报主题(设备→平台):$sys/产品ID/设备名称/thing/property/post
-
上报回复主题(平台→设备):$sys/产品ID/设备名称/thing/property/post/reply
代码中已封装好主题格式,只需替换产品ID和设备名称,无需手动拼接。
4.4 极简工作流程
-
W55RP20通过DNS解析OneNET MQTT服务器域名,获取服务器IP;
-
使用OneNET平台提供的产品ID、设备名称、Token,建立MQTT连接;
-
W55RP20按OneNET物模型规范封装温湿度数据(JSON格式),向上报主题发布数据;
-
OneNET平台接收数据,在设备详情页显示实时温湿度数据,同时向回复主题发送确认消息,设备接收并打印。
五、核心C语言代码复制与编译烧录
5.1 依赖库说明
核心依赖 WIZnet 官方驱动库(包含wizchip_conf.h、socket.h、mqtt_interface.h、MQTTClient.h等),用于实现W55RP20硬件初始化、网络连接、DNS解析及MQTT客户端的连接、发布、订阅等基础功能;无需额外添加OneNET专用库,代码中已集成连接配置、物模型JSON封装和消息回调逻辑,直接关联到项目中即可使用。
5.2 完整C语言代码(主程序)
将以下代码复制到VS Code项目的主文件(如main.c)中,重点替换OneNET平台获取的连接参数,编译生成UF2固件后烧录到开发板,代码注释清晰,关键配置部分已标注,可直接修改。
/**
Copyright (c) 2021 WIZnet Co.,Ltd
Modified for W55RP20 with OneNET MQTT (final fixed version)
SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <string.h>
#include "port_common.h"
#include "wizchip_conf.h"
#include "wizchip_spi.h"
#include "mqtt_interface.h"
#include "MQTTClient.h"
#include "timer.h"
#include "time.h"
#include "dns.h"
/* Buffer */
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
/* Socket */
#define SOCKET_MQTT 0
#define SOCKET_DNS 3
/* Port */
#define PORT_MQTT 1883
/* Timeout */
#define DEFAULT_TIMEOUT 1000
/* ========== OneNET 配置(请根据实际修改)========== */
#define ONENET_PRODUCT_ID "ZGB6zBD0nS" // 产品ID
#define ONENET_DEVICE_NAME "led" // 设备名称
// MQTT Password(Token),从OneNET设备详情页复制,注意时效性
#define ONENET_MQTT_PASSWORD "version=2018-10-31&res=products%2FZGB6zBD0nS%2Fdevices%2Fled&et=1780016971&method=md5&sign=AAMTeit90OTmwPpugN%2Fe%2Bg%3D%3D"
#define ONENET_MQTT_DOMAIN "studio-mqtt.heclouds.com" // OneNET MQTT服务器域名
/* 物模型主题 */
#define PROPERTY_POST_TOPIC "$sys/" ONENET_PRODUCT_ID "/" ONENET_DEVICE_NAME "/thing/property/post"
#define PROPERTY_POST_REPLY_TOPIC "$sys/" ONENET_PRODUCT_ID "/" ONENET_DEVICE_NAME "/thing/property/post/reply"
/* 温湿度数据(模拟值,可替换为真实传感器) */
#define TEMPERATURE_VALUE 45.6
#define HUMIDITY_VALUE 68.1
/* 发布周期(毫秒) */
#define MQTT_PUBLISH_PERIOD (1000 * 10)
#define MQTT_KEEP_ALIVE 60
/* ========== 网络配置(根据实际环境修改)========== */
static wiz_NetInfo g_net_info = {
.mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56},
.ip = {192, 168, 1, 128},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 1, 1},
.dns = {8, 8, 8, 8},
#if _WIZCHIP_ > W5500
.lla = {0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xdc, 0xff, 0xfe, 0x57, 0x57, 0x25},
.gua = {0},
.sn6 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
.gw6 = {0},
.dns6 = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88},
.ipmode = NETINFO_STATIC_ALL
#else
.dhcp = NETINFO_STATIC
#endif
};
/* DNS解析结果存储 */
static uint8_t g_mqtt_broker_ip[4] = {0};
/* MQTT相关变量 */
static uint8_t g_mqtt_send_buf[ETHERNET_BUF_MAX_SIZE] = {0};
static uint8_t g_mqtt_recv_buf[ETHERNET_BUF_MAX_SIZE] = {0};
static Network g_mqtt_network;
static MQTTClient g_mqtt_client;
static MQTTPacket_connectData g_mqtt_packet_connect_data = MQTTPacket_connectData_initializer;
static MQTTMessage g_mqtt_message;
static volatile uint32_t g_msec_cnt = 0;
/* DNS解析缓冲区 */
static uint8_t g_dns_buf[ETHERNET_BUF_MAX_SIZE] = {0};
/* 函数声明 */
static void repeating_timer_callback(void);
static time_t millis(void);
static void build_onenet_payload(char *payload, int max_len, float temperature, float humidity);
static int do_dns(const char *domain_name, uint8_t *ip_addr);
static void message_arrived(MessageData *msg_data);
/**
* @brief DNS域名解析函数
*/
static int do_dns(const char *domain_name, uint8_t *ip_addr)
{
int8_t ret = 0;
uint8_t dns_ip[4];
dns_ip[0] = g_net_info.dns[0];
dns_ip[1] = g_net_info.dns[1];
dns_ip[2] = g_net_info.dns[2];
dns_ip[3] = g_net_info.dns[3];
if (dns_ip[0] == 0 && dns_ip[1] == 0 && dns_ip[2] == 0 && dns_ip[3] == 0) {
dns_ip[0] = g_net_info.gw[0];
dns_ip[1] = g_net_info.gw[1];
dns_ip[2] = g_net_info.gw[2];
dns_ip[3] = g_net_info.gw[3];
printf("DNS: Using gateway as DNS server %d.%d.%d.%d\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
} else {
printf("DNS: Using DNS server %d.%d.%d.%d\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
}
printf("DNS: Resolving domain: %s\n", domain_name);
DNS_init(SOCKET_DNS, g_dns_buf);
ret = DNS_run(dns_ip, (uint8_t *)domain_name, ip_addr);
if (ret == 1) {
printf("DNS: Success! IP: %d.%d.%d.%d\n", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
return 0;
} else {
printf("DNS: Failed! Error: %d\n", ret);
return -1;
}
}
/**
* @brief 构造OneNET物模型JSON数据(无多余空格,无可选time字段)
*/
static void build_onenet_payload(char *payload, int max_len, float temp, float humi) {
snprintf(payload, max_len,
"{\"id\":\"%lu\",\"version\":\"1.0\",\"params\":{\"temp\":{\"value\":%.1f},\"humi\":{\"value\":%.1f}}}",
(unsigned long)millis(), temp, humi);
}
/* 定时器回调 */
static void repeating_timer_callback(void) {
g_msec_cnt++;
MilliTimer_Handler();
}
/* 获取毫秒数 */
static time_t millis(void) {
return g_msec_cnt;
}
/* 收到MQTT消息的回调(订阅回复主题) */
static void message_arrived(MessageData *msg_data) {
MQTTMessage *msg = msg_data->message;
printf("Reply received: topic=%.*s, payload=%.*s\n",
msg_data->topicName->lenstring.len, msg_data->topicName->lenstring.data,
(int)msg->payloadlen, (char*)msg->payload);
}
/**
* @brief 主函数
*/
int main() {
int32_t retval = 0;
uint32_t start_ms = 0;
uint32_t end_ms = 0;
char payload[256];
stdio_init_all();
sleep_ms(3000);
printf("\r\n=== W55RP20 OneNET MQTT Demo (Final Fixed Version) ===\r\n");
wizchip_spi_initialize();
wizchip_cris_initialize();
wizchip_reset();
wizchip_initialize();
wizchip_check();
wizchip_1ms_timer_initialize(repeating_timer_callback);
network_initialize(g_net_info);
print_network_information(g_net_info);
/* DNS解析 */
printf("\n--- DNS Resolution Phase ---\n");
int dns_retry = 0;
while (do_dns(ONENET_MQTT_DOMAIN, g_mqtt_broker_ip) != 0) {
dns_retry++;
if (dns_retry >= 3) {
printf("DNS resolution failed after 3 attempts!\n");
while (1);
}
printf("Retry %d in 3 seconds...\n", dns_retry);
sleep_ms(3000);
}
/* TCP连接 */
NewNetwork(&g_mqtt_network, SOCKET_MQTT);
printf("Connecting to OneNET MQTT broker at %d.%d.%d.%d:%d...\n",
g_mqtt_broker_ip[0], g_mqtt_broker_ip[1],
g_mqtt_broker_ip[2], g_mqtt_broker_ip[3], PORT_MQTT);
retval = ConnectNetwork(&g_mqtt_network, g_mqtt_broker_ip, PORT_MQTT);
if (retval != 1) {
printf("Network connect failed! retval=%d\n", retval);
while (1);
}
printf("Network connected.\n");
/* MQTT初始化 */
MQTTClientInit(&g_mqtt_client, &g_mqtt_network, DEFAULT_TIMEOUT,
g_mqtt_send_buf, ETHERNET_BUF_MAX_SIZE,
g_mqtt_recv_buf, ETHERNET_BUF_MAX_SIZE);
/* 关键:MQTT协议版本 4 = 3.1.1 */
g_mqtt_packet_connect_data.MQTTVersion = 4;
g_mqtt_packet_connect_data.cleansession = 1;
g_mqtt_packet_connect_data.willFlag = 0;
g_mqtt_packet_connect_data.keepAliveInterval = MQTT_KEEP_ALIVE;
g_mqtt_packet_connect_data.clientID.cstring = ONENET_DEVICE_NAME;
g_mqtt_packet_connect_data.username.cstring = ONENET_PRODUCT_ID;
g_mqtt_packet_connect_data.password.cstring = ONENET_MQTT_PASSWORD;
printf("MQTT Connecting to OneNET...\n");
retval = MQTTConnect(&g_mqtt_client, &g_mqtt_packet_connect_data);
if (retval < 0) {
printf("MQTT connect failed: %d\n", retval);
while (1);
}
printf("MQTT connected to OneNET Platform!\n");
/* 订阅回复主题(用于获取平台返回的错误信息) */
retval = MQTTSubscribe(&g_mqtt_client, PROPERTY_POST_REPLY_TOPIC, QOS0, message_arrived);
if (retval < 0) {
printf("Subscribe warning: %d\n", retval);
} else {
printf("Subscribed to reply topic: %s\n", PROPERTY_POST_REPLY_TOPIC);
}
sleep_ms(500);
/* 发布使用 QOS0 便于测试 */
g_mqtt_message.qos = QOS0;
g_mqtt_message.retained = 0;
g_mqtt_message.dup = 0;
start_ms = millis();
/* 主循环 */
while (1) {
end_ms = millis();
if (end_ms >= start_ms + MQTT_PUBLISH_PERIOD) {
build_onenet_payload(payload, sizeof(payload), TEMPERATURE_VALUE, HUMIDITY_VALUE);
g_mqtt_message.payload = payload;
g_mqtt_message.payloadlen = strlen(payload);
printf("Topic: %s\n", PROPERTY_POST_TOPIC);
printf("Payload: %s\n", payload);
retval = MQTTPublish(&g_mqtt_client, PROPERTY_POST_TOPIC, &g_mqtt_message);
if (retval < 0) {
printf("Publish failed: %d\n", retval);
} else {
printf("Data published (QOS0)\n");
}
start_ms = millis();
}
/* Yield 超时 1000 毫秒,确保网络报文及时处理 */
retval = MQTTYield(&g_mqtt_client, 1000);
if (retval < 0) {
printf("Yield error: %d\n", retval);
sleep_ms(1000);
}
}
return 0;
}
5.3 代码关键配置说明
-
OneNET MQTT参数(核心修改):
-
ONENET_PRODUCT_ID:替换为OneNET平台产品详情页获取的产品ID,为字符串格式,不可修改字符;
-
ONENET_DEVICE_NAME:替换为OneNET平台创建的设备名称,需与平台完全一致,大小写敏感;
-
ONENET_MQTT_PASSWORD:替换为OneNET设备生成工具复制的Token,注意Token有有效期,过期后需重新生成并替换;
-
ONENET_MQTT_DOMAIN:固定为「studio-mqtt.heclouds.com」,无需修改;
-
物模型主题:代码中自动拼接,无需手动修改,替换产品ID和设备名称后自动生效。
网络配置:根据路由器实际网段修改g_net_info中的ip、gw、dns,确保与路由器在同一网段;DNS推荐使用阿里云DNS(223.5.5.5),提高解析成功率;
MQTT版本:代码中已配置为3.1.1版本(MQTTVersion = 4),无需修改,与OneNET平台兼容;
数据上传周期:MQTT_PUBLISH_PERIOD定义为10秒,可根据需求修改(单位:毫秒);
温湿度数据:当前为固定值(TEMPERATURE_VALUE、HUMIDITY_VALUE),实际开发中可替换为传感器采集的实时数据(如DHT11、DS18B20)。
5.4 编译与烧录步骤
-
第一步:将上述代码复制到VS Code项目主文件,关联WIZnet官方驱动库(确保所有头文件能正常引用,无报错);
-
第二步:修改代码中的OneNET MQTT参数、网络配置,保存文件;
-
第三步:编译项目,生成UF2固件文件(若编译报错,优先检查驱动库关联是否正确、头文件名称是否拼写正确);
-
第四步:按前文“固件烧录”步骤,将UF2固件烧录到W55RP20开发板;
-
第五步:打开串口调试助手,查看开发板运行日志,确认网络初始化、DNS解析、MQTT连接成功;
-
第六步:登录OneNET平台,进入设备详情页,查看「物模型数据」,确认温湿度数据定时上传成功。
六、运行结果与OneNET平台验证
6.1 串口输出结果
烧录完成后,开发板自动重启,打开串口调试助手,会输出以下内容,说明网络初始化、DNS解析、MQTT连接及数据上传成功:
---- 已打开串行端口 COM80 ----
=== W55RP20 OneNET MQTT Demo (Final Fixed Version) ===
[PIO SPI CLOCK SPEED : 31.25 MHz] (sys=125.00 MHz)
====================================================================================================
W5500 network configuration : static
MAC : 00:08:DC:12:34:56
IP : 192.168.1.128
Subnet Mask : 255.255.255.0
Gateway : 192.168.1.1
DNS : 8.8.8.8
====================================================================================================
--- DNS Resolution Phase ---
DNS: Using DNS server 8.8.8.8
DNS: Resolving domain: studio-mqtt.heclouds.com
DNS: Success! IP: 218.201.45.7
Connecting to OneNET MQTT broker at 218.201.45.7:1883...
Network connected.
MQTT Connecting to OneNET...
MQTT connected to OneNET Platform!
Subscribed to reply topic: $sys/ZGB6zBD0nS/led/thing/property/post/reply
Topic: $sys/ZGB6zBD0nS/led/thing/property/post
Payload: {"id":"11707","version":"1.0","params":{"temp":{"value":25.6},"humi":{"value":60.1}}}
Data published (QOS0)
Topic: $sys/ZGB6zBD0nS/led/thing/property/post
Payload: {"id":"21708","version":"1.0","params":{"temp":{"value":25.6},"humi":{"value":60.1}}}
Data published (QOS0)
Topic: $sys/ZGB6zBD0nS/led/thing/property/post
Payload: {"id":"31709","version":"1.0","params":{"temp":{"value":25.6},"humi":{"value":60.1}}}
Data published (QOS0)
Topic: $sys/ZGB6zBD0nS/led/thing/property/post
Payload: {"id":"41710","version":"1.0","params":{"temp":{"value":25.6},"humi":{"value":60.1}}}
Data published (QOS0)
说明:若打印“DNS retry”,属于正常现象,最多重试3次;若一直无法解析或连接失败,参考“常见问题排查”部分。
6.2 OneNET平台数据验证
登录OneNET物联网平台,进入设备详情页,查看数据上传情况,步骤如下:
-
进入OneNET平台「物联网核心套件」→「设备管理」,找到已注册的设备,点击设备名称进入详情页;
-
点击「物模型数据」→「实时数据」,可看到温湿度数据定时更新(每10秒一次),与串口打印的 payload 数据一致;
-
点击「消息日志」,可查看设备连接、数据上传、回复消息的详细日志,若数据上传失败,可在此处查看错误原因;
-
(可选)点击「数据可视化」,创建仪表盘,可直观展示温湿度数据的变化趋势。
至此,W55RP20的C语言版MQTT协议与OneNET物联网平台对接实战完成!
七、常见问题一站式排查
结合OneNET对接的特殊性,以下是高频问题及排查步骤,优先排查连接参数和格式问题:
|
问题现象 |
排查步骤 |
|
1. 串口无打印或打印乱码 |
1. 确认串口参数配置正确(波特率115200、无校验);2. 固件为W55RP20专属C语言固件;3. 重新烧录固件,检查USB数据线是否支持数据传输。 |
|
2. DNS解析失败,提示Error |
1. 检查DNS地址是否正确(推荐使用阿里云DNS:223.5.5.5);2. 确认路由器能正常联网;3. 检查OneNET MQTT服务器域名是否拼写正确;4. 重启路由器和开发板。 |
|
3. MQTT连接失败,提示retval为负数 |
1. 确认TCP连接成功(查看串口打印的“Network connected”提示);2. 检查MQTT版本是否为3.1.1(代码中已配置,无需修改);3. 核对产品ID、设备名称、Token是否与OneNET平台一致,无拼写错误;4. 检查Token是否过期,过期需重新生成。 |
|
4. 能连接OneNET,但无法上传数据 |
1. 检查上报主题格式是否正确,产品ID和设备名称是否替换;2. 确认JSON payload格式正确,无语法错误(可复制串口打印的payload到JSON校验工具验证);3. 检查OneNET物模型中属性名是否与payload中的字段名一致(temp、humi,大小写敏感); |
八、W55RP20 核心优势对比
为了让你更直观地了解 W55RP20 的价值,我们对比了目前主流的三种嵌入式以太网方案:
|
对比维度 |
W55RP20 集成方案 |
外接 PHY 芯片 方案 |
外接 串口转以太网模块 方案 |
|
BOM 成本 |
低(单芯片) |
中高(MCU + 模块 + 外围器件) |
高 |
|
PCB 面积 |
小(仅需网口电路) |
大(需预留芯片和布线空间) |
高 |
|
开发难度 |
低(官方驱动库,一行代码联网) |
中高(调试协议栈、编写驱动) |
低 |
|
网络稳定性 |
极高(WIZnet 专注硬件 TCP/IP 协议栈 25 年) |
不定(对于研发人员要求高,熟悉协议栈与网络开发,才能调试稳定) |
不定(视研发公司能力水平) |
|
CPU 资源占用 |
0%(协议栈网络处理完全由硬件完成) |
50% 以上(协议栈完全运行在 MCU 上,占用相关资源) |
0% |
|
硬件 Socket 数量 |
8 个独立硬件 Socket |
视 MCU 能力而定,理论支持多路拓展 |
一般为单路透传 |
|
网络吞吐量 |
最高 15Mbps |
视 MCU 能力而定 |
约 3-5Mbps |
|
接口易用性 |
单芯片集成 |
要 MCU 带有 MII/RMII 等接口 |
TTL 接口 |
|
部署难度 |
低(官方C语言驱动库成熟,应用层协议均有适配,可灵活部署) |
高(应用层协议需要手动移植开源库适配) |
视模块集成情况,无集成的功能需要自我封包拆包 |
九、典型应用场景
W55RP20 芯片集成以太网功能,结合其工业级稳定性,非常适合以下应用场景:
1.工业数据采集网关:简化现场部署,实现传感器数据的稳定上传
2.远程监控终端:用于工厂、机房、变电站等环境的设备状态远程监控
3.串口转网口设备:将传统 RS232/RS485 串口设备快速升级为以太网设备
4.智能楼宇节点:用于照明、空调、门禁等楼宇设备的网络控制
5.工业 PLC 扩展模块:为 PLC 增加以太网通信能力,实现远程编程和数据采集
十. 系列预告与资源获取
10.1系列预告
下一篇教程我们将讲解 W55RP20 c开发下的 MQTT+ThingSpeak实现上传数据,带你了解连接建立、心跳包维护、异常重连等关键机制,掌握嵌入式以太网通信的基础能力。
10.2 资源获取
本文完整代码:WIZnet 官方 Gitee 仓库
W55RP20 芯片手册:WIZnet 官方资料网址
如果本文对你有帮助,欢迎点赞、收藏、关注,你的支持是我们持续更新的动力!如有任何问题,欢迎在评论区留言,我们会第一时间回复。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)