2

I've trying to send AT commands via pySerial to a SIM800 module. The problem I'm having is that when I send a command, the message I receive back is the output of the previous command (or sometimes, the previous command itself). My code looks like this:

import time
import serial

ser = serial.Serial()
ser.port = "/dev/ttyAMA0"
ser.baudrate = 9600
ser.open()

def readData():
    buffer = ""
    while True:
        oneByte = ser.read(1)
        if oneByte == b"\n":
            return buffer
        else:
            buffer += oneByte.decode("ascii")

def sendData(command, timeout):
    fullcommand = "{}\r\n".format(command)
    print "Sent: {}".format(fullcommand)
    ser.write(fullcommand)
    time.sleep(timeout)
    return

sendData("AT", 1) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints AT

sendData("AT+CIPSHUT", 5) # Expecting "SHUT OK" back
print "Return: {}".format(readData()) # Prints OK

sendData("AT+CIPMUX=0", 2) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints AT+CIPSHUT

sendData("AT+CSTT=\"myapn\"", 4) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints SHUT OK

I feel it's something to do with needing to flush buffers, but I'm not too experienced with Serial work. Can anyone suggest what I'm doing wrong?

fistameeny
  • 1,048
  • 2
  • 14
  • 27

2 Answers2

3

I was facing the same issue while communicating with SIM 800 through UART. I used ATE0 command to disable the echo.Try this it might help you.

 import serial
 import time

 # dmesg | grep tty #to get which port it ts using
 port = serial.Serial("/dev/ttyO2", baudrate=9600, timeout=1)

 if port.isOpen():
     print(port.name + ' is open...!!!')

 # Transmitting AT Commands to the Modem
 port.write('AT'+'\r')
 print port.read(32)
 time.sleep(2)

 # To disable echo
 port.write('ATE0'+'\r')  
 print port.read(32)
 time.sleep(2)
2

A few things.

  1. If you want to set the timeout for write, it needs to be done using write_timeout either in the initialization of the Serial object or by setting ser.write_timeout

  2. If you are truly concerned that the data is still in the input buffer you can do ser.reset_input_buffer()

  3. If you are truly concerned that the data is still in the output buffer you can do ser.reset_output_buffer()

Now in terms of code you can do something like this

import time
import serial

ser = serial.Serial()
ser.port = "/dev/ttyAMA0"
ser.baudrate = 9600
ser.open()

def readData():
    buffer = ""
    while True:
        oneByte = ser.read(1)
        if oneByte == b"\n":
            return buffer
        else:
            buffer += oneByte.decode("ascii")

def sendData(command, timeout):
    fullcommand = "{}\r\n".format(command)
    ser.write_timeout = timeout # This is where you can set the timeout
    bytes_written = ser.write(fullcommand)
    # Check to see if all the data was written
    if bytes_written == len(fullcommand):
        print "Sent: {}".format(fullcommand)
    else:
        print 'Not all data transferred'

sendData("AT", 1) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints AT

sendData("AT+CIPSHUT", 5) # Expecting "SHUT OK" back
print "Return: {}".format(readData()) # Prints OK

sendData("AT+CIPMUX=0", 2) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints AT+CIPSHUT

sendData("AT+CSTT=\"myapn\"", 4) # Expecting "OK" back
print "Return: {}".format(readData()) # Prints SHUT OK
Chrispresso
  • 3,660
  • 2
  • 19
  • 31
  • 1
    Thanks. I've implemented your changes, but still seeing the previous command in the readData() function. The only way I can get it to act as it should is to readData() twice after every sendData(). The first read outputs the command I issued, the second read gives me the response I wanted. Not sure why this is happening in the first place. Any ideas? – fistameeny Apr 26 '18 at 16:33
  • @fistameeny it might be because `pyserial` returns immediately after writing even though the data may not be fully through the buffer. Try putting `time.sleep(.1)` in between the `write` and `read` and see if that helps – Chrispresso Apr 28 '18 at 21:56
  • Thanks, I'll give that a try. So far, reading twice after every send seems to be working, but would prefer a proper fix. – fistameeny Apr 30 '18 at 11:49