ESP8266使用SoftwareSerial连接SIMCom时乱码问题的解决求助
ESP8266 与 SIMCom 76xx 通信发送长AT指令出现乱码的解决方法
问题描述
编写ESP8266连接SIMCom 76xx模块通过HTTP获取数据的代码时,发送AT+HTTPPARA这类长AT指令出现乱码,导致URL解析错误。代码如下:
SoftwareSerial gsm(14, 12); // RX, TX void setup() { Serial.begin(115200); //ESP的调试串口 gsm.begin(115200); //SIMCom的串口,使用SoftwareSerial模拟 /* 其他代码*/ } void loop() { String http_str = "AT+HTTPPARA=\"URL\",\"http://api.openweathermap.org/data/2.5/weather?xxxxxxxx\"\r\n"; /* xxxxxx 为经度、纬度及API密钥 */ sendD("AT+HTTPINIT\r\n", 4000, DEBUG); sendD(http_str, 6000, DEBUG); sendD("AT+HTTPACTION=0\r\n", 5000, DEBUG); sendD("AT+HTTPTERM\r\n", 3000, DEBUG); } String sendD(String command, const int timeout, boolean debug) { /* 用于向SIMCom发送AT指令,并读取返回信息显示到串口监视器 */ }
串口监视器显示的乱码示例:
AT+HTTPPARA="URL","http://api.openw⸮ AT+HTTPPARA="URL","http://api.openw⸮athermap.org"
该指令在AT指令测试软件中可正常运行,但乱码导致模块无法识别正确的URL。
解决方法
1. 降低串口波特率
SoftwareSerial是软件模拟的串口,在115200高波特率下稳定性极差,长字符串传输时极易丢包、乱码。建议将波特率降到9600或19200:
修改代码中的波特率设置:
void setup() { Serial.begin(9600); //调试串口同步降低波特率 gsm.begin(9600); //SIMCom模块需预先通过AT指令设置为对应波特率(AT+IPR=9600,再用AT&W保存) /* 其他代码*/ }
2. 改用ESP8266硬件串口
ESP8266自带硬件UART,稳定性远高于软件串口。ESP8266有两个硬件串口:
- UART0:映射到GPIO1(TX)、GPIO3(RX),注意GPIO1与板载LED引脚复用;
- UART1:映射到GPIO2(TX)、GPIO15(RX),GPIO15需下拉,适合连接外设。
修改代码使用硬件串口:
// 使用UART1作为SIMCom的通信串口(根据实际接线调整引脚) HardwareSerial gsmSerial(1); void setup() { Serial.begin(115200); //调试用串口 gsmSerial.begin(115200, SERIAL_8N1, 15, 2); // RX=15, TX=2 /* 其他代码*/ } void loop() { String http_str = "AT+HTTPPARA=\"URL\",\"http://api.openweathermap.org/data/2.5/weather?xxxxxxxx\"\r\n"; sendD(gsmSerial, "AT+HTTPINIT\r\n", 4000, DEBUG); sendD(gsmSerial, http_str, 6000, DEBUG); sendD(gsmSerial, "AT+HTTPACTION=0\r\n", 5000, DEBUG); sendD(gsmSerial, "AT+HTTPTERM\r\n", 3000, DEBUG); } // 调整sendD函数,接收HardwareSerial对象 String sendD(HardwareSerial &serial, String command, const int timeout, boolean debug) { serial.print(command); String response = ""; unsigned long startTime = millis(); while (millis() - startTime < timeout) { if (serial.available()) { char c = serial.read(); response += c; if (debug) Serial.print(c); } } return response; }
3. 优化SoftwareSerial的发送逻辑
若必须使用软件串口,优化发送逻辑,逐个字符发送并预留接收时间:
String sendD(String command, const int timeout, boolean debug) { gsm.flush(); // 清空发送缓冲区 // 逐个字符发送,避免批量发送导致的丢包 for (int i = 0; i < command.length(); i++) { gsm.write(command.charAt(i)); delay(2); // 给模块足够时间接收单个字符 } String response = ""; unsigned long startTime = millis(); while (millis() - startTime < timeout) { if (gsm.available()) { char c = gsm.read(); response += c; if (debug) Serial.print(c); } } return response; }
4. 同步SIMCom模块的串口配置
确保模块的串口参数(波特率、数据位、停止位、奇偶校验)与代码完全一致:
- 用
AT+IPR?查询当前波特率; - 用
AT+IPR=xxx设置目标波特率; - 用
AT&W保存配置,重启模块生效。
内容的提问来源于stack exchange,提问作者Cao Minh
相关产品推荐
相关产品推荐

