Отправка команды «AT» на модем usb GSM возвращает пустую строку в Python - PullRequest
0 голосов
/ 05 июня 2019

Проблема

Я настраиваю скрипт на python для связи с моим USB GSM-модемом через AT-команды.
Итак, чтобы проверить правильность связи, я сначала пытаюсь отправить простой AT ожидаю получения OK, но вместо этого с каждым read запросом я все еще получаю только пустые строки.
Я следую стандарту AT, как описано здесь: AT-команды

Пока что

Работа над Linux Mint 18.
Я нашел больше информации о моем GSM с mmcli .
Запуск 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 может ответить на AT я использовал socat :

$ 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 голосов
/ 06 июня 2019

Похоже, что-то мешает вашему коду вернуться с ошибкой.

Для Python 3.x serial.read() возвращает байты, поэтому, где вы делаете:

resp += tmp

Вы должны получить ошибку (я получил ее, когда я запускаю ваш код, соединяющий два последовательных порта вместе в моем ноутбуке).

Измените эту строку на:

resp += tmp.decode()

Подробнее см. Здесь: Почему pyserial для python3k возвращает байты, а python2k возвращает строки?

Единственная причина, по которой я могу думать, чтобы вы не получали эту ошибку преобразования типов, заключается в том, что вы ничего не получаете на своем порту (ваш код переходит на эту строку при пустом чтении из порта). В таком случае, я думаю, вам придется проверить ваши настройки, потому что ваш код Python работает просто отлично.

0 голосов
/ 05 июня 2019

Команды 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.

...