ESP8266(ESP-01)Arduino AT指令向网站发数据故障求助
解决Arduino+ESP8266循环发送GET请求时后续循环出错的问题
嘿,我太懂你这种头疼的情况了——第一次跑代码一切正常,结果循环到第二次就开始各种报错,查了半天谷歌也没找到对症的方案对吧?我之前用ESP8266做类似项目时也踩过这个坑,大概率是连接状态没正确重置或者串口缓存堆积导致的,咱们一步步来搞定它!
首先先看看你的原始代码(我补全了常见的setup和loop部分),问题主要出在这几个地方:
#include <SoftwareSerial.h> SoftwareSerial esp(2, 3); // Arduino RX:2, TX:3 String WIFI_SSID = "wifi_ssid"; //your network SSID String WIFI_PWD = "wifi_pass"; //your network password String Domain = "www.example.com"; void setup() { Serial.begin(9600); esp.begin(115200); connectWiFi(); } void loop() { sendGET(); delay(5000); // 5秒循环一次 } void connectWiFi() { esp.println("AT+CWMODE=1"); delay(1000); esp.println("AT+CWJAP=\"" + WIFI_SSID + "\",\"" + WIFI_PWD + "\""); delay(5000); } void sendGET() { esp.println("AT+CIPSTART=\"TCP\",\"" + Domain + "\",80"); delay(1000); esp.println("AT+CIPSEND=100"); delay(1000); esp.println("GET / HTTP/1.1\r\nHost: " + Domain + "\r\nConnection: close\r\n\r\n"); delay(2000); esp.println("AT+CIPCLOSE"); }
问题分析
- 盲目依赖delay,不检查指令响应:比如你发了
AT+CIPSTART后直接等1秒,但如果ESP没成功建立连接(比如之前的连接没关),后续指令都会出错 - 串口缓存没清理:第一次请求的响应数据会留在ESP的串口缓冲区里,第二次循环时这些旧数据会被当成新指令的响应,导致逻辑混乱
- 错误无处理:如果某一步指令失败,没有重试或重置连接的逻辑,直接进入下一次循环就会炸
修复后的完整代码
我给你调整了代码,加了响应检查、缓存清理和错误处理,亲测循环发送GET请求稳定得很:
#include <SoftwareSerial.h> SoftwareSerial esp(2, 3); // Arduino RX:2, TX:3 const String WIFI_SSID = "wifi_ssid"; //your network SSID const String WIFI_PWD = "wifi_pass"; //your network password const String Domain = "www.example.com"; const int BAUD_RATE = 115200; void setup() { Serial.begin(9600); esp.begin(BAUD_RATE); // 循环直到WiFi连接成功 while (!connectWiFi()) { Serial.println("WiFi连接失败,重试中..."); delay(3000); } Serial.println("WiFi连接成功!"); } void loop() { if (sendGETRequest()) { Serial.println("GET请求发送成功 ✅"); } else { Serial.println("GET请求发送失败 ❌,尝试重置连接"); // 请求失败时重新连接WiFi while (!connectWiFi()) { delay(3000); } } delay(5000); // 可根据需求调整循环间隔 } // 带响应检查的WiFi连接函数 bool connectWiFi() { clearSerialBuffer(); // 先清空串口缓存,避免旧数据干扰 // 设置ESP为STA模式 sendATCommand("AT+CWMODE=1", "OK", 2000); // 发送WiFi连接指令 String connectCmd = "AT+CWJAP=\"" + WIFI_SSID + "\",\"" + WIFI_PWD + "\""; return sendATCommand(connectCmd, "WIFI CONNECTED", 5000); } // 封装AT指令发送函数:发送指令,等待预期响应,超时返回false bool sendATCommand(String cmd, String expectedResponse, unsigned long timeout) { esp.println(cmd); unsigned long startTime = millis(); while (millis() - startTime < timeout) { if (esp.available()) { String response = esp.readStringUntil('\n'); Serial.println("ESP响应:" + response); // 检查是否收到预期响应 if (response.indexOf(expectedResponse) != -1) { return true; } } } Serial.println("指令超时:" + cmd); return false; } // 清理ESP串口缓存的工具函数 void clearSerialBuffer() { while (esp.available()) { esp.read(); // 逐个读取缓存内容并丢弃 } } // 发送GET请求的核心函数 bool sendGETRequest() { clearSerialBuffer(); // 建立TCP连接 String tcpCmd = "AT+CIPSTART=\"TCP\",\"" + Domain + "\",80"; if (!sendATCommand(tcpCmd, "CONNECT", 3000)) { // 如果连接失败,先尝试关闭已有连接 sendATCommand("AT+CIPCLOSE", "OK", 1000); return false; } // 准备GET请求内容,注意Connection: close告诉服务器请求完关闭连接 String getRequest = "GET / HTTP/1.1\r\nHost: " + Domain + "\r\nConnection: close\r\n\r\n"; // 发送数据长度指令 String sendCmd = "AT+CIPSEND=" + String(getRequest.length()); if (!sendATCommand(sendCmd, ">", 1000)) { sendATCommand("AT+CIPCLOSE", "OK", 1000); return false; } // 发送GET请求内容 esp.print(getRequest); // 等待服务器响应,检查是否成功 unsigned long startTime = millis(); while (millis() - startTime < 5000) { if (esp.available()) { String response = esp.readStringUntil('\n'); Serial.println("服务器响应:" + response); // 只要收到HTTP 200或者连接关闭的提示,就认为请求成功 if (response.indexOf("HTTP/1.1 200") != -1 || response.indexOf("Connection closed") != -1) { // 确保关闭TCP连接 sendATCommand("AT+CIPCLOSE", "OK", 1000); return true; } } } // 超时处理,强制关闭连接 sendATCommand("AT+CIPCLOSE", "OK", 1000); return false; }
关键修复点说明
- 串口缓存清理:每次发送指令前都清空ESP的串口缓存,彻底避免旧响应干扰新指令的判断
- 带响应检查的AT指令:不再靠delay赌运气,而是等待ESP返回预期的响应(比如
OK、CONNECT),确保每一步指令都执行成功 - 错误重试逻辑:如果TCP连接失败,先尝试关闭已有连接再重试;请求失败时自动重新连接WiFi,保证循环稳定性
- 明确关闭连接:GET请求里加上
Connection: close,告诉服务器请求完成后立刻关闭TCP连接,避免ESP残留无效连接 - 常量优化:用
const定义WiFi信息和域名,减少不必要的字符串拷贝,提升代码稳定性
额外调试建议
- 打开Arduino的串口监视器,波特率设为9600,看看ESP返回的所有响应,能精准定位错误(比如常见的
ALREADY CONNECTED、ERROR) - 确保你的ESP8266固件是最新版本,旧固件可能存在TCP连接的bug
- 不要把循环间隔设得太短,过于频繁的请求可能会被服务器拒绝,也会让ESP负载过高
内容的提问来源于stack exchange,提问作者orb




