1

I am using the following python script to write AT+CSQ on serial port ttyUSB1. But I cannot read anything.

However, when I fire AT+CSQ on minicom, I get the required results.

What may be the issue with this script?

Logs: Manual Script

root@imx6slzbha:~# python se.py
Serial is open
Serial is open in try block also
write data: AT+CSQ
read data:
read data:
read data:
read data:

Logs:

Minicom console

1. ate
OK

2. at+csq
+CSQ: 20,99

3. at+csq=?
OKSQ: (0-31,99),(99)

How can I receive these results in the following python script?

import serial, time

#initialization and open the port

#possible timeout values:

#    1. None: wait forever, block call

#    2. 0: non-blocking mode, return immediately

#    3. x, x is bigger than 0, float allowed, timeout block call

ser = serial.Serial()

ser.port = "/dev/ttyUSB1"

ser.baudrate = 115200

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.timeout = None          #block read

#ser.timeout = 0             #non-block read

ser.timeout = 3              #timeout block read

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.writeTimeout = 2     #timeout for write

try:

    ser.open()

    print("Serial is open")

except Exception, e:

    print "error open serial port: " + str(e)

    exit()

if ser.isOpen():

    try:

        print("Serial is open in try block also")

        ser.flushInput() #flush input buffer, discarding all its contents

        ser.flushOutput()#flush output buffer, aborting current output

                     #and discard all that is in buffer

        #write data

        ser.write("AT+CSQ")
        time.sleep(1)
#       ser.write("AT+CSQ=?x0D")

        print("write data: AT+CSQ")
#       print("write data: AT+CSQ=?x0D")

        time.sleep(2)  #give the serial port sometime to receive the data

        numOfLines = 1

        while True:

            response = ser.readline()

            print("read data: " + response)

            numOfLines = numOfLines + 1

            if (numOfLines >= 5):

                break

        ser.close()

    except Exception, e1:

        print "error communicating...: " + str(e1)

else:

    print "cannot open serial port "
Mel
  • 5,837
  • 10
  • 37
  • 42
asharma
  • 63
  • 1
  • 7
  • 1. On minicom you appear to first sent ate, don't see you sending that in your terribly formatted Python code. 2. When you do send a string in minicom, you also press the enter key which also gets send as a "\r" or "\n" (not sure which, may not matter), and when you send the strings in python you have to explicitly put the keystroke for the enter key into the string you send, because it isn't sent automagically. So, may need to make sure you send "ate\n" (or it could be \r, not sure) and then check for the OK response, and then similarly add "\r" (or "\n") to the other strings you send. – DisappointedByUnaccountableMod May 30 '17 at 16:22
  • Please, please format the code in the question properly. – hlovdal May 30 '17 at 17:29
  • Hi, hlovdal, i was able to use the existing code to fetch desired output, sorry, the formatting was not proper. :( Here's my output: root@imx6slzbha:~/python_exercises# python serial_tty_working.py port is opened write data: AT+CSQ=?x0D read data: read data: read data: ^RSSI:19 read data: read data: ^HCSQ:"LTE",46,53,161,30 I can easily fetch LTE RSSI using strip(). Thanks Do you have any idea how to write multiple commands using single python script and read output line by line. Thanks – asharma May 31 '17 at 09:18

1 Answers1

0

You have two very fundamental flaws in your AT command handling:

time.sleep(1)

and

if (numOfLines >= 5):

How bad are they? Nothing will ever work until you fix those, and by that I mean completely change the way you send and receive command and responses.

Sending AT commands to a modem is a communication protocol like any other protocols, where certain parts and behaviours are required and not optional. Just like you would not write a HTTP client that completely ignores the responses it gets back from the HTTP server, you must never write a program that sends AT commands to a modem and completely ignores the responses the modem sends back.

AT commands are a link layer protocol, with with a window size of 1 - one. Therefore after sending a command line, the sender MUST wait until has received a response from the modem that it is finished with processing the command line, and that kind of response is called Final result code.

If the modem uses 70ms before it responds with a final result code you have to wait at least 70ms before continuing, if it uses 4 seconds you have to wait at least 4 seconds before continuing, if it uses several minutes (and yes, there exists AT commands that can take minutes to complete) you have to wait for several minutes. If the modem has not responded in an hour, your only options are 1) continue waiting, 2) just give up or 3) disconnect, reconnect and start all over again.

This is why sleep is such a horrible approach that in the very best case is a time wasting ticking bomb. It is as useful as kicking dogs that stand in your way in order to get them to move. Yes it might actually work some times, but at some point you will be sorry for taking that approach...

And regarding numOfLines there is no way anyone in advance can know exactly how many lines a modem will respond with. What if your modem just responds with a single line with the ERROR final result code? The code will deadlock.

So this line number counting has to go completely away, and instead your code should be sending a command line and then wait for the final result code by reading and parsing the response lines from the modem.

But before diving too deep into that answer, start by reading the V.250 specification, at least all of chapter 5. This is the standard that defines the basics of AT command, and will for instance teach you the difference between a command and a command line. And how to correctly terminate a command line which you are not doing, so the modem will never start processing the commands you send.

hlovdal
  • 26,565
  • 10
  • 94
  • 165