2

I'm writing something like an SMS gate on Ubuntu. The device is a Huawei E173 Modem.

I use pyserial to write/read to and from the device. Here is my code:

import serial
import time

port = '/dev/ttyUSB0'
ser = serial.Serial(port,
        stopbits=serial.STOPBITS_ONE,
        parity=serial.PARITY_NONE,
        bytesize=serial.EIGHTBITS
        )
ser.write(b'AT\r\n')
time.sleep(0.1)
print(ser.read(ser.in_waiting))

This code works. But sometimes when I reconnect the device, I find that it cannot read anything. (ser.in_waiting=0 and nothing changes even if I set n larger).

But I can still use minicom to work with that port.

My Question: Why doesn't pyserial work but minicom can? Is there any difference between them?

aschultz
  • 1,658
  • 3
  • 20
  • 30
pingze
  • 973
  • 2
  • 9
  • 18
  • How about setting RTS and DTR to True? – kunif Aug 06 '19 at 03:05
  • @kunif Have tried, not works – pingze Aug 06 '19 at 03:11
  • Isn't it plug-and-play well handled? Is it necessary to use not only PySerial but also a package that supports plug and play? – kunif Aug 06 '19 at 03:32
  • @kunif I don't understand what does it have to do with plug-and-play. Can you explain? – pingze Aug 06 '19 at 03:42
  • Inferred from the keyword reconnect. Please do something to investigate. – kunif Aug 06 '19 at 03:48
  • There's some technical stuff that's beyond me but a search for minicom pyserial turned up this link: https://stackoverflow.com/questions/56385615/using-pyserial-dont-work-until-port-open-with-minicom which doesn't seem to be your exact problem, but it has some explanations what Minicom does. Also, small clarification: you mention setting N larger, but I can't see a variable N in your code. Did you mean another parameter function? – aschultz Aug 06 '19 at 04:34

2 Answers2

2

What I guess it's happening is that the delay you are using together with the timeout you set when you open the port is conspiring with the time it takes for the modem to process the command.

To avoid that try reading data repeatedly for a certain time with a loop:

... 
ser.write(b'AT\r\n')
timeout=time.time()+3.0 
while ser.inWaiting() or time.time()-timeout<0.0: 
    if ser.inWaiting()>0: 
        data+=ser.read(ser.inWaiting()) 
         timeout=time.time()+3.0 print(data)

With minicom or any other terminal you are always listening on the port so you always get the answer no matter how long the modem takes to process the command. In your code you send the command, wait 100 ms and then listen on the port for a time period defined by the timeout setting. Since you are not defining a timeout you have the default wait forever but that behavior is overridden by the use of the bytes in the buffer as an argument. If you happen to check the buffer before data arrives in it (because the command took longer than the 100 ms you gave it) the timeout becomes zero.

Considering the previous paragraph, and assuming you know the number of bytes it might be better to define a finite timeout and read with a ser.read(n) with n the expected bytes.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16
  • It works! I just found that if I read immediately after writing, I got some thing. But if i wait a short time, there is nothing left in output buffer. I guess there is some other program had readed the outputs. With your code, I can got outputs before others. – pingze Aug 06 '19 at 05:47
0

In my case, (on the BeagleBone Black), the above answer helped me get some bytes but not all. I realized, due to some reasons, minicom was reading the port and (maybe) flushing it. So, PySerial got nothing to read.

I simply closed minicom terminal and everything is good now :)

Pe Dro
  • 2,651
  • 3
  • 24
  • 44