STM32与W5500的MQTT通信实践教程
MQTT,即消息队列遥测传输协议(Message Queuing Telemetry Transport),是一种轻量级的发布/订阅消息协议。它因设计简单、实现小巧而被广泛应用于物联网(IoT)领域,用于实现设备间以及设备与服务器间的低带宽、高延迟网络中的消息传输。STM32F103微控制器是STMicroelectronics公司推出的一款基于ARM Cortex-M3内核的高性能微控制器。它拥
简介:本文介绍了一个名为“MQTT_STM32_W5500”的物联网项目,展示了如何利用STM32微控制器和W5500以太网接口芯片通过轻量级MQTT协议实现网络通信。该项目适用于需要数据传输的IoT应用,并包括了STM32F103微控制器的初始化、SPI通信、MQTT连接、主题订阅、消息发布和接收等关键环节。通过此项目,开发者可以掌握在资源受限的嵌入式环境中实现MQTT通信,以及如何与云端平台进行交互,对设计和实现IoT解决方案具有很高的实践价值。 
1. MQTT协议在物联网中的应用
概述MQTT协议
MQTT,即消息队列遥测传输协议(Message Queuing Telemetry Transport),是一种轻量级的发布/订阅消息协议。它因设计简单、实现小巧而被广泛应用于物联网(IoT)领域,用于实现设备间以及设备与服务器间的低带宽、高延迟网络中的消息传输。
物联网通信的需求
物联网设备通常对功耗、带宽和数据传输量有严格要求。MQTT通过主题过滤和消息推送机制,允许数据在需要时发送,节省了设备的电源和网络资源,满足了物联网通信的需求。
MQTT的工作原理
MQTT使用客户端-服务器架构,其中消息代理(Broker)负责消息的分发。客户端连接到代理后,可以根据订阅的主题接收或发送消息。这种模式有效地降低了网络的冗余传输,并提高了消息传递的效率。
2. STM32F103微控制器简介及编程基础
2.1 STM32F103微控制器概述
STM32F103微控制器是STMicroelectronics公司推出的一款基于ARM Cortex-M3内核的高性能微控制器。它拥有丰富的外设接口,高达72MHz的运行频率,以及灵活的功耗控制,被广泛应用于各种嵌入式系统和物联网设备中。接下来我们将对STM32F103的架构特点进行深入的剖析,并介绍如何搭建开发环境。
2.1.1 微控制器架构与特点
STM32F103采用32位RISC核心,拥有独立的三级流水线、硬件除法和单周期乘法器,使其在处理复杂任务时拥有优异的性能。此外,它还拥有256KB到512KB的闪存,32KB到64KB的SRAM,并且支持多种通信接口,包括USART、SPI、I2C、CAN和USB。
特点总结: - 高性能Cortex-M3内核 :具备3级流水线,独立的乘法器和除法器。 - 丰富的内存资源 :不同的存储大小选项,可按需选择。 - 扩展的外设接口 :提供广泛的通信接口,支持多种应用。 - 低功耗模式 :支持多种低功耗模式,适合电池供电设备。
2.1.2 开发环境搭建与配置
开发STM32F103微控制器,通常使用Keil MDK、IAR Embedded Workbench等集成开发环境(IDE)。在本章节中,我们以Keil MDK为例进行说明。
步骤如下: 1. 下载并安装最新版Keil MDK。 2. 启动Keil,创建一个新项目。 3. 在项目选项中选择对应的STM32F103芯片型号。 4. 配置时钟、外设等设置。 5. 加载必要的启动文件和库文件。
完成以上步骤后,环境配置就完成了。开发人员可以开始编写程序,并通过Keil提供的编译、调试工具进行项目开发。
2.2 STM32F103基础编程
2.2.1 GPIO操作与外设配置
GPIO(General Purpose Input/Output)引脚是微控制器与外部设备交互的重要通道。STM32F103通过其内置的GPIO控制器管理这些引脚的功能和状态。
以下是一个简单的GPIO操作代码示例:
// 代码示例:配置GPIO为输出模式
#include "stm32f10x.h"
void GPIO_Configuration(void) {
// 1. 使能GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// 2. 配置GPIOB的第6个引脚为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 3. 设置GPIOB第6个引脚高电平
GPIO_SetBits(GPIOB, GPIO_Pin_6);
}
int main(void) {
// 初始化GPIO
GPIO_Configuration();
while (1) {
// 循环保持状态
}
}
本段代码首先使能了GPIOB的时钟,然后配置了GPIOB的第6个引脚为推挽输出模式,最后将该引脚设置为高电平。通过修改GPIO_SetBits函数的参数,可以轻松控制GPIO引脚输出高电平或低电平。
2.2.2 定时器与中断机制
定时器是微控制器中十分重要的外设,它在精确的时间间隔内产生中断,可以用来管理时间,测量时间间隔或生成PWM波形。
下面的代码片段展示了如何配置STM32F103的定时器中断:
#include "stm32f10x.h"
void TIM_Configuration(void) {
// 1. 使能定时器2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 2. 配置定时器2为1秒中断一次
TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 10000) - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 3. 开启定时器2中断并配置优先级
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 4. 启动定时器2
TIM_Cmd(TIM2, ENABLE);
}
// 定时器2中断服务函数
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 执行定时器中断内的代码,例如翻转LED状态
}
}
int main(void) {
TIM_Configuration();
while (1) {
// 主循环代码
}
}
在此代码中,我们配置了定时器2每秒钟产生一次中断,通过中断服务函数 TIM2_IRQHandler 来执行周期性任务,例如翻转一个LED的状态。定时器的中断机制对于周期性任务的执行至关重要,它允许CPU在无需轮询的情况下,响应定时事件。
以上两节涵盖了STM32F103微控制器的基础知识与编程要点。下一章节,我们将继续深入了解W5500以太网接口芯片。
3. W5500以太网接口芯片详解
3.1 W5500芯片概述
3.1.1 芯片架构与功能特点
W5500是一个全硬件网络协议栈的以太网接口芯片,它集成了TCP/IP协议栈,最高支持8个独立的网络连接(Socket)。W5500芯片的引入简化了嵌入式设备的网络通信设计,尤其是对于微控制器来说,它通过简单的SPI(Serial Peripheral Interface)接口连接,将复杂的网络操作封装起来,提供给用户简化的网络编程接口。
W5500芯片能够支持多种网络功能,包括但不限于IP层的数据包封装、ARP请求、ICMP协议、TCP/UDP协议、以及DHCP功能。此外,其集成的MAC(Media Access Control)和PHY(Physical Layer)层硬件满足IEEE 802.3以太网标准,支持10/100 Mbps数据速率。
W5500的功耗控制也是一个亮点。通过软件控制,可以实现低功耗的网络待机模式。它的工作温度范围广泛,适合各种工业和消费级应用。W5500还具有硬件多播过滤器,能够提高多播数据包的处理效率。
3.1.2 硬件连接与引脚定义
W5500芯片与主控制器(如STM32F103)的连接主要通过SPI总线进行。W5500提供以下关键引脚:
- MISO(Master In Slave Out):数据从W5500发送到主控制器。
- MOSI(Master Out Slave In):数据从主控制器发送到W5500。
- SCLK(Serial Clock):主控制器产生的时钟信号,用于同步数据传输。
- CS(Chip Select):用于选中W5500设备,激活SPI总线通信。
- INT(Interrupt):用于发送中断信号到主控制器,通知有网络事件发生。
除此之外,W5500还包含一些网络物理层连接引脚,如:
- TX+/TX-:用于以太网差分信号传输。
- RX+/RX-:接收以太网差分信号。
- RESET:用于重置W5500。
- VDDIO、GND:分别为芯片的逻辑I/O供电和地线。
3.2 W5500的网络编程基础
3.2.1 网络层配置与控制
W5500的网络层配置可以通过寄存器设置来完成。网络的初始化过程包括设置IP地址、子网掩码、默认网关以及DNS服务器。这些操作通常在设备上电或复位后进行。
在编程过程中,我们首先需要初始化SPI接口,然后根据W5500的寄存器映射来配置网络参数。例如,设置MAC地址寄存器需要写入6个字节的MAC地址数据。IP地址寄存器则需要写入4个字节的IP地址。
W5500支持自动获取IP地址,即通过DHCP协议由DHCP服务器分配。如果需要手动设置静态IP地址,则需要通过编程将静态IP地址的相关信息写入W5500的相关寄存器中。
3.2.2 常用网络功能与编程接口
W5500提供了多种网络功能的编程接口,其中最常用的功能包括:
- 发送和接收网络数据包(包括TCP和UDP模式)
- 发起和维护TCP连接
- 发送和接收电子邮件(通过SMTP/POP3协议)
- 网络状态指示,如连接状态、网络活动等
在TCP模式下,可以使用SOCKET API进行通信,比如创建SOCKET,绑定端口,连接服务器,发送数据,接收数据以及关闭SOCKET等。每个SOCKET都有自己的状态机,可以独立操作。
下面是一个使用W5500进行TCP连接的基本代码示例:
#include "W5500.h"
#include "socket.h"
#define SOCKET 0
void Socket_Init() {
// 初始化W5500
// ...
// 设置网络参数,例如IP地址、子网掩码、默认网关等
// ...
}
void Socket_Connect() {
// 创建一个新的SOCKET
if (Sn_SR(SOCKET) == SOCK_CLOSED) {
Sn_MR(SOCKET) = SOCK_STREAM;
Sn_PORT(SOCKET) = HTONS(80); // HTTP端口
Sn_CR(SOCKET) = CR Connect;
}
}
void Socket_Send(char *data, uint16_t length) {
if (Sn_SR(SOCKET) == SOCK Established) {
Sn_TX_WR(SOCKET) = HTONS(length);
for (int i = 0; i < length; i++) {
WIZCHIP_WRITE(Sn_TX_buf(SOCKET) + i, data[i]);
}
Sn_CR(SOCKET) = CR Send;
}
}
int Socket_Receive(uint8_t *data, uint16_t length) {
int read_len = 0;
if (Sn_SR(SOCKET) == SOCK_CLOSE_WAIT || Sn_SR(SOCKET) == SOCK_CLOSE) {
Sn_CR(SOCKET) = CR Receive;
read_len = Sn_RX_RSR(SOCKET);
if (read_len > length) read_len = length;
for (int i = 0; i < read_len; i++) {
data[i] = WIZCHIP_READ(Sn_RX_buf(SOCKET) + i);
}
}
return read_len;
}
在这个例子中,我们定义了初始化、连接以及发送和接收函数。这些操作都是通过访问W5500的内部寄存器和缓冲区来完成的。需要注意的是,在操作寄存器之前,必须确保已经通过SPI正确地初始化了W5500,并且设置了网络参数。
此外,W5500提供的各种编程接口都是通过其内部的寄存器来实现的,因此在使用时需要仔细阅读其数据手册,确保对这些寄存器进行正确的操作。
在实际应用中,W5500的编程接口通常被抽象成更高级别的网络API,以简化开发过程。针对特定的硬件平台,通常会有现成的库可以使用,这些库封装了上述功能,使得网络编程更为方便快捷。
4. 使用STM32F103与W5500实现MQTT通信
在本章节中,我们将深入探讨如何结合STM32F103微控制器与W5500以太网接口芯片,构建一个可实现MQTT通信的物联网设备。首先,我们会详细分析硬件连接与系统设计的步骤;接着,我们会深入了解如何实现MQTT协议以及进行调试。
4.1 硬件连接与系统设计
4.1.1 STM32F103与W5500硬件接口
STM32F103与W5500芯片之间通过SPI(Serial Peripheral Interface)总线进行通信。在设计硬件连接时,确保STM32F103的SPI引脚与W5500的SPI引脚正确连接,同时还要注意供电和地线连接。此外,W5500芯片还需要通过其特有的网络引脚与外部以太网连接。
以下是一个简化的硬件连接示例代码,展示了如何初始化STM32F103与W5500之间SPI通信的基本步骤:
#include "spi.h"
#include "w5500.h"
int main(void)
{
// 初始化SPI接口
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
// W5500芯片初始化
W5500_Init();
// 其他初始化代码...
while(1)
{
// 主循环代码...
}
}
4.1.2 系统设计与通信流程
系统设计需要考虑如何利用STM32F103强大的计算能力与W5500稳定的网络连接,来实现有效的数据通信。在构建系统时,我们首先要进行硬件接口设计,然后是软件层面上的网络协议栈设计。
通信流程通常遵循以下步骤:
- 初始化STM32F103的网络接口。
- W5500以太网接口芯片初始化,并设置IP地址、子网掩码、网关等网络参数。
- 实现MQTT协议栈,以便STM32F103可以作为MQTT客户端进行通信。
- 建立MQTT连接,登录到MQTT代理服务器。
- 发布和订阅主题,实现数据的上传与接收。
4.2 MQTT协议的实现与调试
4.2.1 MQTT协议栈的选择与集成
在实现MQTT协议时,首先要选择合适的MQTT协议栈。对于STM32F103这样的微控制器,我们通常会选择轻量级的MQTT客户端库,如Paho MQTT库。集成这个库到我们的项目中,可以通过以下步骤实现:
- 下载Paho MQTT库。
- 将库文件包含到STM32F103的项目中。
- 根据项目需求配置库选项。
具体示例代码如下:
#include "MQTTClient.h"
#define ADDRESS "tcp://broker.hivemq.com:1883"
#define CLIENTID "STM32F103Client"
#define TOPIC "test/topic"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
MQTTClient client;
void MQTTPublish(void)
{
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
pubmsg.payload = (void*)PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
printf("Waiting for publication of %s\non topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID);
rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
printf("Message with delivery token %d delivered\n", token);
}
int main(int argc, char* argv[])
{
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
int rc;
MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
MQTTClient_setCallbacks(client, NULL, NULL, NULL, NULL);
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
MQTTPublish();
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}
4.2.2 MQTT连接、消息发布与接收的实现
接下来,我们需要实现MQTT连接、消息发布和接收的逻辑。这需要我们仔细阅读并理解Paho MQTT库的API文档,编写适合STM32F103与W5500的网络环境的代码。
在连接到MQTT代理服务器时,我们必须考虑网络异常和重连机制。发布消息时,应实现对消息传递状态的确认机制,以确保消息可靠地发送到代理服务器。消息接收则涉及到回调函数的设计,以便在接收到订阅主题的消息时,执行特定的操作。
在代码中,我们通常会定义如下结构来处理这些操作:
// MQTT连接选项
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
// MQTT客户端句柄
MQTTClient client;
// 网络读取超时时间
int timeout = 3600 * 1000L;
// MQTT连接处理函数
void onConnect(MQTTClient* client, void* context, MQTTClient_token璜ret)
{
if(ret == MQTTCLIENT_SUCCESS)
{
// 连接成功,执行订阅等操作...
}
}
// MQTT消息接收处理函数
void onMessageArrived(MQTTClient* client, char* topicName, int topicLen, MQTTClient_message* message, void* context)
{
// 消息接收处理逻辑...
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
}
// MQTT消息发布函数
void publishMessage(MQTTClient client, char* topic, char* payload, int payloadLen, int qos)
{
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
pubmsg.payload = payload;
pubmsg.payloadlen = payloadLen;
pubmsg.qos = qos;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
// 等待消息发布完成...
}
// MQTT程序入口
int main(int argc, char* argv[])
{
// 定义MQTT连接选项
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.onConnect = onConnect;
conn_opts.onMessageArrived = onMessageArrived;
// 创建MQTT客户端实例
MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
// 连接到MQTT代理服务器
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
// 发布消息
publishMessage(client, TOPIC, PAYLOAD, strlen(PAYLOAD), QOS);
// 断开连接并销毁MQTT客户端实例
MQTTClient_disconnect(client, timeout);
MQTTClient_destroy(&client);
return rc;
}
通过以上步骤,我们可以完成STM32F103微控制器与W5500以太网接口芯片结合实现MQTT通信的基本设计与实现。这不仅涵盖了硬件的连接与初始化,也深入探讨了如何在软件层面上实现MQTT协议,并确保设备能够稳定地与MQTT代理服务器进行消息的发布和接收。
5. MQTT客户端库的使用与物联网设备交互
5.1 MQTT客户端库概览
5.1.1 Paho MQTT库与EMQX SDK的选择
在实现MQTT通信时,选择一个合适的客户端库是至关重要的。Paho MQTT库和EMQX SDK是两种广泛使用的库,它们各有特点。
Paho MQTT库是由Eclipse基金会维护的开源项目,专注于提供轻量级的MQTT客户端实现,支持多种编程语言,包括Python、Java、C等。Paho库非常注重跨平台支持,并且是物联网设备开发中常用的库。
而EMQX SDK是另一款强大的库,由EMQX公司维护,它提供丰富的MQTT客户端功能,包括连接管理、消息发布和订阅、会话持久化等。它更适合需要高度可靠和可扩展性的企业级应用。
在选择时,需要考虑项目需求、开发语言和预期的性能等因素。例如,如果你的项目使用的是Python,并且对轻量级有较高要求,Paho可能是更好的选择。如果你的项目需要在企业环境中部署,并且对稳定性和安全性有很高的要求,EMQX SDK将是更适合的选项。
5.1.2 库的安装与配置
安装Paho MQTT库的步骤依赖于你选择的编程语言。以下是在Python环境下安装Paho MQTT库的示例代码:
pip install paho-mqtt
安装后,你可以在代码中导入并使用它:
import paho.mqtt.client as mqtt
# 创建MQTT客户端实例
client = mqtt.Client()
# 连接MQTT代理服务器
client.connect("broker.hivemq.com")
而安装EMQX SDK可能需要从源代码编译或者使用包管理器进行安装。以C语言为例,以下是安装EMQX MQTT客户端库的步骤:
- 下载EMQX MQTT客户端库源码。
- 解压并进入源码目录。
- 使用configure脚本生成Makefile。
- 执行make编译命令。
- 执行make install进行安装。
配置过程中,你可能需要指定MQTT代理服务器的地址、端口和其他连接参数。根据库的不同,配置方式也会有所差异,但大体上都遵循类似的步骤。
5.2 物联网设备与云端平台的交互实例
5.2.1 云端平台选择与接入
在物联网应用中,选择一个合适的云端平台是实现设备与云间通信的第一步。市面上有许多不同的云服务提供商,如AWS IoT、Microsoft Azure IoT Hub、Google Cloud IoT等。
以AWS IoT为例,接入设备需要以下步骤:
- 创建AWS IoT核心服务。
- 生成设备证书并注册设备。
- 为设备配置IAM(Identity and Access Management)策略。
- 将设备证书和私钥上传到设备。
- 设备使用证书和私钥连接到AWS IoT。
5.2.2 物联网设备数据处理与交互策略
在连接到云端平台后,物联网设备需要进行数据处理和交互策略的配置,以实现有效的数据通信。
数据处理可能包括传感器数据的采集、预处理、过滤、格式化等。预处理可能涉及转换数据格式、执行数据清洗或执行简单分析。
设备交互策略方面,通常需要定义设备如何发布数据到云端(上报),以及如何接收云端的指令或查询响应(下发)。这可能需要在设备端实现状态机逻辑,以处理各种消息类型和相应的动作。
以AWS IoT为例,设备可以发布消息到一个或多个主题(topic),云端平台可以订阅这些主题,并根据接收到的数据做出响应。设备端的伪代码示例:
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
client.subscribe("$aws/things/MyDevice/shadow/update")
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("your-broker-endpoint", 1883, 60)
# Start the network loop for processing messages
client.loop_forever()
在此代码中,设备在连接成功后订阅了一个主题,并定义了一个处理消息的回调函数。这样,当设备接收到云端发送的消息时,它将执行相应的方法。
在实际应用中,除了实现上述基础的MQTT通信功能,还需要考虑安全连接(如使用TLS/SSL加密)、消息确认、重连机制、设备在线状态监测等功能,以保证物联网设备与云端平台间通信的可靠性与稳定性。
简介:本文介绍了一个名为“MQTT_STM32_W5500”的物联网项目,展示了如何利用STM32微控制器和W5500以太网接口芯片通过轻量级MQTT协议实现网络通信。该项目适用于需要数据传输的IoT应用,并包括了STM32F103微控制器的初始化、SPI通信、MQTT连接、主题订阅、消息发布和接收等关键环节。通过此项目,开发者可以掌握在资源受限的嵌入式环境中实现MQTT通信,以及如何与云端平台进行交互,对设计和实现IoT解决方案具有很高的实践价值。
更多推荐




所有评论(0)