You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 19:06:04