Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pySerial+;SIM800/900 AT命令-读取缓冲区包含以前的写入缓冲区数据_Python_Pyserial_Sim900_Sim800 - Fatal编程技术网

Python pySerial+;SIM800/900 AT命令-读取缓冲区包含以前的写入缓冲区数据

Python pySerial+;SIM800/900 AT命令-读取缓冲区包含以前的写入缓冲区数据,python,pyserial,sim900,sim800,Python,Pyserial,Sim900,Sim800,我试图通过pySerial向SIM800模块发送AT命令。我遇到的问题是,当我发送命令时,我收到的消息是前一个命令的输出(有时是前一个命令本身)。我的代码如下所示: import time import serial ser = serial.Serial() ser.port = "/dev/ttyAMA0" ser.baudrate = 9600 ser.open() def readData(): buffer = "" while True: oneB

我试图通过pySerial向SIM800模块发送AT命令。我遇到的问题是,当我发送命令时,我收到的消息是前一个命令的输出(有时是前一个命令本身)。我的代码如下所示:

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
我觉得这与需要刷新缓冲区有关,但我对串行工作不太有经验。有人能告诉我我做错了什么吗?

有几件事

  • 如果要设置写入超时,则需要在初始化
    Serial
    对象时使用
    write\u timeout
    或通过设置
    ser.write\u timeout

  • 如果您确实担心数据仍在输入缓冲区中,您可以执行以下操作:
    ser.reset\u input\u buffer()

  • 如果您确实担心数据仍在输出缓冲区中,您可以执行以下操作:
    ser.reset\u output\u buffer()

  • 现在,在代码方面,您可以这样做

    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
    

    我在通过UART与SIM 800通信时也遇到了同样的问题。我使用ATE0命令来禁用回音。试试这个,它可能会对您有所帮助

     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)
    

    谢谢我已经实现了您的更改,但仍然可以在readData()函数中看到前面的命令。我能让它发挥应有作用的唯一方法是在每次sendData()之后读取Data()两次。第一次读取输出我发出的命令,第二次读取给出我想要的响应。不知道为什么会发生这种情况。有什么想法吗?@fistameny可能是因为
    pyserial
    在写入后立即返回,即使数据可能没有完全通过缓冲区。试着把
    time.sleep(.1)
    放在
    write
    read
    之间,看看这是否有帮助谢谢,我会试试的。到目前为止,每次发送后阅读两次似乎是有效的,但更希望有一个适当的修复。