UDP消息触发IF语句失效问题及变量比较方案咨询
问题分析与解决:UDP报文参数匹配失败
你遇到的问题其实是个典型的变量作用域陷阱——你在loop()里重新定义了一个和全局变量同名的局部UdpMsg,导致全局变量根本没被更新,始终停留在初始值"12345",自然永远匹配不上"relay01_off"。
问题细节拆解
看你代码里的这段逻辑:
if(udp.read(buffer, 50) > 0){ Serial.print("Recevied UDP: "); Serial.println((char *)buffer); String UdpMsg ((char *)buffer); // 这里是局部变量,和全局的UdpMsg没关系! }
这里创建的UdpMsg是loop()函数内的局部变量,当这个代码块执行结束后,这个局部变量就被销毁了,全局的UdpMsg完全没被修改。所以后面的if (UdpMsg == "relay01_off")判断的始终是初始的"12345",当然不会触发继电器。
修复方案
去掉局部变量定义,直接更新全局变量
把局部的String UdpMsg ((char *)buffer);改成给全局变量赋值:UdpMsg = String((char *)buffer);处理UDP报文的隐藏空白字符
很多UDP发送工具会自动在报文末尾加换行符或回车符,这些看不见的字符会导致字符串匹配失败。建议在赋值后调用trim()方法去除首尾空白:UdpMsg = String((char *)buffer).trim();
修改后的完整代码
#include <WiFi.h> #include <WiFiUdp.h> #include <cstring> //For the string functions const char* wifi_name = "SSID"; // Your Wifi network name here const char* wifi_pass = "password"; // Your Wifi network password here WiFiServer server(80); // Server will be at port 80 // IP address to send UDP data to. const char * udpAddress = "192.168.1.6"; int udpPort = 4444; //create UDP instance WiFiUDP udp; // relay PIN int relay_pin = 15; // UDP Message storage (global variable) String UdpMsg = "12345"; void setup() { Serial.begin (115200); pinMode (relay_pin, OUTPUT); Serial.print ("Connecting to "); Serial.print (wifi_name); WiFi.begin (wifi_name, wifi_pass); // Connecting to the wifi network while (WiFi.status() != WL_CONNECTED) // Waiting for the response of wifi network { delay (500); Serial.print ("."); } Serial.println(""); Serial.println("Connection Successful"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); // Getting the IP address Serial.println("Type the above IP address into browser search bar"); server.begin(); // Starting the server digitalWrite(relay_pin, LOW); // switch to AC //This initializes udp and transfer buffer udp.begin(udpPort); } void loop() { uint8_t buffer[50] = {0}; // 初始化buffer为0,避免残留数据 //processing incoming packet, must be called before reading the buffer int packetSize = udp.parsePacket(); //receive response from server if(packetSize > 0 && udp.read(buffer, 50) > 0){ Serial.print("Received UDP: "); Serial.println((char *)buffer); // 更新全局变量,同时去除首尾空白 UdpMsg = String((char *)buffer).trim(); // 调试:打印全局变量的内容和长度,确认是否正确 Serial.print("Global UdpMsg: "); Serial.println(UdpMsg); Serial.print("UdpMsg length: "); Serial.println(UdpMsg.length()); } //////// UDP 判断逻辑 /////////// if (UdpMsg == "relay01_off") { // 匹配成功 digitalWrite(relay_pin, HIGH); Serial.println("You!"); } }
额外调试建议
如果还是匹配失败,可以在判断前打印UdpMsg的长度和每个字符的ASCII码,看看是不是有隐藏字符:
Serial.print("UdpMsg chars: "); for(int i=0; i<UdpMsg.length(); i++){ Serial.print((int)UdpMsg[i]); Serial.print(" "); } Serial.println();
比如如果报文末尾有换行符(ASCII 10),trim()会帮你去掉,但如果有其他特殊字符,你可以针对性处理。
内容的提问来源于stack exchange,提问作者G Flame
相关产品推荐
相关产品推荐

