基于ESP8266的无线温湿度网关IP配置及串口数据不显示问题求助
核心问题排查
你的代码存在4个直接导致功能失效的错误:
- 网络配置完全不匹配:网关设置的静态IP为
192.168.1.29,TCP服务监听端口为80,但传感器节点代码里写的目标服务IP是192.168.1.28,连接端口为29,地址和端口全不对应,根本无法建立TCP连接。 - 网关地址配置错误:代码中填写的网关地址为
192.168.1.80,常规局域网默认网关为192.168.1.1,80是常用服务端口,不可能作为网关地址的主机位,该配置会导致ESP8266无法正常完成局域网路由转发。 - 串口资源冲突:网关硬件串口
Serial同时被用于Nextion屏幕通信和电脑端调试日志输出,且Nextion默认通信波特率为9600,你代码里设置的115200波特率本身就和屏幕不匹配,串口监视器看到的只会是发给屏幕的二进制控制指令,不可能显示正常的温湿度数值。 - 数据收发逻辑缺陷:网关侧用
readStringUntil('\r')分两次隔500ms读取数据,传感器侧用client.println()发送的行尾标识为\r\n,加上TCP传输存在粘包问题,往往第一次读取就会把两行数据全部读完,第二次读取为空,最终解析出的温湿度数值为0。
修正方案
- 统一网络参数
- 先确认你所在局域网的实际网关地址(可登录路由器后台查看,绝大多数默认是
192.168.1.1),替换网关代码里的gateway参数。 - 统一两端IP和端口:网关固定使用
192.168.1.29、监听80端口的话,传感器侧的目标IP要改成192.168.1.29,连接端口改成80,两边参数必须完全一致。
- 先确认你所在局域网的实际网关地址(可登录路由器后台查看,绝大多数默认是
- 解决串口冲突
调试阶段先拔掉Nextion屏幕,单独用串口打印调试日志,确认网络传输正常后再接屏幕;如果要同时使用屏幕和调试功能,需要给Nextion屏幕单独接软件串口,不要和调试串口共用硬件Serial接口。接屏幕时记得把串口波特率改成和屏幕一致(默认9600)。 - 优化数据收发逻辑
传感器侧把温湿度数据用逗号拼接成一行发送,网关侧一次读取整行后按分隔符拆分解析,避免粘包、半包导致的解析失败;传感器发送数据前先判断连接状态,连接失败时主动释放客户端资源,不要硬发数据。
修正后的网关代码
#include <ESP8266WiFi.h> float temps; float hums; String request; String data; char ssid[] = "my/net"; // 替换为实际WiFi名称 char pass[] = "my/pass"; // 替换为实际WiFi密码 WiFiServer server(80); IPAddress ip(192, 168, 1, 29); IPAddress gateway(192, 168, 1, 1); // 替换为实际网关地址 IPAddress subnet(255, 255, 255, 0); void setup() { // 接Nextion屏时波特率改为9600,调试阶段可临时设为115200 Serial.begin(9600); WiFi.config(ip, gateway, subnet); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("Connected, IP address: "); Serial.println(WiFi.localIP()); server.begin(); } void loop() { WiFiClient client = server.available(); if (client) { if (client.connected()) { request = client.readStringUntil('\n'); request.trim(); int splitPos = request.indexOf(','); if (splitPos > 0) { hums = request.substring(0, splitPos).toFloat(); temps = request.substring(splitPos + 1).toFloat(); // 调试阶段打开下行注释打印日志,接屏幕时注释掉避免输出乱码 // Serial.printf("Received: Humidity=%.1f%%, Temp=%.1fC\n", hums, temps); } } client.stop(); NextionData(); } } void NextionData() { data = "temps.txt=\"" + String(temps, 1) + "\""; Serial.print(data); Serial.write(0xff); Serial.write(0xff); Serial.write(0xff); data = "hums.txt=\"" + String(hums, 1) + "\""; Serial.print(data); Serial.write(0xff); Serial.write(0xff); Serial.write(0xff); }
修正后的传感器节点代码
#include "Wire.h" #include "SparkFunBME280.h" #include <ESP8266WiFi.h> char ssid[] = "my/net"; // 替换为实际WiFi名称 char pass[] = "my/pass"; // 替换为实际WiFi密码 IPAddress server(192, 168, 1, 29); // 和网关IP保持一致 WiFiClient client; BME280 mySensor; float hums; float temps; void setup() { Serial.begin(115200); Wire.begin(); Wire.setClock(400000); mySensor.setI2CAddress(0x76); mySensor.beginI2C(); WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("Connected, IP address: "); Serial.println(WiFi.localIP()); } void loop(){ hums = mySensor.readFloatHumidity(); temps = mySensor.readTempC(); Serial.print("Humidity: "); Serial.print(hums, 2); Serial.print(" Temp: "); Serial.print(temps, 2); Serial.println(); if (client.connect(server, 80)) { // 端口和网关服务端口保持一致 client.print(hums, 2); client.print(","); client.println(temps, 2); client.flush(); client.stop(); } else { Serial.println("Connect to gateway failed"); client.stop(); } delay(2000); }
内容的提问来源于stack exchange,提问作者Kishor
相关产品推荐
相关产品推荐

