0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

零知IDE——基于STM32与W5500的UDP通信实现温湿度监控

零知实验室 来源:PCB56242069 作者:PCB56242069 2026-02-28 15:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

​ ✔零知开源(零知IDE)是一个专为电子初学者/电子兴趣爱好者设计的开源软硬件平台,在硬件上提供超高性价比STM32系列开发板、物联网控制板。取消了Bootloader程序烧录,让开发重心从“配置环境”转移到“创意实现”,极大降低了技术门槛。零知IDE编程软件,内置上千个覆盖多场景的示例代码,支持项目源码一键下载,项目文章在线浏览。零知开源(零知IDE)平台通过软硬件协同创新,让你的创意快速转化为实物,来动手试试吧!

✔访问零知实验室,获取更多实战项目和教程资源吧!

www.lingzhilab.com

项目概述

本项目基于零知增强板(主控STM32F407VET6)结合W5500以太网模块,实现了一套完整的UDP通信温湿度监控系统。系统通过DHT11传感器实时采集环境温湿度数据,通过W5500以太网模块建立UDP通信链路,将数据发送至PC上位机。同时,上位机可通过UDP协议发送控制指令,远程控制开发板上的LED灯开关状态

项目难点及解决方案

问题描述:多网卡路由冲突导致路由表混乱,UDP包丢失

解决方案:网段隔离与静态配置,将网络拓扑从混合网段改为独立网段;代码中禁用DHCP功能,网关和DNS强制指向PC的以太网IP;同时网段检测逻辑

一、系统硬件部分

1.1 元件清单

硬件名称 数量 备注
零知增强板(STM32F407VET6) 1 主控核心板
W5500 以太网模块 1 带 SPI 接口的以太网模块
DHT11 温湿度传感器 1 数字型温湿度传感器
LED 发光二极管 1 用于远程控制演示
10K 上拉电阻 1 DHT11 数据脚需接
杜邦线 若干 连接各模块
网线 1 PC 与 W5500 直连
PC(带以太网口) 1 运行 Python 上位机

1.2 接线方案表

请务必严格按照代码中的定义进行连接,否则会导致初始化失败。

零知增强板引脚 外接设备 设备引脚 功能说明
7 DHT11 DATA 温湿度数据传输
8 LED 正极 LED 控制引脚(低电平熄灭)
GND DHT11/LED/W5500 GND 公共接地
5V W5500/DHT11 5V / + 供电(W5500 需 5V)
3.3V 可选 DHT11 (+) DHT11 也可接 3.3V
A5 (SCLK) W5500 SCLK SPI 时钟线
A6 (MISO) W5500 MISO SPI 主机输入 / 从机输出
A7 (MOSI) W5500 MOSI SPI 主机输出 / 从机输入
A4 (SCS) W5500 CS W5500 片选引脚

1.3 接线示意图

wKgZO2mihGeAdPofAAL7J-GWgn0512.png

W5500 的 SPI 接线必须严格对应零知增强板 的 SPI 引脚(SCK/MISO/MOSI/CS)

1.4 实物连接图

wKgZPGmihGqAJm-OAAHDpmOJff4944.png

二、安装与使用部分

2.1 开源平台-输入"W5500的UDP通信"并搜索-代码下载自动打开

wKgZPGmihKOAV5jJAAH2rQYRbIQ254.png

2.2 连接-验证-上传

wKgZPGmihKqATLHYAAMaMkf-JbY751.png

2.3 调试-串口监视器

wKgZO2mihK-AanV3AANXu1QQwrE695.png

三、核心代码讲解

本项目的代码设计体现了模块化和健壮性的特点,以下将对核心的四个部分进行详细剖析

3.1网络初始化与配置

网络初始化是本项目的核心,采用PC直连静态IP模式,确保通信稳定

// ==================== 网络配置 - PC直连模式 ====================
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

// 静态IP配置
IPAddress staticIP(192, 168, 10, 22);      // W5500的IP
IPAddress gateway(192, 168, 10, 1);        // 设为PC的以太网卡IP
IPAddress subnet(255, 255, 255, 0);        
IPAddress dnsip(192, 168, 10, 1);          // DNS指向PC

// PC的以太网卡IP
IPAddress pcIP(192, 168, 10, 17);

// 网络初始化函数
void initNetwork() {
  // 静态IP配置
  Ethernet.begin(mac, staticIP, dnsip, gateway, subnet);
  
  // 验证网络配置
  IPAddress ip = Ethernet.localIP();
  if (ip == IPAddress(0, 0, 0, 0)) {
    Serial.println("✗✗✗ 错误: 以太网初始化失败! ✗✗✗");
    // 错误处理...
  }
  
  // 启动UDP服务
  Udp.begin(localPort);
}

PC以太网卡不提供DHCP服务,必须使用静态IP;网关设置指向PC,点对点直连网络

3.2DHT11数据采集与处理

DHT11传感器数据采集需要精确的时序控制,并处理可能的读取失败情况

// DHT11初始化
DHT dht(DHTPIN, DHTTYPE);

// 读取DHT数据函数
void readDHTData() {
  unsigned long currentTime = millis();
  
  // 每10秒读取一次
  if (currentTime - lastDHTReadTime >= 10000) {
    lastDHTReadTime = currentTime;
    
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    
    if (isnan(h) || isnan(t)) {
      Serial.println("✗ DHT11读取失败!");
      dhtValid = false;
    } else {
      humidity = h;
      temperature = t;
      dhtValid = true;
      
      // 发送数据
      sendDHTData();
    }
  }
}

// 发送DHT数据函数
void sendDHTData() {
  if (dhtValid) {
    messageCount++;
    
    char tempStr[10];
    char humiStr[10];
    floatToString(tempStr, temperature, 2);  // 2位小数精度
    floatToString(humiStr, humidity, 2);
    
    // 构建JSON格式数据
    snprintf(sendBuffer, sizeof(sendBuffer),
             "{"type":"dht","count":%lu,"temp":%s,"humi":%s,"time":%lu}",
             messageCount, tempStr, humiStr, millis() / 1000);
    
    sendUDP(sendBuffer);
  }
}

DHT11设置为10秒的读取间隔,使用自定义floatToString()函数处理浮点数

3.3 UDP通信协议解析

实现简单的命令解析机制,支持多种控制指令

// 协议解析函数
void parseCommand(const char* cmd, IPAddress remoteIP, int remotePort) {
  // LED_ON命令
  if (strcmp(cmd, "LED_ON") == 0) {
    digitalWrite(LED_CONTROL_PIN, HIGH);
    ledControlState = true;
    
    snprintf(sendBuffer, sizeof(sendBuffer),
             "{"type":"response","cmd":"LED_ON","status":"success","led_state":true}");
    
    Udp.beginPacket(remoteIP, remotePort);
    Udp.write((uint8_t*)sendBuffer, strlen(sendBuffer));
    Udp.endPacket();
  }
  // GET_DHT命令
  else if (strcmp(cmd, "GET_DHT") == 0) {
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    
    if (isnan(h) || isnan(t)) {
      snprintf(sendBuffer, sizeof(sendBuffer),
               "{"type":"response","cmd":"GET_DHT","status":"error","error":"read_failed"}");
    } else {
      char tempStr[10];
      char humiStr[10];
      floatToString(tempStr, t, 2);
      floatToString(humiStr, h, 2);
      
      snprintf(sendBuffer, sizeof(sendBuffer),
               "{"type":"response","cmd":"GET_DHT","status":"success","temp":%s,"humi":%s}",
               tempStr, humiStr);
    }
    
    Udp.beginPacket(remoteIP, remotePort);
    Udp.write((uint8_t*)sendBuffer, strlen(sendBuffer));
    Udp.endPacket();
  }
  // 其他命令处理...
}

支持的命令列表

指令 功能说明 返回信息
LED_ON 点亮LED 返回成功状态和LED状态
LED_OFF 熄灭LED 返回成功状态和LED状态
GET_DHT 读取实时温湿度 返回数据或错误信息
STATUS 获取设备完整状态信息 返回设备状态

每个命令都有明确的成功/失败状态返回,接收到命令后立即处理并返回结果

3.4系统状态维护与心跳机制

系统需要维护多个状态变量,并实现心跳机制确保连接正常

// 全局状态变量
unsigned long lastDHTReadTime = 0;    // 上次DHT读取时间
unsigned long lastSendTime = 0;       // 上次发送时间
unsigned long messageCount = 0;       // 消息计数器
unsigned long lastHeartbeat = 0;      // 上次心跳时间

bool dhtValid = false;                // DHT数据有效性
bool ledControlState = false;         // LED控制状态
bool networkInitialized = false;      // 网络初始化状态

unsigned long packetsSent = 0;        // 发送数据包计数
unsigned long packetsReceived = 0;    // 接收数据包计数

// 心跳包发送函数
void sendHeartbeat() {
  unsigned long currentTime = millis();
  
  if (currentTime - lastHeartbeat >= 30000) {  // 每30秒
    lastHeartbeat = currentTime;
    
    snprintf(sendBuffer, sizeof(sendBuffer),
             "{"type":"heartbeat","uptime":%lu,"packets_sent":%lu,"packets_received":%lu}",
             millis() / 1000, packetsSent, packetsReceived);
    sendUDP(sendBuffer);
  }
}

// 状态LED指示函数
void updateStatusLED() {
  unsigned long currentTime = millis();
  
  if (currentTime - lastBlinkTime >= 500) {  // 每500ms闪烁一次
    lastBlinkTime = currentTime;
    ledBlinkState = !ledBlinkState;
    digitalWrite(LED_BUILTIN, ledBlinkState ? LOW : HIGH);
  }
}

统计发送和接收的数据包数量,用于监控通信质量;定期发送心跳包,让上位机知道设备在线状态

3.5 系统完整代码

/**************************************************************************************
 * 文件: W5500_UDP_DHT11_Control.ino
 * 作者:零知实验室(深圳市在芯间科技有限公司)
 * -^^- 零知实验室,让电子制作变得更简单! -^^-
 * 时间: 2026-02-09
 * 网络拓扑:
 *   路由器(192.168.3.1) ←WiFi→ PC(WiFi: 192.168.3.17, 以太网: 192.168.10.1)
 *                                    ↓ 直连网线
 *                               W5500(192.168.10.22)
 * 
 * 功能说明:
 * W5500以太网模块UDP通信、DHT11温湿度传感器数据采集和上报、远程LED控制功能、简单协议解析和响应、修复JSON浮点数格式化问题(snprintf不支持%f)
 ************************************************************************************/

#include < SPI.h >
#include < Ethernet_STM.h >
#include < EthernetUdp.h >
#include "DHT.h"

// ==================== 硬件配置 ====================
#define DHTPIN 7
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

#define LED_CONTROL_PIN 8


// ==================== 网络配置 - PC直连模式 ====================
#if defined(WIZ550io_WITH_MACADDRESS)
  // WIZ550io有内置MAC地址
#else
  byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
#endif

//  PC直连模式 - 必须使用静态IP!
// PC的以太网卡不提供DHCP服务,所以DHCP无法工作
#define USE_DHCP false

// ==================== 重要: 网段配置说明 ====================
// 使用 192.168.10.x 网段,与PC的WiFi网段(192.168.3.x)分开
// 避免IP冲突和路由混乱

// 静态IP配置
IPAddress staticIP(192, 168, 10, 22);      // W5500的IP
IPAddress gateway(192, 168, 10, 1);        // 设为PC的以太网卡IP
IPAddress subnet(255, 255, 255, 0);        
IPAddress dnsip(192, 168, 10, 1);          // DNS指向PC

// PC的以太网卡IP (连接W5500的那个网卡)
//  不是WiFi的IP (192.168.3.17)!
IPAddress pcIP(192, 168, 10, 17);

// UDP端口
unsigned int localPort = 8888;
unsigned int pcPort = 9003;

// ==================== 如果您的PC以太网卡IP是其他值 ====================
// 请相应修改上面的配置,例如:
// 
// 如果PC以太网卡是 192.168.137.1 (启用了ICS):
//   IPAddress staticIP(192, 168, 137, 22);
//   IPAddress gateway(192, 168, 137, 1);
//   IPAddress dnsip(192, 168, 137, 1);
//   IPAddress pcIP(192, 168, 137, 1);
//
// 如果PC以太网卡是 192.168.3.215 (不推荐,会与WiFi冲突):
//   IPAddress staticIP(192, 168, 3, 22);
//   IPAddress gateway(192, 168, 3, 215);  // 指向PC,不是路由器!
//   IPAddress dnsip(192, 168, 3, 215);
//   IPAddress pcIP(192, 168, 3, 215);


// ==================== 全局变量 ====================
EthernetUDP Udp;
char receiveBuffer[256];
char sendBuffer[512];

// 定时器
unsigned long lastDHTReadTime = 0;
unsigned long lastSendTime = 0;
unsigned long messageCount = 0;
unsigned long lastHeartbeat = 0;

// DHT数据
float temperature = 0.0;
float humidity = 0.0;
bool dhtValid = false;

// LED状态
bool ledControlState = false;
unsigned long lastBlinkTime = 0;
bool ledBlinkState = false;

// 网络状态
bool networkInitialized = false;
unsigned long lastSuccessTime = 0;
unsigned long packetsSent = 0;
unsigned long packetsReceived = 0;


// ==================== 函数声明 ====================
void floatToString(char* buffer, float value, int decimalPlaces);


// ==================== 浮点数转字符串 ====================
void floatToString(char* buffer, float value, int decimalPlaces) {
  int intPart = (int)value;
  int decPart = (int)((value - intPart) * pow(10, decimalPlaces));
  
  if (decPart < 0) decPart = -decPart;
  
  if (decimalPlaces == 1) {
    sprintf(buffer, "%d.%01d", intPart, decPart);
  } else if (decimalPlaces == 2) {
    sprintf(buffer, "%d.%02d", intPart, decPart);
  }
}


// ==================== 初始化 ====================
void setup() {
  Serial.begin(115200);
  delay(100);
  
  Serial.println("nn");
  Serial.println("========================================");
  Serial.println("  W5500 UDP + DHT11温湿度监控系统");
  Serial.println("  零知实验室");
  Serial.println("  版本: v3.1 (PC直连专用版)");
  Serial.println("========================================n");
  
  Serial.println("  网络模式: PC直连(静态IP)");
  Serial.println("  请确保PC的以太网卡已配置静态IP!n");
  
  initHardware();
  initNetwork();
  initDHT();
  
  Serial.println("n========================================");
  Serial.println("系统启动完成!");
  Serial.println("========================================n");
  
  printSystemInfo();
  sendStartupMessage();
  
  Serial.println("n开始工作...n");
  Serial.println("----------------------------------------n");
}


// ==================== 硬件初始化 ====================
void initHardware() {
  Serial.println("[1/3] 初始化硬件...");
  
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  
  pinMode(LED_CONTROL_PIN, OUTPUT);
  digitalWrite(LED_CONTROL_PIN, LOW);
  ledControlState = false;
  
  // 启动提示 - LED快闪3次
  for(int i = 0; i < 3; i++) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
  }
  
  Serial.println("✓ 硬件初始化完成!");
}


// ==================== 网络初始化 ====================
void initNetwork() {
  Serial.println("n[2/3] 初始化W5500以太网模块...");
  Serial.println("  模式: 静态IP (PC直连)");
  delay(500);
  
  // 静态IP配置
  #if defined(WIZ550io_WITH_MACADDRESS)
    Ethernet.begin(staticIP, dnsip, gateway, subnet);
  #else
    Ethernet.begin(mac, staticIP, dnsip, gateway, subnet);
  #endif
  
  delay(1000);
  
  // 验证网络配置
  IPAddress ip = Ethernet.localIP();
  
  if (ip == IPAddress(0, 0, 0, 0)) {
    Serial.println("n✗✗✗ 错误: 以太网初始化失败! ✗✗✗");
    Serial.println("n请检查:");
    Serial.println("  1. W5500模块SPI接线是否正确");
    Serial.println("  2. 网线是否连接到PC的以太网口");
    Serial.println("  3. PC的以太网卡是否已配置静态IP");
    Serial.println("n设备将进入错误指示模式");
    
    while(1) {
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      delay(100);
    }
  }
  
  Serial.println("n✓ W5500初始化成功!");
  Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
  Serial.print("  本机IP:   ");
  Serial.println(ip);
  Serial.print("  子网掩码: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("  网关:     ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("  DNS:      ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.println("  模式:     静态IP (PC直连)");
  Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
  
  // 显示PC配置提示
  Serial.println("n


审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2313

    文章

    11195

    浏览量

    374673
  • UDP
    UDP
    +关注

    关注

    0

    文章

    335

    浏览量

    35529
  • 湿度监控
    +关注

    关注

    0

    文章

    5

    浏览量

    5330
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    IDE——基于STM32W5500UDP通信实现温湿度监控

    以太网模块,实现了一套完整的UDP通信温湿度监控系统。系统通过DHT11传感器实时采集环境温湿度
    发表于 02-28 16:08

    模块化扩展:多机房以太网 POE 温湿度监控部署方案

    @ 以太网 POE 供电温湿度传感器变送器在多机房温湿度监控中的应用方案 机房 一、项目背景与核心需求 随着楼宇智能化、数据中心集群化发展,企业、高校、园区等场景普遍存在多个分散机房(如办公楼机房
    的头像 发表于 01-21 16:46 858次阅读

    冷库温湿度监控系统物联网解决方案

    冷库作为生鲜食品、医药试剂、化工原料等物资的核心存储载体,温湿度的稳定性直接决定物资品质与安全。传统冷库温湿度管理存在诸多痛点:人工巡检效率低、误差大,难以实现 24 小时全覆盖监测;温湿度
    的头像 发表于 01-19 16:57 723次阅读

    科研实验室以太网POE供电温湿度监控系统方案

    可能导致实验数据失真、样品失效、设备损坏等严重后果。传统监控方式存在布线复杂、供电不便、数据传输延迟、维护成本高等问题,而以太网 POE(Power over Ethernet)技术可实现 “一线双用”(同时传输数据与电力),结合高精度
    的头像 发表于 12-18 14:35 1753次阅读
    科研实验室以太网POE供电<b class='flag-5'>温湿度</b><b class='flag-5'>监控</b>系统方案

    STM32驱动W5500作为客户端进行通讯

    SR-ES1内嵌Wiznet的W5500芯片,使用硬件逻辑门电路实现TCP/IP协议栈的传输层及网络层(如:TCP,UDP,ICMP,IPv4,ARP,IGMP,PPPoE等协议),并集成了数据链
    的头像 发表于 10-14 17:19 1526次阅读
    <b class='flag-5'>STM32</b>驱动<b class='flag-5'>W5500</b>作为客户端进行通讯

    MCU无法检测到W5500是怎么回事?

    在兆易创新 GD32F303,国民技术 N32G457和ST STM32F103上试用了W5500以太网模块(RT-Thread版本是rt-thread-4.1.1), 只有STM32F103上可以
    发表于 10-14 07:38

    使用w5500通信使用wiz包的时候,突然拔掉网线,如何释放网络资源?

    我用wiz包,使用w5500进行网络通信,对接到但是socket此时已经建立,正在通信,如果此时突然拔掉网线,因为本身使用非阻塞。所以我这边可以通过netdev_is_link_up检测到网线断开
    发表于 10-11 09:01

    冷库温湿度物联网监控系统解决方案:冷链智能化

    实现冷库温湿度的实时、远程监控,减少人工巡检工作量,管理人员可同时管理多个冷库,提高工作效率。
    的头像 发表于 08-07 11:52 865次阅读

    开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

    目基于STM32F407VET6增强板,实现SHT41高精度温湿度传感器的驱动和数据采集。SHT41是Sensirion推出的新一代数字
    发表于 07-10 12:01

    开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

    摘要:本项目基于STM32F407VET6增强板驱动SHT41高精度温湿度传感器,实现±0.2℃温度精度和±1.8%RH
    的头像 发表于 07-09 18:53 1889次阅读
    <b class='flag-5'>零</b><b class='flag-5'>知</b>开源——<b class='flag-5'>STM32</b>F407VET6驱动SHT41<b class='flag-5'>温湿度</b>传感器完整教程

    一款适用于粉尘、易结露等恶劣环境温湿度监控中的温湿度传感芯片

    温湿度监控系统在恶劣环境中通过传感器实时监测温湿度参数,当达到预设阈值时自动触发预警或调节机制,确保环境状态维持在安全范围内。
    的头像 发表于 07-09 09:41 883次阅读
    一款适用于粉尘、易结露等恶劣环境<b class='flag-5'>温湿度</b><b class='flag-5'>监控</b>中的<b class='flag-5'>温湿度</b>传感芯片

    物联网温湿度监控系统

    物联网温湿度监控系统作为现代智能化管理的重要工具,已广泛应用于农业温室、医药仓储、数据中心、食品冷链等多个领域。其核心价值在于通过实时数据采集、智能分析和远程控制,实现对环境参数的精准管理,从而保障
    的头像 发表于 07-07 17:36 1353次阅读

    温湿度变送器功能有哪些?一文详细解析

    数据,帮助用户及时了解环境状况。 二、数据传输与远程监控 温湿度变送器可以将测量到的温湿度数据通过多种方式进行传输,如模拟信号、数字信号等。用户可以将变送器与监控系统相连,
    发表于 06-03 10:56

    智能仓储:温湿度监控方案应用

    随着仓储环境要求提高,温湿度监控对保障货物品质至关重要。本文介绍一个工厂仓库温湿度监控方案,利用温湿度变送器、LoRa技术和智能监测平台,为
    的头像 发表于 05-29 11:35 924次阅读
    智能仓储:<b class='flag-5'>温湿度</b><b class='flag-5'>监控</b>方案应用

    w5500随机出现接收问题

    我现在用STM32F103CBT6与W5500作为TCP Server,多台PC与服务器连接上后,服务器会实时传输数据到PC上,并且PC随时能通过控制软件发送数据至服务器。但是运行一段时间后,PC上
    发表于 05-15 09:45