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

西门子iRZ ES75iT GSM调制解调器发送含AT命令短信技术咨询

Sending SMS with AT Command Content via Siemens iRZ ES75iT Modem

Alright, let's tackle this problem head-on. The core issue here is that your GSM modem will misinterpret any AT-prefixed text in your message as an actual AT command (instead of part of the SMS content). Below are two reliable solutions, along with fixes for your existing Python script.

Why This Happens

When using text mode (the default for many simple SMS scripts), the modem listens for AT sequences even while you're inputting message content. So if your SMS says something like "Check AT+CMGF settings", the modem will try to run AT+CMGF as a command instead of sending it as text.


Solution 1: Escape AT Sequences in Text Mode (Quick Fix)

If you want to stick with text mode (the approach your current script uses), you just need to add an escape character before any AT in your message. For Siemens modems, the standard escape character is a backslash (\).

Here's your modified sendsms function with this fix, plus some debug improvements to help you troubleshoot:

import serial
import time

def sendsms(to, message):
    # Replace @ with null char (as your original script does)
    message = message.replace('@', '\0')
    # Escape AT sequences so the modem treats them as plain text
    message = message.replace('AT', '\\AT')
    # Trim message to GSM text mode limit (160 chars max for 7-bit encoding)
    if len(message) > 160:
        message = message[:160]
    
    print("Connecting to modem...")
    ser = serial.Serial('/dev/ttyS0', 115200, timeout=12)
    time.sleep(1)

    # Send AT command to check modem connectivity
    ser.write('AT\r')
    time.sleep(1)
    print("AT command response:", ser.read_all().decode('utf-8').strip())

    # Explicitly set text mode (avoids default mode inconsistencies)
    ser.write('AT+CMGF=1\r')
    time.sleep(1)
    print("Text mode setup response:", ser.read_all().decode('utf-8').strip())

    # Delete old SMS (as your original script does)
    ser.write('AT+CMGD="ALL"\r')
    time.sleep(2)
    print("Delete SMS response:", ser.read_all().decode('utf-8').strip())

    # Send the SMS
    ser.write(f'AT+CMGS="{to}"\r')
    time.sleep(1)
    # Send message content, then end with Ctrl+Z (ASCII 26) to trigger send
    ser.write(message.encode('utf-8') + b'\x1A')
    time.sleep(3)
    response = ser.read_all().decode('utf-8').strip()
    print("SMS send response:", response)

    ser.close()

Solution 2: Switch to PDU Mode (More Reliable)

Text mode is prone to edge cases like this. For any SMS with special content (including AT commands, non-ASCII characters), PDU mode is the better choice. It encodes the message as binary, so the modem never confuses content with commands.

Here's a complete script using PDU mode, with a simplified encoding function for GSM 7-bit text:

import serial
import time

def encode_gsm_pdu(phone_number, message):
    """Encode SMS content and phone number into a PDU string (GSM 7-bit encoding)."""
    # Process phone number (E.164 format, reversed nibbles)
    num = phone_number.lstrip('+')
    if len(num) % 2 != 0:
        num += 'F'  # Pad with F if length is odd
    encoded_num = ''.join([num[i+1] + num[i] for i in range(0, len(num), 2)])
    
    # Process message content (GSM 7-bit character set)
    encoded_msg = ''
    for char in message:
        # Map standard ASCII to GSM 7-bit code (simplified for common characters)
        gsm_code = ord(char)
        if 0x20 <= gsm_code <= 0x7E:
            encoded_msg += format(gsm_code, '02X')
        # Add handling for special GSM characters (like €, ñ) if needed
    
    # Build full PDU string
    msg_length = len(encoded_msg) // 2
    pdu = f'0011000D91{encoded_num}0000{format(msg_length, "02X")}{encoded_msg}'
    return pdu, len(pdu) // 2  # Return PDU string and its length in bytes

def sendsms(to, message):
    print("Connecting to modem...")
    ser = serial.Serial('/dev/ttyS0', 115200, timeout=12)
    time.sleep(1)

    # Verify modem connectivity
    ser.write('AT\r')
    time.sleep(1)
    print("AT response:", ser.read_all().decode('utf-8').strip())

    # Switch to PDU mode
    ser.write('AT+CMGF=0\r')
    time.sleep(1)
    print("PDU mode setup response:", ser.read_all().decode('utf-8').strip())

    # Clear old SMS
    ser.write('AT+CMGD="ALL"\r')
    time.sleep(2)
    print("Clear SMS response:", ser.read_all().decode('utf-8').strip())

    # Encode message to PDU
    pdu_str, pdu_byte_len = encode_gsm_pdu(to, message)
    
    # Send SMS via PDU command
    ser.write(f'AT+CMGS={pdu_byte_len}\r')
    time.sleep(1)
    ser.write(pdu_str.encode('utf-8') + b'\x1A')
    time.sleep(3)
    response = ser.read_all().decode('utf-8').strip()
    print("SMS send response:", response)

    ser.close()

Key Notes for Success

  • Debug with Responses: Always read the modem's response after each AT command (like I did in the scripts). A response of OK means success; ERROR means something went wrong (check your command syntax or modem settings).
  • Baud Rate Check: Confirm your modem uses 115200 baud. If not, query the current rate with AT+IPR? and adjust the serial.Serial parameter.
  • Character Limits: Text mode supports up to 160 7-bit characters; PDU mode supports the same, or 70 characters if using UCS2 encoding (for non-ASCII text like Chinese).

内容的提问来源于stack exchange,提问作者Programming Lover

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:41:36