W5100S_EVB_PICO快速入门之MQTT篇(十二)

news2024/12/23 18:35:57

目录

1. 前言       

2. MQTT介绍

2.1 什么是mqtt?

2.2 特点

2.3 应用场景

2.4 MQTT协议实现方式

3. 硬件及接线方式

3.1 硬件准备

3.2 硬件介绍

3.3 接线图

4. 测试

4.1 MQTT测试流程图

4.2 相关代码

4.3 测试现象

5. 相关链接: 


1. 前言       

        随着物联网技术的快速发展,MQTT(Message Queuing Telemetry Transport)协议已成为一种广泛使用的通讯协议,它适用于设备间低带宽、高延迟、不可靠的网络通信。W5500是一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,同时也是一颗工业级以太网控制芯片。在以太网应用中使用 W5500 + MQTT应用协议让用户可以更加方便地在设备之间实现远程连接和通信。本教程将介绍W5500以太网MQTT应用的基本原理、使用步骤、应用实例以及注意事项,帮助读者更好地掌握这一技术。

2. MQTT介绍

2.1 什么是mqtt?

        MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上。MQTT最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

2.2 特点

  1. 轻量级:MQTT协议非常轻量,它的开销很小,适用于低带宽、低功耗设备和网络。
  2. 发布/订阅模式:MQTT采用发布/订阅模式,客户端可以订阅一个或多个主题(Topic),并且可以在不知道其他客户端的情况下发布消息到主题。
  3. QoS支持:MQTT支持三种服务质量(QoS)等级,可以在发布和订阅时指定。 这些等级为0、1、2,提供不同的消息传递保证。
  4. 遗嘱机制:MQTT支持遗嘱(Will)机制,当客户端异常断开连接时,可以通过遗嘱机制通知其他客户端。
  5. 保留消息:MQTT支持保留消息(Retained Message),允许客户端发布一个保留的消息到主题,而后连接到该主题的新订阅者可以立即接收到该消息。
  6. 连接控制:MQTT支持连接控制机制,允许客户端在连接时指定自己的客户端ID、用户名和密码。
  7. 安全性:MQTT支持TLS/SSL加密通信协议,以确保数据的安全传输。
  8. 基于 TCP/IP 网络连接

2.3 应用场景

  1. 科学研究:在科学研究中,需要对实验数据进行采集和传输,使用MQTT协议可以有效地解决数据传输过程中的丢包问题,保证数据传输的稳定性和完整性。
  2. 金融行业:在金融行业中,需要对交易信息进行实时监控和传输,使用MQTT协议可以实现实时监控和传输,并保证数据的稳定性和安全性。
  3. 医疗行业:在医疗行业中,需要对患者的生命体征进行采集和传输,使用MQTT协议可以有效地解决数据传输过程中的丢包问题,保证数据传输的稳定性和完整性。
  4. 能源行业:在能源行业中,需要对能源设备进行监控和控制,MQTT协议正是满足这一需求而设计的,它具有简单、可靠、灵活等特点,在能源领域中得到了广泛应用。

2.4 MQTT协议实现方式

        实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。

MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:

(1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);

(2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。

3. 硬件及接线方式

3.1 硬件准备

  1. W5100S-EVB-Pico开发板
  2. USB数据线、网线
  3. 路由器
  4. pc

3.2 硬件介绍

        W5100S-EVB-Pico是基于树莓派RP2040和全硬件TCP/IP协议栈控制器W5100S的微控制器开发板-基本上与树莓派Pico板相同,但通过W5100S芯片增加了以太网功能。

        W5100S采用WIZnet技术的硬件TCP / IP设计的一款嵌入式以太网控制器。在使用 W5100S时MCU 可以方便的处理 IPv4,TCP,UDP,ICMP,IGMP,ARP,PPPoE等TCP/IP 协议。W5100S 分别有 8KB 的发送缓存和接收缓存,可以减少MCU 的开销。 主机可以同时使用 W5100S 的 4 个独立的硬件SOCKETs,并基于每个硬件SOCKET 开发独立的互联网应用。

3.3 接线图

4. 测试

4.1 MQTT测试流程图

4.2 相关代码

        我们打开例程中库文件的mqttx_client.c文件用到几个函数和定义:

        1.首先我们是对收发缓存大小和收发缓存数组进行定义

        2.然后创建一个 MQTTCONNECTION结构体,里面的参数有mqttHostUrl服务器网址,port端口号,clientid客户端id,username用户名,password密码,server_ip服务器ip,pubtopic发布主题,subtopic1订阅主题,QOS发布服务质量等级。

3.接下就是定义了一个mqtt_params结构体,将结构体的参数填写进去,其中mqttHostUrl服务器网址和server_ip服务器ip填写其中一个就可以,端口固定为1883,clientid客户端id,clientid客户端id不能与同一个服务器下的clientid客户端id重名,username用户名,password密码可以任意填,也可以选择不填,订阅和发布根据自己来定,保证与另一端客户端进行通信并且不受到别人干扰。服务质量等级也是根据自己的需求来定,这里定义的是0,消息最多传送一次。如果当前客户端不可用,它将丢失这条消息

#define SOCKET_ID 0
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)

#define MQTT_SEND_BUFF_SIZE 2048
#define MQTT_RECV_BUFF_SIZE 2048
uint8_t mqtt_send_buff[MQTT_SEND_BUFF_SIZE] = {0};
uint8_t mqtt_recv_buff[MQTT_RECV_BUFF_SIZE] = {0};
typedef struct MQTTCONNECTION
{
    char mqttHostUrl[1024];
    int port;
    char clientid[1024];
    char username[1024];
    char passwd[1024];
    uint8_t server_ip[4];
    char pubtopic[255];
    char subtopic1[255];
    int QOS;
} mqttconn;
mqttconn mqtt_params = {
    .server_ip = {54,244,173,190},
    .port = 1883,
    .clientid = "9a1d7719a8ac40d29311f26c5c5469dc",
    .username = "mqtt_username",
    .passwd = "123456",
    .pubtopic = "1234",
    .subtopic1 = "2345",
    .QOS = 0,
};

        1.定义一个net_info的结构体对静态网络参数进行配置,mac地址不能与已经存在的mac地址有重复,首位不能为偶数,ip地址的设置如果连接路由器这必须与路由器在同一网段,并且不能与路由器已经存在的ip有冲突,下来是sn子网掩码(常用的是255.255.255.0)和gw网关(路由器ip)dns域名解析服务器,然后dhcp设为静态获取网络

void network_init(void);
wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},
    .ip = {192, 168, 124, 10},
    .sn = {255, 255, 255, 0},
    .gw = {192, 168, 124, 1},
    .dns = {8, 8, 8, 8},
    .dhcp = NETINFO_STATIC};
MQTTClient c = {0};  

        1.定义MQTTPacket_connectData 类型的结构体初始化连接协议、版本、心跳包的参数

        2.NewNetwork是网络设置函数,需传入的参数是网络配置的结构体指针和socket号

        3.ConnectNetwork是连接网络函数,需传入的参数是socket号、服务器ip、端口号

        4.MQTTClientInit是客户端初始化函数,需传入mqtt连接配置的结构体指针和网络配置的结构体指针、命令超时时间/ms、发送缓存和发送缓存大小、接收缓存和接收缓存大小。

        5.将得到的数据存入到结构体 MQTTPacket_connectData中

        6.MQTTConnect函数和MQTTSubscrib函数是查看监测是否连接服务器和订阅上主题,如果返回值为0则表示成功

void mqtt_init(void)
{
    int ret;

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    NewNetwork(&n, 1);
    ConnectNetwork(&n, mqtt_params.server_ip, 1883);
    MQTTClientInit(&c, &n, 1000, mqtt_send_buff, MQTT_SEND_BUFF_SIZE, mqtt_recv_buff, MQTT_RECV_BUFF_SIZE);
    data.willFlag = 0;
    data.MQTTVersion = 3;
    data.clientID.cstring = mqtt_params.clientid;
    data.username.cstring = mqtt_params.username;
    data.password.cstring = mqtt_params.passwd;
    data.keepAliveInterval = 30;
    data.cleansession = 1;
    connOK = MQTTConnect(&c, &data);
    printf("Connected:%s\r\n", connOK == 0 ? "success" : "failed");
    printf("Subscribing to %s\r\n", mqtt_params.subtopic1);
    ret = MQTTSubscribe(&c, mqtt_params.subtopic1, mqtt_params.QOS, messageArrived);
    printf("Subscribed:%s\r\n", ret == 0 ? "success" : "failed");
   
    sleep_ms(300);
    MQTTMessage pubmessage={
        .qos=QOS2,
        .dup=0,
        .retained=0,
        .id=0,
    };
    pubmessage.payload="hello mqtt!\r\n";
    pubmessage.payloadlen=strlen(pubmessage.payload);
    MQTTPublish(&c,mqtt_params.pubtopic,&pubmessage);
}

        messageArrived发布消息函数,传入参数是MessageData的结构体,里面主题和消息,函数里面主要是对发布消息的服务等级的判断。
        keep_alive心跳包保活函数,此函数必须放在主循环函数中

void messageArrived(MessageData* md)
{
    unsigned char messagebuffer[512];
    MQTTMessage* message = md->message;
    if (mqtt_params.QOS)
    {
        memcpy(messagebuffer,(char*)message->payload,(int)message->payloadlen);
        *(messagebuffer + (int)message->payloadlen + 1) = '\n';
        printf("%s\r\n",messagebuffer);
    }
    if (mqtt_params.QOS)
        printf("%.*s", (int)message->payloadlen, (char*)message->payload);
    else
        printf("%s%.*s%s%s", "RX:",(int)message->payloadlen, (char*)message->payload, mqtt_params.QOS,"\r\n");
}
void keep_alive(void)
{
    if (!connOK)
    {
        if (MQTTYield(&c, 30))
        {
            mqtt_init();
        }
    }
}
         主函数:主要是对串口和网络还有mqtt进行初始化

int main()                                                          
{   
    struct repeating_timer timer;
    stdio_init_all();
    sleep_ms(2000);
    wizchip_initialize();
    wizchip_setnetinfo(&net_info);
    print_network_information(net_info);
    add_repeating_timer_ms(1, repeating_timer_callback, NULL, &timer);
    mqtt_init();
    while(true)
    {
        // loopback_udpc(SOCKET_ID, ethernet_buf, destip, destport);
        keep_alive();
        sleep_ms(10);
    }
    
}

          烧录完程序后打开MQTTX工具信息配置好mqtt的信息。

        订阅和发布(对应代码上的订阅与发布信息)。

4.3 测试现象

        我们可以看到串口打印信息中打印了网络连接上且配置好网络信息,最后连接上了mqttx上的mqtt公共服务器。

        打开mqttx可以到由W5100S_EVB_PICO发来的“hello mqtt”,表示订阅成功。

         用mqttx切换到发布消息,将信息发送给W5100S_EVB_PICO。

 

        最后可以看到串口打印了mqttx下发的消息,表示发布成功。

5. 相关链接: 

        本章例程链接:mqtt_cliten example

  

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++,名称空间、运算符重载、模板/泛型

目录 一、名称空间 二、重载运算符 三、模板/泛型 一、名称空间 C中名称空间可以区别同名C风格函数、同名C风格全局变量、同名类。名称空间还可以无限嵌套。 namespace ns1 { ..... namespace ns2 { ..... } } 同一个名称空间名字可以多处书写,比如,在demo1.h中…

腾讯云最新优惠活动有哪些?活动入口在哪里?

腾讯云作为国内知名的云计算服务提供商,为了吸引用户,经常推出各种优惠活动。以下是近期腾讯云的一些优惠活动及其入口: 一、腾讯云新用户优惠券【点此领取】 腾讯云新用户专属大礼包,无门槛领取总价值高达2860元代金券&#xff…

postmain 存储接口返回值

1、postmain 存储接口返回值 //把json字符串转化为对象 var dataJSON.parse(responseBody);//获取data对象的utoken值。 var tokendata.data;//设置成全局变量 pm.globals.set("webToken", token); 2、固定参数设置

RocketMQ —消息存储和清理机制

本文为您介绍 Apache RocketMQ 中消息的存储机制,包括消息的存储粒度、判断依据及后续处理策略等。 背景信息​ 参考 Apache RocketMQ 中队列的定义,消息按照达到服务器的先后顺序被存储到队列中,理论上每个队列都支持无限存储。 但是在实…

87、Redis 的 value 所支持的数据类型(String、List、Set、Zset、Hash)---->List相关命令

本次讲解要点: List相关命令:是指value中的数据类型 启动redis服务器: 打开小黑窗: C:\Users\JH>e: E:>cd E:\install\Redis6.0\Redis-x64-6.0.14\bin E:\install\Redis6.0\Redis-x64-6.0.14\bin>redis-server.exe redi…

电压信号拉线位移编码器有何突出的特点

电压信号拉线位移编码器有何突出的特点 电压信号拉线位移编码器原理简单,外观工艺做工精细,由铝合金精心打造、坚固耐磨;适合空间较小的环境安装。该产品重复精度达到0.01%;工作电压上可选择5V或5-24V供电,保护功能上具…

博客摘录「 MPLS/LDP原理介绍+报文分析+配置示例」2023年9月26日

//首先发送UDP Hello组播包进行发现;随后TCP三次握手开始建立Session,Active端和Passive端互相初始化和Keepalive保活确认;完成之后可开始进行标签交互。 //首先发送UDP Hello组播包进行发现;随后TCP三次握手开始建立Session&…

2023-9-26 JZ23 链表中环的入口结点

题目链接:链表中环的入口结点 import java.util.*; /*public class ListNode {int val;ListNode next null;ListNode(int val) {this.val val;} } */ public class Solution {public ListNode EntryNodeOfLoop(ListNode head) {if(head null || head.next null …

MTK6765/MT6765联发科4G安卓核心板安兔兔跑分

Mediatek Helio P35 MTK6765是智能手机的主流ARM SoC。它在两个集群中集成了8个ARM Cortex-A53内核(big.LITTLE)。四个性能内核的频率高达2.3 GHz。 集成显卡为PowerVR GE8320,频率高达680 MHz。 集成内存控制器支持1500 MHz或933 MHz LPDDR3的LPDDR4x。 MT6765处理…

澜渟:长期主义才能成就专研企业

企业的增长模式有三种:第一种是全局增长,即“水大鱼大”式的、更多依靠外界环境的增长;第二种是结构性增长,即找准赛道,随着产业、行业的增长而增长;第三种是内生性增长,即通过内部创新实现增长…

tp6 + swagger 配置文档接口

ThinkPHP 6.0 运行环境要求PHP7.2,兼容PHP8.1 安装 composer create-project topthink/think tp 6.0.*如果需要更新框架使用 composer update topthink/framework文档 完全开发手册 swagger 文档 注解文档 安装包 composer require zircote/swagger-php 引用…

迅为龙芯3A5000_7A2000运行国产Loongnix、银河麒麟、统信UOS以及实时系统翼辉SylixoS系统

iTOP-3A5000开发板采用全国产龙芯3A500处理器,基于龙芯自主指令系统 (LoongArch)的LA464微结构,并进一步提升频率,降低功耗,优化性能。在与龙芯3A4000处理器保持引脚兼容的基础上,频率提升至2.5GHZ,功耗降低…

Vue+Three.js实现三维管道可视化及流动模拟续集

继上一篇文章中实现了三维管道的可视化和流动模拟,经过反馈,对大家还是有一定帮助,因此就编写了一个续集,相当于增加了一些常见的通用共性功能,主要在前面的基础上增加了以下功能:1.新增直角拐弯的管道,工业中很多管道都是横平竖直的,相当于我们装修的水管或电线等,不…

龙芯2K1000核心板在智能座舱行业产品方案-迅为电子

迅为2K1000核心板是一款高性能的处理器,适用于智能座舱行业。它具备多核CPU、高级图像处理和丰富的接口选项,可用于开发先进的智能座舱解决方案,提高乘坐体验、安全性和便捷性。以下是2K1000处理器在智能座舱行业中的产品方案。 高清晰度显…

跨网传输文件时,如何通过日志记录来审计追溯?

跨网文件传输也就是内外网文件传输,一直是企业最基本的传输需求,无论是内部的业务数据、技术文档、合同报告,还是外部的客户资料、合作方案、市场分析,都需要通过不同的网络进行安全高效的传输。然而,跨网传输文件也存…

curl 接口调用工具

后端接口开发完成,你还在为等待前端而无法调试吗? 今天分享一个小工具,curl,一个命令行文件传输工具。可用于大家平常开发的接口调用测试。 它支持文件的上传和下载,支持包括HTTP、HTTPS、ftp等众多协议,…

vue3+eleement plus日历选择季度

<template><div class"el-quarter-wrap"><el-popover width"280" v-model"visible"><template #reference><el-input v-model"quarterDate" placeholder"请选择季度" clearable :prefix-icon&qu…

【Vue.js】使用ElementUI搭建动态树数据表格与分页

一&#xff0c;动态树 本文章为上一篇文章拓展内容》》实现首页导航及左侧菜单 将左侧菜单结构更换为下面代码&#xff1a; 菜单结构&#xff1a; <el-menu><el-submenu index"" key""><template slot"title"><i class…

EOCR-I3M420/I3M420电动机保护器4-20mA输出的设置方法

此文章由上海韩施电气自动化设备有限公司提供 EOCR-I3M420/IFM420是施耐德韩国公司生产的一款具备4-20mA电流输出功能的电动机保护器&#xff0c;它同时还具备过载、欠载、堵转、失速、逆相、缺相和三相不平衡等电流保护功能&#xff0c;以其测量精度高、功能全面、占用空间小…

获得1688商品详情(关键词搜索,店铺所有商品)API接口返回值说明

1688API接口&#xff0c;简单而言&#xff0c;就是一套工具&#xff0c;可以帮助你与1688平台的数据与功能进行智能对接。它能够让你的店铺信息、商品信息、用户数据等信息实现高效流通&#xff0c;帮助你更好地理解客户需求 我们深知数据安全的重要性&#xff0c;因此&#x…