Skip to content

Arduino UNO R4 WiFi TCP 通信示例文档

1. 简介

本示例演示如何使用 Arduino UNO R4 WiFi 通过 TCP 协议进行网络通信。TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,保证数据完整有序地到达目的地,适合需要高可靠性的数据传输场景。

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


2. TCP vs UDP:如何选择?

特性TCPUDP
连接方式面向连接(需建立连接)无连接
可靠性可靠传输,保证数据到达不保证到达
数据顺序按序到达可能乱序
适用场景需要可靠通信的控制指令、状态上报实时数据流、广播信息

提示:对于需要确认指令执行结果的控制场景,推荐使用 TCP;对于传感器数据上报这类实时性要求高但允许偶尔丢包的场景,UDP 更轻量高效。


3. 硬件准备

部件说明
Arduino UNO R4 WiFi主控板
LM35 / 传感器(可选)数据采集
USB Type-C 数据线供电和程序下载
WiFi 网络2.4GHz 无线网络
PC 端 TCP 服务端软件测试用(如 ezTermnetcatPutty

4. 软件准备

4.1 安装开发板支持包

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

4.2 核心库

UNO R4 WiFi 使用 WiFiS3 库(与旧版 UNO WiFi 的 WiFiNINA 不同,请注意区分):

cpp
#include <WiFiS3.h>

5. 示例 1:TCP 客户端(向服务器发送数据)

以下代码实现 Arduino 作为 TCP 客户端,连接到 PC 端的 TCP 服务器,并发送数据。

5.1 完整代码

cpp
#include <WiFiS3.h>

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

// ========== TCP 服务器配置 ==========
const char* TCP_SERVER_ADDR = "192.168.1.100";  // 修改为服务器 IP 地址
const int TCP_SERVER_PORT = 1470;               // 修改为服务器端口

WiFiClient tcpClient;

void setup() {
  Serial.begin(9600);
  while (!Serial) delay(10);
  
  Serial.println("=== Arduino UNO R4 WiFi TCP Client ===");

  // 检查 WiFi 模块状态
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("WiFi 模块通信失败!");
    while (true);
  }

  // 检查固件版本
  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("请升级 WiFi 固件");
  }

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

  // ----- 连接 TCP 服务器 -----
  Serial.print("正在连接 TCP 服务器: ");
  Serial.print(TCP_SERVER_ADDR);
  Serial.print(":");
  Serial.println(TCP_SERVER_PORT);
  
  if (tcpClient.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
    Serial.println("TCP 服务器连接成功!");
    tcpClient.println("Hello from Arduino UNO R4 WiFi!");
  } else {
    Serial.println("TCP 服务器连接失败!");
  }
}

void loop() {
  // ----- 接收服务器数据并打印到串口 -----
  if (tcpClient.available()) {
    char c = tcpClient.read();
    Serial.print(c);
  }

  // ----- 检查连接状态,断开则尝试重连 -----
  if (!tcpClient.connected()) {
    Serial.println("连接已断开,尝试重连...");
    tcpClient.stop();
    
    if (tcpClient.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
      Serial.println("重新连接成功!");
      tcpClient.println("Reconnected!");
    } else {
      Serial.println("重新连接失败,等待 1 秒后重试...");
      delay(1000);
    }
  }
}

5.2 PC 端 TCP 服务器测试

方法一:使用 netcat(Linux/macOS)

bash
# 在终端中监听端口 1470
nc -l 1470

方法二:使用 Windows 端 TCP 服务器软件

  1. 下载并运行 ezTerm 或其他 TCP 服务器软件
  2. 配置为 TCP Server 模式,监听端口 1470
  3. 点击 Listen 按钮

方法三:使用 Python 快速启动 TCP 服务器

python
# server.py
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 1470))
server.listen(1)
print("监听端口 1470...")

conn, addr = server.accept()
print(f"客户端已连接: {addr}")

while True:
    data = conn.recv(1024)
    if not data:
        break
    print(f"收到: {data.decode()}")
    conn.send(b"ACK: " + data)

6. 示例 2:双向通信(串口 ↔ TCP 透传)

以下代码将 Arduino 的串口数据转发到 TCP 服务器,并将 TCP 服务器返回的数据转发到串口,实现双向透传。

cpp
#include <WiFiS3.h>

// ========== WiFi 配置 ==========
const char* WIFI_SSID = "你的WiFi名称";
const char* WIFI_PASSWORD = "你的WiFi密码";

// ========== TCP 服务器配置 ==========
const char* TCP_SERVER_ADDR = "192.168.1.100";
const int TCP_SERVER_PORT = 1470;

WiFiClient tcpClient;

void setup() {
  Serial.begin(9600);
  while (!Serial) delay(10);
  
  Serial.println("=== Serial ↔ TCP Bridge ===");

  // 连接 WiFi
  while (WiFi.begin(WIFI_SSID, WIFI_PASSWORD) != WL_CONNECTED) {
    Serial.print(".");
    delay(10000);
  }
  Serial.println("\nWiFi 已连接!IP: " + WiFi.localIP().toString());

  // 连接 TCP 服务器
  if (tcpClient.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
    Serial.println("TCP 服务器已连接");
  } else {
    Serial.println("TCP 服务器连接失败");
  }
}

void loop() {
  if (tcpClient.connected()) {
    // ----- TCP → 串口 -----
    if (tcpClient.available()) {
      char c = tcpClient.read();
      Serial.write(c);      // 转发到串口
    }
    
    // ----- 串口 → TCP -----
    if (Serial.available()) {
      char c = Serial.read();
      tcpClient.write(c);   // 转发到 TCP 服务器
    }
  } else {
    // 断线重连
    Serial.println("TCP 连接断开,尝试重连...");
    tcpClient.stop();
    delay(1000);
    if (tcpClient.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
      Serial.println("重新连接成功!");
    }
  }
}

7. 示例 3:两个 UNO R4 WiFi 之间通过 TCP 通信

架构说明

┌──────────────────┐          TCP 连接         ┌──────────────────┐
│   UNO R4 WiFi    │  ──────────────────────► │   UNO R4 WiFi    │
│   (TCP Server)   │  192.168.1.101:1470    │   (TCP Client)   │
│  传感器采集       │  发送传感器数据           │  接收并处理       │
└──────────────────┘                          └──────────────────┘

7.1 TCP 服务器端(数据发布方)

cpp
#include <WiFiS3.h>

const char* WIFI_SSID = "你的WiFi名称";
const char* WIFI_PASSWORD = "你的WiFi密码";
const int TCP_PORT = 1470;

WiFiServer server(TCP_PORT);
WiFiClient client;

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

  // 连接 WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  Serial.println("WiFi 已连接!IP: " + WiFi.localIP().toString());

  // 启动 TCP 服务器
  server.begin();
  Serial.print("TCP 服务器已启动,端口: ");
  Serial.println(TCP_PORT);
}

void loop() {
  // 等待客户端连接
  client = server.available();
  
  if (client) {
    Serial.println("客户端已连接!");
    
    while (client.connected()) {
      // 模拟读取传感器数据
      float temperature = 25.0 + random(-10, 10) * 0.1;
      float humidity = 60.0 + random(-15, 15) * 0.1;
      
      // 格式:温度,湿度
      String data = String(temperature, 1) + "," + String(humidity, 1);
      
      // 发送数据到客户端
      client.println(data);
      
      Serial.print("已发送: ");
      Serial.println(data);
      
      delay(2000);  // 每 2 秒发送一次
    }
    
    client.stop();
    Serial.println("客户端已断开");
  }
}

7.2 TCP 客户端(数据接收方)

cpp
#include <WiFiS3.h>

const char* WIFI_SSID = "你的WiFi名称";
const char* WIFI_PASSWORD = "你的WiFi密码";
const char* TCP_SERVER_ADDR = "192.168.1.101";  // 服务器端的 IP
const int TCP_SERVER_PORT = 1470;

WiFiClient tcpClient;

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

  // 连接 WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  Serial.println("WiFi 已连接!IP: " + WiFi.localIP().toString());

  // 连接 TCP 服务器
  connectToServer();
}

void connectToServer() {
  if (tcpClient.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
    Serial.println("已连接到 TCP 服务器!");
  } else {
    Serial.println("连接服务器失败,5 秒后重试...");
    delay(5000);
    connectToServer();
  }
}

void loop() {
  if (tcpClient.connected()) {
    // 接收服务器数据
    if (tcpClient.available()) {
      String data = tcpClient.readStringUntil('\n');
      data.trim();
      
      Serial.print("收到数据: ");
      Serial.println(data);
      
      // 解析数据:温度,湿度
      int commaIndex = data.indexOf(',');
      if (commaIndex > 0) {
        String temp = data.substring(0, commaIndex);
        String humi = data.substring(commaIndex + 1);
        Serial.print("  温度: ");
        Serial.print(temp);
        Serial.print("°C, 湿度: ");
        Serial.print(humi);
        Serial.println("%");
      }
    }
  } else {
    Serial.println("服务器连接断开,尝试重连...");
    tcpClient.stop();
    delay(5000);
    connectToServer();
  }
}

8. 常用测试工具

工具平台用途
netcat (nc)Linux/macOS/Windows命令行 TCP 测试
ezTermWindows图形化 TCP 服务器/客户端
Putty全平台串口和 TCP 连接测试
Python socket全平台自定义 TCP 服务端测试脚本

9. 常见问题排查

问题可能原因解决方法
WiFi 连接失败SSID/密码错误确认 WiFi 名称和密码,确保为 2.4GHz 网络
TCP 连接失败服务器 IP/端口错误确认服务器 IP 和端口,检查防火墙
连接后立即断开服务器端主动关闭检查服务器端程序是否保持监听
数据接收乱码编码不一致统一使用 ASCII 或 UTF-8 编码
长时间运行后无响应连接超时增加心跳包或重连机制
编译错误 WiFiS3.h not found未安装 R4 支持包在开发板管理器中安装 "Arduino UNO R4 WiFi"

10. 进阶参考

  • Web Server 模式:UNO R4 WiFi 可以作为 Web 服务器,通过浏览器 HTTP 请求控制设备
  • 固件升级:通过 工具 → 固件更新器 更新 ESP32-S3 模块固件
  • 更多示例:在 Arduino IDE 中打开 文件 → 示例 → WiFiS3 查看官方示例程序