Skip to content

Arduino UNO R4 WiFi MQTT 通信示例文档

1. 简介

本示例演示如何使用 Arduino UNO R4 WiFi 通过 MQTT 协议进行物联网通信。通过板载的 ESP32-S3 WiFi 模块,Arduino 可以作为 MQTT 发布者(Publisher)或订阅者(Subscriber),与 MQTT Broker 进行数据交互。

MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模式的消息传输协议,非常适合资源受限的嵌入式设备和低带宽网络环境。

2. 硬件准备

部件说明
Arduino UNO R4 WiFi主控板(自带 WiFi 模块)
LM35 / AHT30 / DHT11 传感器用于数据采集(可选)
USB Type-C 数据线供电和程序下载
WiFi 网络2.4GHz 无线网络

提示:Arduino UNO R4 WiFi 采用双核架构——Renesas RA4M1(48 MHz Arm Cortex-M4) 负责运行主程序和外设控制,ESP32-S3 模块独立处理 WiFi 与蓝牙通信,网络通信不占用主控资源。

3. 软件准备

3.1 安装 Arduino IDE

3.2 安装开发板支持包

  1. 打开 Arduino IDE
  2. 点击 工具 → 开发板 → 开发板管理器
  3. 搜索 "Arduino UNO R4 WiFi",点击安装

3.3 安装所需库

在 Arduino IDE 的 库管理器(工具 → 管理库)中安装以下库:

库名称用途
WiFiS3Arduino UNO R4 WiFi 的 WiFi 驱动(通常已预装)
ArduinoMqttClientMQTT 协议通信
ArduinoHttpClientHTTP 请求(备选)

注意:UNO R4 WiFi 的 WiFi 库是 WiFiS3,与旧版 UNO WiFi 的 WiFiWiFiNINA 不同,请注意区分。

4. MQTT 通信架构

MQTT 系统包含三个核心组件:

┌─────────────────┐          ┌─────────────────┐          ┌─────────────────┐
│   发布者        │  MQTT   │    Broker       │  MQTT   │   订阅者        │
│ (Arduino UNO)  │ ──────► │ (Mosquitto/EMQX)│ ──────► │ (手机/HA/PC)    │
│                 │  主题   │   消息代理       │  转发   │                 │
└─────────────────┘          └─────────────────┘          └─────────────────┘
  • 发布者(Publisher):发送消息到特定主题的设备(Arduino)
  • Broker(消息代理):接收并转发消息的服务器(如 Mosquitto、EMQX、HiveMQ)
  • 订阅者(Subscriber):接收感兴趣主题消息的设备(手机 App、Home Assistant 等)

5. 示例代码

5.1 基础示例:通过 MQTT 发送温度数据

以下代码实现 Arduino UNO R4 WiFi 连接 WiFi 和 MQTT Broker,并每秒向 temperature 主题发送温度数据。

cpp
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>

// ========== WiFi 配置 ==========
const char* ssid = "你的WiFi名称";      // 修改为实际 WiFi 名称
const char* password = "你的WiFi密码";   // 修改为实际 WiFi 密码

// ========== MQTT 配置 ==========
const char broker[] = "test.mosquitto.org";  // MQTT Broker 地址
int port = 1883;                              // MQTT 端口
const char topic[] = "temperature";           // 发布的主题

// ========== 创建客户端对象 ==========
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    delay(10);
  }

  // ----- 连接 WiFi -----
  Serial.print("正在连接 WiFi: ");
  Serial.println(ssid);
  
  int status = WiFi.begin(ssid, password);
  while (status != WL_CONNECTED) {
    delay(10000);
    status = WiFi.begin(ssid, password);
  }
  
  Serial.print("WiFi 连接成功! IP 地址: ");
  Serial.println(WiFi.localIP());

  // ----- 连接 MQTT Broker -----
  Serial.print("正在连接 MQTT Broker: ");
  Serial.println(broker);
  
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT 连接失败! 错误码: ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  
  Serial.println("MQTT 连接成功!");
}

void loop() {
  // ----- 模拟读取温度数据(实际项目中可接 LM35/DHT11 等传感器)-----
  float temperature = 25.5 + random(-5, 5) * 0.1;
  
  // ----- 发布 MQTT 消息 -----
  mqttClient.beginMessage(topic);
  mqttClient.print(temperature, 1);  // 保留 1 位小数
  mqttClient.endMessage();
  
  // 串口输出调试信息
  Serial.print("已发布温度: ");
  Serial.println(temperature);
  
  // 保持 MQTT 连接活跃
  mqttClient.poll();
  
  delay(1000);  // 每秒发布一次
}

5.2 添加传感器:LM35 模拟温度传感器

如果使用 LM35 温度传感器(连接到 A0 引脚),将 loop() 函数替换为以下代码:

cpp
#define SAMPLES 1000
const int sensorPin = A0;

void loop() {
  // ----- 读取 LM35 温度 -----
  float average = 0;
  for (int k = 1; k <= SAMPLES; k++) {
    average += analogRead(sensorPin);
  }
  average = average / SAMPLES;
  
  // 12 位 ADC,内部参考电压 1.5V
  float voltage = (average / 4095.0) * 1.5;
  float temperature = voltage * 100.0;  // LM35: 10mV/°C
  
  // ----- 发布 MQTT 消息 -----
  mqttClient.beginMessage(topic);
  mqttClient.print(temperature, 2);
  mqttClient.endMessage();
  
  Serial.print("温度: ");
  Serial.println(temperature);
  
  mqttClient.poll();
  delay(1000);
}

setup() 中添加 ADC 配置:

cpp
void setup() {
  // ... 原有 WiFi 和 MQTT 连接代码 ...
  
  // 配置 ADC 为 12 位分辨率,参考电压 1.5V(提高精度)
  analogReadResolution(12);
  analogReference(AR_INTERNAL);
}

5.3 MQTT 订阅示例:接收远程控制命令

以下代码订阅 led/control 主题,接收控制命令来控制板载 LED:

cpp
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>

// ========== 配置 ==========
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
const char broker[] = "broker.hivemq.com";
int port = 1883;
const char subscribeTopic[] = "led/control";

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

const int ledPin = LED_BUILTIN;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  
  // 连接 WiFi(省略详细代码,参考上例)
  // ...
  
  // 连接 MQTT
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT 连接失败!");
    while (1);
  }
  
  // 订阅主题
  mqttClient.subscribe(subscribeTopic);
  Serial.print("已订阅主题: ");
  Serial.println(subscribeTopic);
}

void loop() {
  // 检查 MQTT 消息
  if (mqttClient.parseMessage()) {
    String receivedTopic = mqttClient.messageTopic();
    String payload = mqttClient.readString();
    
    if (receivedTopic == subscribeTopic) {
      Serial.print("收到消息: ");
      Serial.println(payload);
      
      if (payload == "ON") {
        digitalWrite(ledPin, HIGH);
      } else if (payload == "OFF") {
        digitalWrite(ledPin, LOW);
      } else {
        Serial.println("未知命令");
      }
    }
  }
  
  mqttClient.poll();
}

6. 常用 MQTT Broker 列表

Broker 地址端口说明
test.mosquitto.org1883Eclipse Mosquitto 公共测试 Broker
broker.hivemq.com1883HiveMQ 公共 Broker,适合测试
mqtt.eclipseprojects.io1883Eclipse 项目提供的公共 Broker
broker.emqx.io1883EMQX 公共 Broker

7. 测试工具

7.1 手机 App

  • IoT MQTT Panel:功能丰富,支持自定义仪表板和图表
  • myMQTT:轻量级,适合快速测试

7.2 PC 端测试(Mosquitto 客户端)

bash
# 订阅主题,接收 Arduino 发送的数据
mosquitto_sub -h test.mosquitto.org -t "temperature"

8. 常见问题排查

问题可能原因解决方法
WiFi 连接失败SSID/密码错误检查 WiFi 名称和密码,确保为 2.4GHz 网络
MQTT 连接失败Broker 地址/端口错误确认 Broker 地址和端口 1883
发布消息失败MQTT 连接断开检查 WiFi 稳定性,增加 mqttClient.poll() 调用频率
传感器读数异常ADC 配置错误UNO R4 使用 12 位 ADC,参考电压 1.5V
编译错误 WiFiS3.h not found未安装 R4 支持包在开发板管理器中安装 "Arduino UNO R4 WiFi"

9. 进阶应用参考

基于 MQTT 通信,可以扩展实现更多功能:

  • 多设备控制:通过订阅/发布机制同时控制多个 LED 节点
  • Home Assistant 集成:将 Arduino 接入智能家居平台,实现温湿度监控
  • Web 控制面板:通过 Web 界面发送 MQTT 命令控制设备

📌 提示:本文档提供的代码基于公开的 MQTT Broker(无需认证)。如需使用需要用户名/密码的 Broker,可调用 mqttClient.setUsernamePassword(username, password) 进行认证。