SIM800L使用AT指令循环发短信仅首个收件人成功问题求助
问题根因
你遇到的问题核心是AT指令发送流程没有和SIM800L的状态做同步,缺少应答等待逻辑,导致两次发送的指令时序冲突:
SIM800L执行AT+CMGS指令进入短信内容输入模式后,只有收到chr(26)(Ctrl+Z)并完成短信发送后,才会退出输入模式回到AT指令接收状态。你当前的代码只做了固定1秒等待,没有等待模块明确返回发送成功的应答,第一次发送可能刚好在1秒内完成,第二次循环执行时模块还处于输入模式,后续的AT+CMGF=1等指令就会被识别为短信内容存入缓冲区,就出现了你描述的异常。
你之前尝试的修改串口超时、重启串口、追加换行的方案都没有解决核心的时序同步问题,因此无效。
修复方案
修改代码,增加AT指令的应答等待逻辑,确保每一步操作都确认模块执行完成后再走下一步,修改后的参考代码如下:
import serial import time class SIM800L: def __init__(self, port): self.port = port self.com = serial.Serial(self.port, baudrate = 9600, timeout = 2) # 新增应答等待方法,匹配指定的返回内容后才返回成功 def wait_for_response(self, expect_content="OK", timeout=3): start_time = time.time() response_lines = [] while time.time() - start_time < timeout: if self.com.in_waiting: line = self.com.readline().decode().strip() if line: response_lines.append(line) if expect_content in line: return True, response_lines return False, response_lines def send_serial_command(self, cmd, expect_content="OK", timeout=3): self.com.write(cmd.encode()) return self.wait_for_response(expect_content, timeout) def send_sms(self, msg, number): # 先清空串口缓冲区,避免残留内容干扰 self.com.reset_input_buffer() self.com.reset_output_buffer() # 1. 设置短信为文本模式,等待OK确认 set_mode_ok, resp = self.send_serial_command("AT+CMGF=1\r\n", expect_content="OK") if not set_mode_ok: print(f"设置文本模式失败,应答:{resp}") return False # 2. 设置收件人号码,等待模块返回>提示符,确认可以输入短信内容 set_num_ok, resp = self.send_serial_command(f'AT+CMGS="{number}"\r\n', expect_content=">", timeout=5) if not set_num_ok: print(f"设置收件人{number}失败,应答:{resp}") return False # 3. 发送短信内容 self.send_serial_command(msg, expect_content=None) # 4. 发送结束符Ctrl+Z,等待短信发送成功的应答 send_ok, resp = self.send_serial_command(chr(26), expect_content="+CMGS:", timeout=10) if not send_ok: print(f"向{number}发送短信失败,应答:{resp}") return False time.sleep(0.5) return True
另外注意你给出的循环测试代码存在笔误,参数之间缺少逗号,修正后为:
sim800l = SIM800L("/dev/ttyUSB0") numbers = ["+44XXXXXXXXXX", "+44VVVVVVVVVV"] for n in numbers: sim800l.send_sms("Hello", n)
内容的提问来源于stack exchange,提问作者Eugene Levinson
相关产品推荐
相关产品推荐

