向USB GSM调制解调器发送“ AT”命令后,Python中将返回空字符串

时间:2019-06-05 20:50:05

标签: python linux usb pyserial

问题

我正在用python设置脚本,以通过AT命令与USB GSM调制解调器通信。
因此,为了测试通信是否正常工作,我首先尝试发送一个简单的AT,希望收到一个OK,但是对于每个read请求,我仍然只收到空字符串。
我遵循的AT标准如下:AT Commands

到目前为止

使用Linux Mint18。
我通过mmcli找到了有关GSM的更多信息。
启动mmcli -L会导致:

$ mmcli -L
    /org/freedesktop/ModemManager1/Modem/0 [D-Link,Inc  ] D-Link DWM-157

,然后显示以下信息:

$ mmcli -m /org/freedesktop/ModemManager1/Modem/0 
  --------------------------
  General  |      dbus path: /org/freedesktop/ModemManager1/Modem/0
           |      device id: 741cce5b5eb40d9ac1c9a1dc0dfa2356f0abe3e7
  --------------------------
  Hardware |   manufacturer: D-Link,Inc  
           |          model: D-Link DWM-157
           |       revision: MOLY.WR8.W1231.DC.WG.MP.V3
           |   h/w revision: MTK2
           |      supported: gsm-umts
           |        current: gsm-umts
           |   equipment id: 355620059754511
  --------------------------
  System   |         device: /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-5
           |        drivers: cdc_mbim, option1
           |         plugin: Generic
           |   primary port: cdc-wdm2
           |          ports: ttyUSB0 (at), wwp0s29f7u5 (net), ttyUSB1 (at), 
           |                 cdc-wdm2 (mbim)
  --------------------------
  Numbers  |            own: 393515383117
  --------------------------
  Status   | unlock retries: unknown (0)
           |          state: registered
           |    power state: on
           |    access tech: hsdpa, hsupa
           | signal quality: 0% (cached)
  --------------------------
  Modes    |      supported: allowed: 2g, 3g; preferred: none
           |        current: allowed: 2g, 3g; preferred: none
  --------------------------
  IP       |      supported: ipv4, ipv6, ipv4v6
  --------------------------
  3GPP     |           imei: 355620059754511
           |  enabled locks: net-pers, net-sub-pers, provider-pers, corp-pers
           |    operator id: 22250
           |  operator name: 22250
           |   registration: home
  --------------------------
  SIM      |      dbus path: /org/freedesktop/ModemManager1/SIM/0

因此要检查我的GSM是否能够响应我使用过socatAT

$ sudo socat - /dev/ttyUSB0
AT

OK

最终目标

我的目标是创建一个脚本,使我可以将多个SMS发送到数字列表中。

完整脚本

import serial, time

def initSerial() :
    print ('initialize...', end='')
    ser = serial.Serial()
    ser.port = "/dev/ttyUSB0"
    ser.baudrate = 115200
    ser.timeout = 5                     #timeout block read
    ser.writeTimeout = 2
    ser.bytesize = serial.EIGHTBITS     #number of bits per bytes
    ser.parity = serial.PARITY_NONE     #set parity check: no parity
    ser.stopbits = serial.STOPBITS_ONE  #number of stop bits
    ser.xonxoff = False                 #disable software flow control
    ser.rtscts = False                  #disable hardware (RTS/CTS) flow control
    ser.dsrdtr = False                  #disable hardware (DSR/DTR) flow control
    ser.open()
    print('done')
    return ser


def write_cmd(ser,cmd) :
    if ser.isOpen() :   
        print('writing: " {} " in {}'.format(cmd, ser.name))
        ser.write(cmd.encode('utf-8'))  # Write the 'cmd' encoded with utf-8


def read_until(ser,terminator='\n'):
    print ('reading {}...'.format(ser.name))
    resp = ''
    while not ( resp.endswith(terminator) or resp.endswith('\r') ) : # If the string is not terminated
        tmp = ser.read(1)   # Read and store in a temp variable
        if not tmp : return resp # timeout occured
        resp += tmp
    return resp  


if __name__ == '__main__' :
    ser = initSerial()          # Setup initial variables and configurations
    write_cmd(ser,'AT\r\n')         # Write a command to the serial pipe
    print(read_until(ser))      # Read from the serial pipe until 
    ser.close()

这是输出:

$ sudo python3 main.py 
  initialize...done
  writing: " AT " in /dev/ttyUSB0
  reading /dev/ttyUSB0...

那里有一个空白行。

2 个答案:

答案 0 :(得分:0)

AT命令根据特定的指令来工作。在这种情况下,我要说的问题是您发送的AT没有结尾行。您必须在末尾发送所有 AT命令,并附带载波和结束行字符。因此,在这种情况下将为AT\r\n,与设备进行通信的所有命令都应以相同的方式完成。

if __name__ == '__main__' :
ser = initSerial()          # Setup initial variables and configurations
write_cmd(ser,'AT\r\n')     # Write a command to the serial pipe
print(read_until(ser))      # Read from the serial pipe until 
ser.close()

每个AT命令更改的响应取决于您所使用的命令。我建议您使用更详细的代码来接收RX信号。

答案 1 :(得分:0)

似乎有些原因阻止了您的代码返回错误。

对于Python 3.x serial.read()返回字节,以便您这样做:

resp += tmp

您应该得到一个错误(当我在笔记本电脑上运行将两个串行端口连接在一起的代码时,我得到了它。)

将该行更改为:

resp += tmp.decode()

有关更多详细信息,请参见此处:Why does pyserial for python3k return bytes while python2k returns strings?

我能为您想到的不出现此类型转换错误的唯一原因是,您在端口上根本没有收到任何东西(您的代码在从端口上读取空行时跳到了该行)。如果是这种情况,我猜您将不得不检查您的设置,因为您的Python代码可以正常工作。