Arduino Uno R3与ESP8266-01软件串口通信故障排查求助
问题排查与解决方案:Arduino Uno与ESP8266-01软件串口通信
我帮你梳理了代码和硬件里的几个核心问题,一步步来解决:
1. ESP8266-01代码的关键错误
你的ESP代码里有几个致命问题,直接导致通信失败:
- 软件串口引脚配置完全错误:
SoftwareSerial mhaUno(12, 12, false, 256);把RX和TX都设为同一个引脚,而且ESP8266-01的可用串口引脚是GPIO1(TX)和GPIO3(RX),不能乱用其他引脚,更不能收发共用一个引脚。另外GPIO0是烧录引脚,正常工作时要接高电平,别用来做IO。 - 未初始化软件串口波特率:setup函数里只启动了USB硬件串口,没调用
mhaUno.begin(9600);,软件串口根本没工作。 - 发送数据用错了串口:
Serial.write("hello from esp");是往USB串口发调试信息,不是发给Uno的,应该用mhaUno.write()。
修正后的ESP8266-01代码:
#include <SoftwareSerial.h> // ESP8266-01的GPIO3(RX)接Uno的TX,GPIO1(TX)接Uno的RX SoftwareSerial mhaUno(3, 1); // RX, TX void setup() { Serial.begin(9600); // USB串口,用于调试查看日志 mhaUno.begin(9600); // 初始化和Uno通信的软件串口 pinMode(0, OUTPUT); digitalWrite(0, LOW); // 初始电平拉低 } void loop() { // 向Uno发送数据,用println自动加换行,方便接收端识别 mhaUno.println("hello from esp"); Serial.println("Sent to Uno: hello from esp"); // 调试日志 delay(1000); String IncomingString = ""; boolean StringReady = false; // 用readStringUntil('\n')替代readString,避免无限制阻塞 if(mhaUno.available()){ IncomingString = mhaUno.readStringUntil('\n'); StringReady = true; } if(StringReady) { Serial.print("Received from Uno: "); Serial.println(IncomingString); // 调试日志 // 用trim去掉换行和空格,避免匹配失败 if(IncomingString.trim() == "hello from uno") { digitalWrite(0, HIGH); } else { digitalWrite(0, LOW); } } }
2. Arduino Uno代码的关键错误
你的Uno代码同样有两个核心问题:
- 未初始化软件串口波特率:setup里没调用
esp8266.begin(9600);,软件串口处于未激活状态。 - 发送数据用错了串口:
Serial.write("hello from uno");是往USB串口发,不是发给ESP的,应该用esp8266.write()。
修正后的Arduino Uno代码:
#include <SoftwareSerial.h> // Uno的引脚2(RX)接ESP的TX,引脚3(TX)接ESP的RX SoftwareSerial esp8266(2, 3); // RX, TX void setup() { Serial.begin(9600); // USB串口,用于调试查看日志 esp8266.begin(9600); // 初始化和ESP通信的软件串口 pinMode(13, OUTPUT); digitalWrite(13, LOW); // 初始电平拉低 } void loop() { // 向ESP发送数据,用println自动加换行 esp8266.println("hello from uno"); Serial.println("Sent to ESP: hello from uno"); // 调试日志 delay(1000); String IncomingString = ""; boolean StringReady = false; // 读取ESP发来的数据 if(esp8266.available()){ IncomingString = esp8266.readStringUntil('\n'); StringReady = true; } if(StringReady) { Serial.print("Received from ESP: "); Serial.println(IncomingString); // 调试日志 if(IncomingString.trim() == "hello from esp") { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } } }
3. 硬件连接的必做事项
很多通信失败都是硬件问题,这部分一定要注意:
- 电平匹配(重中之重):ESP8266是3.3V器件,直接接Uno的5V引脚会烧坏ESP!必须做电平转换:
- Uno的TX(引脚3) → 分压电阻(比如1kΩ+2kΩ串联,取中间点)→ ESP的RX(GPIO3),把5V信号降到3.3V左右。
- ESP的TX(GPIO1) → 直接接Uno的RX(引脚2),3.3V信号Uno的5V系统可以识别。
- 嫌麻烦的话,直接用双向逻辑电平转换器,更可靠。
- 引脚对应:
- ESP8266-01 TX(GPIO1) → Uno 软件串口 RX(引脚2)
- ESP8266-01 RX(GPIO3) → Uno 软件串口 TX(引脚3)
- ESP8266-01 GND → Uno GND(必须共地,否则信号无法传输)
- ESP供电:Uno的3.3V引脚最大输出只有50mA,远不够ESP8266工作(需要200mA左右),建议用外部3.3V/1A电源给ESP供电,同时和Uno共地。
- ESP启动模式:ESP8266-01正常工作时,GPIO0要接高电平(接3.3V),EN引脚接3.3V(不能悬空),GPIO2可以悬空(内部有上拉)。
4. 调试小技巧
- 分别用USB串口查看两边的调试日志,确认数据是否正常发送和接收。
- 如果还是无法通信,先测试单向通信:比如只让ESP发数据,Uno接收,确认正常后再开双向。
- 用万用表测ESP的RX引脚在Uno发送时是否有3.3V左右的电平变化,测Uno的RX引脚在ESP发送时是否有电平变化,排查硬件连接问题。
内容的提问来源于stack exchange,提问作者rendy ada
相关产品推荐
相关产品推荐

