从串口写入和读取

时间:2017-05-30 06:15:37

标签: serial-port usb pyserial at-command

我使用以下python脚本在串口ttyUSB1上写AT + CSQ。 但我什么都看不懂。

然而,当我在minicom上触发AT + CSQ时,我得到了所需的结果。

此脚本可能存在什么问题?

日志: 手动脚本

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:

日志:

Minicom控制台

1. ate
OK

2. at+csq
+CSQ: 20,99

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

如何在以下python脚本中收到这些结果?

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 "

1 个答案:

答案 0 :(得分:0)

你的AT命令处理有两个非常根本的缺陷:

time.sleep(1)

if (numOfLines >= 5):

他们有多糟糕?在你解决这些问题之前,什么都行不通,我的意思是完全改变你发送和接收命令和响应的方式。

向调制解调器发送AT命令是一种通信协议,与任何其他协议一样,其中某些部分和行为是必需的,而不是可选的。就像你不会编写一个完全忽略它从HTTP服务器返回的响应的HTTP客户端一样,你必须永远不要写一个程序将AT命令发送到调制解调器并完全忽略调制解调器发回的响应。

AT命令是链路层协议,窗口大小为1 - 1。因此,在发送命令行之后,发送方必须等到收到调制解调器的响应,表明它已完成处理命令行,并且这种响应称为最终结果代码

如果调制解调器在使用最终结果代码响应之前使用70ms,则必须等待至少70ms再继续,如果它使用4秒,则必须等待至少4秒再继续,如果它使用几分钟(并且是,存在可能需要几分钟才能完成的AT命令)你必须等待几分钟。如果调制解调器在一小时内没有响应,你唯一的选择是1)继续等待,2)放弃或3)断开连接,重新连接并重新开始。

这就是为什么sleep是如此可怕的方法,在最好的情况下是浪费时间炸弹的时间。它和踢狗一样有用,可以阻挡它们移动。是的它可能实际上有效,但在某些时候你会抱歉采取这种方法......

关于numOfLines,任何人都无法确切知道调制解调器将响应多少行。如果您的调制解调器只使用ERROR最终结果代码的单行响应怎么办?代码将陷入僵局。

所以这个行号必须完全消失,而你的代码应该发送一个命令行,然后等待reading and parsing来自调制解调器的响应行的最终结果代码。

但是在深入研究这个答案之前,首先要阅读V.250规范,至少是第5章的全部内容。这是定义AT命令基础知识的标准,并且例如会教你差异在命令命令行之间。以及如何correctly terminate你没有做的命令行,所以调制解调器永远不会开始处理你发送的命令。