二十、W5100S/W5500+RP2040树莓派Pico<MQTT连接阿里云控制板载LED>

1. 前言

  物联网平台提供安全可靠的设备连接通信能力,支持设备数据采集上云,规则引擎流转数据和云端数据下发设备端。此外,也提供方便快捷的设备管理能力,支持物模型定义,数据结构化存储,和远程调试、监控、运维。本章讲解阿里云物联网平台的使用方法,并讲解使用设备连接阿里云物联网平台。

  在以太网应用中使用 W5500 + MQTT应用协议让用户可以更加方便地在设备之间实现阿里云远程连接和通信。本教程将介绍W5500以太网MQTT连接阿里云的应用以及注意事项,帮助读者更好地掌握这一技术。

2. 简介

2.1 初步了解阿里云物联网平台创建产品步骤

接着进入正题,如何在阿里云公共实例平台创建产品:

  1. 以aliyun账号直接进入IoT控制台,如果还没有开通阿里云物联网套件服务,则申请开通

  2. 开通完后,创建一个自定义产品类

    在这里插入图片描述

  3. 之后再添加一个测试设备

    在这里插入图片描述

  4. 添加好之后点进去查看设备,查看连接参数
    在这里插入图片描述

  5. 之后再去产品那边查看功能定义里添加物模型
    在这里插入图片描述

  6. 下面是查看发布和订阅主题,要将${deviceName}替换成上一个步骤获取的DeviceName然后保存
    在这里插入图片描述

  7. 设置遗嘱消息的发布主题

在这里插入图片描述

2.2 阿里云物模型讲解

  物模型是物理空间中的实体(如传感器、车载装置、楼宇、工厂等)在云端的数字化表示,从属性、服务和事件三个维度,分别描述了该实体是什么、能做什么、可以对外提供哪些信息。定义了物模型的这三个维度,即完成了产品功能的定义。

功能类型说明
属性(Property)用于描述设备运行时具体信息和状态。例如,环境监测设备所读取的当前环境温度、智能灯开关状态、电风扇风力等级等。属性可分为读写和只读两种类型。读写类型支持读取和设置属性值,只读类型仅支持读取属性值。
服务(Service)指设备可供外部调用的指令或方法。服务调用中可设置输入和输出参数。输入参数是服务执行时的参数,输出参数是服务执行后的结果。相比于属性,服务可通过一条指令实现更复杂的业务逻辑,例如执行某项特定的任务。服务分为异步和同步两种调用方式。
事件(Event)设备运行时,主动上报给云端的信息,一般包含需要被外部感知和处理的信息、告警和故障。事件中可包含多个输出参数。例如,某项任务完成后的通知信息;设备发生故障时的温度、时间信息;设备告警时的运行状态等。事件可以被订阅和推送。

  物联网平台支持为产品定义多组功能(属性、服务和事件)。一组功能定义的集合,就是一个物模型模块。多个物模型模块,彼此互不影响。

3 WIZnet以太网芯片

  WIZnet 主流硬件协议栈以太网芯片参数对比

ModelEmbedded CoreHost I/FTX/RX BufferHW SocketNetwork Performance
W5100STCP/IPv4, MAC & PHY8bit BUS, SPI16KB4Max.25Mbps
W6100TCP/IPv4/IPv6, MAC & PHY8bit BUS, Fast SPI32KB8Max.25Mbps
W5500TCP/IPv4, MAC & PHYFast SPI32KB8Max 15Mbps
  1. W5100S/W6100 支持 8bit数据总线接口,网络传输速度会优于W5500。
  2. W6100 支持IPV6,与W5100S 硬件兼容,若已使用W5100S的用户需要支持IPv6,可以Pin to Pin兼容。
  3. W5500 拥有比 W5100S更多的 Socket数量以及发送与接收缓存。

4 示例概述

4.1 流程图

  程序的运行框图如下所示:

在这里插入图片描述

4.2 准备工作核心

软件

  • Visual Studio Code
  • WIZnet UartTool
  • 阿里云平台

硬件

  • W5100SIO模块 + RP2040 树莓派Pico开发板 或者 WIZnet W5100S-EVB-Pico开发板
  • Micro USB 接口的数据线
  • TTL 转 USB
  • 网线

4.3 连接方式

  • 通过数据线连接PC的USB口(主要用于烧录程序,也可以虚拟出串口使用)

  • 通过TTL串口转USB,连接UART0 的默认引脚:

    • RP2040 GPIO0(UART0 TX) <----> USB_TTL_RX
    • RP2040 GPIO1(UART0 RX) <----> USB_TTL_TX
  • 使用模块连接RP2040 进行接线时

    • RP2040 GPIO16 <----> W5100S MISO
    • RP2040 GPIO17 <----> W5100S CS
    • RP2040 GPIO18 <----> W5100S SCK
    • RP2040 GPIO19 <----> W5100S MOSI
    • RP2040 GPIO20 <----> W5100S RST
  • 通过PC和设备都通过网线连接路由器LAN口

4.4 主要代码概述

  我们使用的是WIZnet官方的ioLibrary_Driver库。该库支持的协议丰富,操作简单,芯片在硬件上集成了TCP/IP协议栈,该库又封装好了TCP/IP层之上的协议,我们只需简单调用相应函数即可完成协议的应用。

第一步:mqtt_aliyun.c文件中加入对应的.h文件。

第二步:定义DHCP所要的宏和MQTT收发缓存buff的宏。

第三步:定义一个mqtt连接参数的结构体并进行定义,这里给结构体赋的值是阿里云上对应的连参数,以及发布和订阅主题和遗嘱主题的设置都是相对应的。

第四步: 初始化了库内部的参数。

第五步:网络信息的配置和mqtt初始的参数,以及标志位。

第六步:编写定时器回调处理函数,用于DHCP和MQTT 滴答定时器处理函数。

第七步:主函数先是对串口和SPI的初始化,然后写入W5100S的网络配置参数,初始化DHCP后开始DHCP获取IP,获取到就打印获取到的IP,获取次数超过最大获取次数时就使用静态IP,DNS解析域名,之后初始化MQTT,然后主循环是一个状态机的轮询,状态机先是进入到连接状态,当连接成功之后状态才开始进行发布和订阅,然后到订阅遗嘱消息,然后阿里云进行数据的下发和接收。

void network_init(wiz_NetInfo *conf_info);
bool repeating_timer_1ms_callback(struct repeating_timer *t);
bool repeating_timer_1s_callback(struct repeating_timer *t);
void mqtt_init(void);
void messageArrived(MessageData *md);
void do_dns(uint8_t *domain_name, uint8_t *remote_ip);
void json_decode(uint8_t *msg);

int main()
{
    /* Variable definition */
    int ret;
    struct repeating_timer timer_1s;
    struct repeating_timer timer_1ms;
    MQTTMessage pubmessage = {0};

    /*mcu init*/
    stdio_init_all();     /*Initialize the serial port*/
    wizchip_initialize(); /*Initialize the SPI*/

    /* LED init */
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);

    /*timer init*/
    add_repeating_timer_ms(1000, repeating_timer_1s_callback, NULL, &timer_1s); // Add DHCP and DNS 1s Tick Timer handler
    add_repeating_timer_ms(1, repeating_timer_1ms_callback, NULL, &timer_1ms);  // Add MQTT 1ms Tick Timer handler

    /*dhcp init*/
    DHCP_init(SOCK_DHCP, ethernet_buf); // DHCP initialization

    /*dns init*/
    DNS_init(SOCK_DNS, ethernet_buf);

    /* Set the network address information */
    printf("wiznet chip mqtt of aliyun example.\r\n");
    network_init(&net_info);              // Configuring Network Information
    print_network_information(&get_info); // Read back the configuration information and print it

    /* Resolve mqtt broker domain names using dns */
    do_dns(mqtt_params.mqttHostUrl, mqtt_params.server_ip);

    /*mqtt init*/
    mqtt_init();

    while (true)
    {
        switch (run_status)
        {
        case CONN:
        {
            ret = MQTTConnect(&c, &data); /* Connect to the MQTT server */
            printf("Connect to the MQTT server: %d.%d.%d.%d:%d\r\n", mqtt_params.server_ip[0], mqtt_params.server_ip[1], mqtt_params.server_ip[2], mqtt_params.server_ip[3], mqtt_params.port);
            printf("Connected:%s\r\n\r\n", ret == SUCCESSS ? "success" : "failed");
            if (ret != SUCCESSS)
            {
                run_status = ERROR;
            }
            else
            {
                run_status = SUB;
            }
            break;
        }
        case SUB:
        {
            ret = MQTTSubscribe(&c, mqtt_params.subtopic, mqtt_params.subQoS, messageArrived); /* Subscribe to Topics */
            printf("Subscribing to %s\r\n", mqtt_params.subtopic);
            printf("Subscribed:%s\r\n\r\n", ret == SUCCESSS ? "success" : "failed");
            if (ret != SUCCESSS)
            {
                run_status = ERROR;
            }
            else
            {
                run_status = PUB_ONLINE;
            }
            run_status = PUB_ONLINE;
            break;
        }
        case PUB_ONLINE:
        {
            pubmessage.qos = 0;
            pubmessage.payload = "W5100S online!";
            pubmessage.payloadlen = strlen(pubmessage.payload);
            ret = MQTTPublish(&c, mqtt_params.willtopic, &pubmessage); /* Publish message */
            if (ret != SUCCESSS)
            {
                run_status = ERROR;
            }
            else
            {
                printf("publish:%s,%s\r\n\r\n", mqtt_params.willtopic, pubmessage.payload);
                run_status = PUB_MESSAGE;
            }
            break;
        }
        case PUB_MESSAGE:
        {
            pubmessage.qos = 0;
            pubmessage.payload = "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"CurrentTemperature\":26.6,},\"method\":\"thing.event.property.post\"}";
            pubmessage.payloadlen = strlen(pubmessage.payload);
            ret = MQTTPublish(&c, (uint8_t *)&(mqtt_params.pubtopic), &pubmessage); /* Publish message */
            if (ret != SUCCESSS)
            {
                run_status = ERROR;
            }
            else
            {
                printf("publish:%s,%s\r\n\r\n", mqtt_params.pubtopic, pubmessage.payload);
                run_status = KEEPALIVE;
            }
            break;
        }
        case KEEPALIVE:
        {
            if (MQTTYield(&c, 30) != SUCCESSS) /* keepalive MQTT */
            {
                run_status = ERROR;
            }
            sleep_ms(100);
            break;
        }
        case ERROR: /* Running error */
            printf("system ERROR!");
            sleep_ms(1000);
            break;

        default:
            break;
        }
    }
}

4.5 结果演示

在这里插入图片描述

1.打开WIZ UartTool,填入参数,获取到IP之后解析mqtt服务器域名,然后进行阿里云的连接,连接成功后会打印订阅和发布的主题,并对服务器发送信息,同时上传模拟的物模型数据。

在这里插入图片描述

2.可以看到板子上LED灯是灭的,接下来我们通过阿里云来将灯给打开。

在这里插入图片描述

3.可以看到设备已经上线,并且物模型以及获取到开发板发布的数据,然后我们看到LED是关闭状态。进入到在线调试进行设置灯的状态。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.可以看到当阿里云设置完灯的状态时,串口打印出接收到数据,并通过json解析出开启LED灯,然后开发板将灯开启。至此测试结束。

5 注意事项

  • 发布和订阅不要弄反了 ,弄反会导致收不到消息。
  • 把阿里云的物模型主题复制过来时,需要把{devicename}替换成设备名
  • 如果想用WIZnet的W5500来实现本章的示例,我们只需修改两个地方即可:

​ (1)在library/ioLibrary_Driver/Ethernet/下找到wizchip_conf.h这个头文件,将_WIZCHIP_ 宏定义修改为W5500。

​ (2)在library下找到CMakeLists.txt文件,将COMPILE_SEL设置为ON即可,OFF为W5100S,ON为W5500。

6 相关链接

WIZnet官网

WIZnet官方库链接

本章例程链接

想了解更多,评论留言哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/121920.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

es6过滤对象里面指定的不要的值filter过滤

//过滤出需要的值this.dataItemTypeSelectOption response.data.filter(ele > ele.dictValue tree||ele.dictValue float4);//过滤不需要的值this.dataItemTypeSelectOption response.data.filter((item) > {return item.dictValue ! "float4"&&it…

Note1: 算法的时间复杂度和空间复杂度

目录 ---前言 1.算法效率 1.1 算法的复杂度 2.时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3常见时间复杂度计算举例 2.3.1 示例1 2.3.2 示例2 2.3.3 示例3 2.3.4 示例4 2.3.5 示例5 2.3.6 示例6 2.3.7 示例7 2.3.8 示例8 3.空间复杂度 3.1 示例1 …

征服地球极限,中国极地科考与登峰事业的“御寒”之旅

7日&#xff0c;全国各地大幅降温&#xff0c;今年第一场暴风雪也席卷了黑龙江。 伴随着冷空气不断入侵&#xff0c;气温持续走低&#xff0c;寒冬的脚步越来越近&#xff0c;供暖也成为了北方地区的冬季重点民生课题。 是日&#xff0c;天色未晓&#xff0c;黑龙江各地身披红…

经典OJ题:单链表的回文结构

回文结构&#xff1a; 所谓的回文结构就是将一组数值分为两个部分&#xff0c;并用取一个中间值&#xff0c;除去中间值外&#xff0c;其他的数值都是一一镜面对称相同。 如&#xff1a; 这就是单链表的回文结构 。 题目&#xff1a; 判断单链表是否符合回文结构&#xff1a;…

SOLIDWORKS参数化设计之干涉检查

SOLIDWORKS参数化设计的思路和技巧我们讲过很多了&#xff0c;今天来讲一讲如何在模型完成之后自动执行干涉检查。 SOLIDWORKS软件本身就有干涉检查的功能&#xff0c;在评估选项卡里可以找到该功能&#xff0c;我们这里说的干涉检查指的是静态干涉检查&#xff0c;即模型在静…

异常断电文件损坏docker服务异常处理

问题场景 我们在某地部署信控平台&#xff0c;当初是在产品研发早期&#xff0c;采取的还是Windows服务器部署虚拟机的方式使用virtualbox导入centos7虚拟机&#xff0c;虚拟机里运行docker服务&#xff0c;使用docker-compose统一管理客户今天上午反馈&#xff0c;昨天断电了…

【源码】自制链接表管理器

hi&#xff0c;大家好呀&#xff01; 前几天更新了个视频&#xff0c;教大家做了一个链接表的管理器&#xff0c;今天把文字内容给到大家&#xff0c;至于什么原因需要自己做一个链接表管理器&#xff0c;我在视频中有讲到&#xff0c;因为系统自带的链接表管理器没有筛选功能…

技术分享 | app自动化测试(Android)--显式等待机制

WebDriverWait类解析 WebDriverWait 用法代码 Python 版本 WebDriverWait(driver,timeout,poll_frequency0.5,ignored_exceptionsNone)参数解析&#xff1a; driver&#xff1a;WebDriver 实例对象 timeout: 最长等待时间&#xff0c;单位秒 poll_frequency: 检测的间隔步…

怎么批量获取文件名,并保存到excel?

怎么批量获取文件名&#xff1f;什么叫批量获取文件名&#xff0c;其实也非常好理解&#xff0c;就是面对大量文件是可以一次性的获取所有文件名称&#xff0c;这项技术的应用也是非常常见的&#xff0c;为什么这么说呢&#xff1f;现在很多的文档管理人员或者公司的文员&#…

Go类型嵌入介绍和使用类型嵌入模拟实现“继承”

一、独立的自定义类型 什么是独立的自定义类型呢&#xff1f;就是这个类型的所有方法都是自己显式实现的。 我们举个例子&#xff0c;自定义类型 T 有两个方法 M1 和 M2&#xff0c;如果 T 是一个独立的自定义类型&#xff0c;那我们在声明类型 T 的 Go 包源码文件中一定可以找…

Redis中的渐进式遍历-Scan命令

之前我们学习过遍历命令keys,而keys *是一次性的把整个redis中所有的key都获取到.在不知道当前redis中有多少key的情况下,这个操作是非常危险的,可能会一下子得到太多的key而阻塞redis服务器.从而使其他redis客户端卡顿. 通过渐进式遍历,就可以做到,既可以获取到所有的key,同时…

利用AI快速跨过新手区:用DevChat编写Python程序-CSV导入TDengine

还在用百度搜索编程吗&#xff1f; 直接上 AI&#xff0c;帮助小白快速跨过新手区。 以下用一个物联网最常见的场景做示例演示如何利用 AI 快速编程。 ChatGPT4 是目前最火的 AI 了&#xff0c;但是国内却用不了。不过现在新出的 DevChat 可以让大家尝鲜一番。 以下介绍来自B…

linux生成code文件

1. 设置core文件路径在当前工作目录 echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern 具体参数 %s - insert signal that caused the coredump into the filename 添加导致产生core的信号 %t - insert UNIX time that the coredump occurred into filen…

scss 实用教程

变量 $ 定义变量 $link-color: blue;变量名可以与css中的属性名和选择器名称相同 使用变量 a {color: $link_color; }$highlight-border: 1px solid $link_color;中划线和下划线相互兼容&#xff0c;即中划线声明的变量可以使用下划线的方式引用&#xff0c;反之亦然。 $li…

Python教程:随机函数,开始猜英文单词的游戏

开始猜英文单词的游戏… 总计生命次数&#xff1a;3次 -----------游戏开始中…----------- &#xff1f;&#xff1f;&#xff1f;&#xff1f;请猜一个&#xff0c;4位数的单词:mafr 猜错了&#xff0c;再努力一下 -----------你还有2次生命------------ ma&#xff1f;&…

一文带你走进 AIGC(生成式人工智能)世界

AI&#xff08;人工智能&#xff09;是一门在过去几十年中不断增长其能力和效用的学科。AI 驱动的工具正逐渐成为主流&#xff0c;例如改进的语音识别、及时翻译以及令人惊叹不止的图像编辑工具&#xff0c;它们使我们能够根据自定义风格轻松地突出显示图像中想要替换的内容。 …

如何下载PDF版本的专利

问题描述&#xff1a;有时下载的专利是CAJ格式&#xff0c;需要用CAJViewer软件才能观看&#xff0c;那么如何下载pdf版本的呢&#xff1f; 问题解决&#xff1a; 方法一&#xff1a; 使用CAJViewer软件进行转换。&#xff08;注意&#xff1a;这种方法转换的PDF其实就是一个…

Linux环境下安装人大金仓数据库

人大金仓产品简介 金仓数据库管理系统[简称:KingbaseES]是北京人大金仓信息技术股份有限公司&#xff08;简称人大金仓&#xff09;自主研发的、具有自主知识产权的商用关系型数据库管理系统&#xff08;DBMS&#xff09;。该产品面向事务处理类应用&#xff0c;兼顾各类数据分…

JAVA 版小程序商城免费搭建 多商家入驻 直播带货 商城系统 B2B2C 商城源码之 B2B2C产品概述

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

idea使用git删除本地提交(未推送)

1、找到reset head 2、打开弹窗&#xff0c;在HEAD后面输入^ 结果为HEAD^ 注释&#xff1a; Reset Type 有三种&#xff1a; Mixed&#xff08;默认方式&#xff09;&#xff0c;保留本地源码&#xff0c;回退 commit 和 index 信息&#xff0c;最常用的方式Soft 回退到某个版本…