1

I am communicating with a Fona 808 module from a Raspberry Pi and I can issue AT commands, yey!

Now I want to make a python program where I can reliably issue AT commands using shortcut commands like "b" for getting the battery level and so on.

This is what I have so far:

import serial
con = serial.Serial('/dev/ttyAMA0',timeout=0.2,baudraute=115200)
def sendAtCommand(command):
    if command == 'b':
        con.write("at+cbc\n".encode())
        reply = ''
        while con.inWaiting():
            reply = reply + con.read(1)
        return reply

while True:
    x = raw_input("At command: ")
    if x.strip() == 'q':
        break
    reply = sendAtCommand(x)
    print(reply)


con.close()

In the sendAtCommand I will have a bunch of if statements that send different at commands depending on the input it receives.

This is somewhat working but is very unreliable. Sometimes I get the full message. Other times I get nothing. Then double message next time and so on.

I would like to create one method that issues a command to the Fona module and then reads the full response and returns it.

Any suggestions?

Sigmundur
  • 725
  • 1
  • 8
  • 25

2 Answers2

1

Your loop quits if the 'modem' has not responded anything to your at command yet. You should keep reading the serial input until you get a linefeed or until a certain time has passes e.g. 1 second or so.

Sami Sallinen
  • 3,203
  • 12
  • 16
  • The timeout is 0.2 seconds. That should be enough for the module to return such things as the battery level. In the case of reading the battery level the output from the modem is 4 lines of data. If I use con.readline() four times then it reliably reads it every time. – Sigmundur Feb 25 '16 at 18:31
  • I dont think inWaiting() cares about the timeout. It returns false immediately if there is no data received yet. – Sami Sallinen Feb 25 '16 at 18:35
1

Okay. It turns out this is pretty trivial. Since at commands always return OK after a successful query then it is simply a matter of reading the lines until eventually one of them will contain 'OK\r\n'. Like so:

def readUntilOK():
    reply=''
    while True:
        x = con.readline()
        reply += x
        if x == 'OK\r\n':
            return reply

This does not have a timeout and it does not check for anything else than an OK response. Which makes it very limiting. Adding error handling is up to the reader. Something like if x == 'ERROR\r\n' would be a good start.

Cheers!

Sigmundur
  • 725
  • 1
  • 8
  • 25
  • You should not wait for only `OK`, you have to wait for all possible final result codes. It is not hard and you have the overall code structure almost in place, but not quite. See [this answer](http://stackoverflow.com/a/31126602/23118) for more details. – hlovdal Feb 28 '16 at 10:21