2017-07-31 26 views
1

我試圖通過Python3建立雙向通信。有一個插入我的USB端口之一的激光測距儀,我想發送/接收命令。我有一張可以發送的命令,他們會返回什麼,所以這部分已經在那裏了。Python3雙向串行通信:讀取數據

我需要的是一種方便的實時操作方式。到目前爲止,我有以下代碼:

import serial, time 

SERIALPORT = "/dev/ttyUSB0" 
BAUDRATE = 115200 

ser = serial.Serial(SERIALPORT, BAUDRATE) 
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.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 = 0  #timeout for write 

print ("Starting Up Serial Monitor") 

try: 
    ser.open() 
except Exception as e: 
    print ("Exception: Opening serial port: " + str(e)) 

if ser.isOpen(): 
    try: 
     ser.flushInput() 
     ser.flushOutput() 
     ser.write("1\r\n".encode('ascii')) 
     print("write data: 1") 
     time.sleep(0.5) 
     numberOfLine = 0 
     while True: 
      response = ser.readline().decode('ascii') 
      print("read data: " + response) 
      numberOfLine = numberOfLine + 1 
      if (numberOfLine >= 5): 
       break 
     ser.close() 
    except Exception as e: 
     print ("Error communicating...: " + str(e)) 
else: 
    print ("Cannot open serial port.") 

因此,在上面的代碼中我送「1」,這應當觸發激光測距儀的「getDistance的()」函數,並在返回毫米的距離。我在膩子上嘗試過,它可以工作,返回最多4位數的距離。但是,當我啓動上面的Python腳本時,我的輸出僅爲以下內容:

Starting Up Serial Monitor 
Exception: Opening serial port: Port is already open. 
write data: 1 
read data: 

它會一直持續下去。沒有讀數據或任何。

我錯在哪裏?

+0

嘗試添加'ser.close()''之前ser.open()'。 –

+0

不幸的是,沒有改變任何東西。 –

回答

1

顯然,更簡單的代碼版本解決了這個問題。

import serial 
import time 

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout = 1) # ttyACM1 for Arduino board 

readOut = 0 #chars waiting from laser range finder 

print ("Starting up") 
connected = False 
commandToSend = 1 # get the distance in mm 

while True: 
    print ("Writing: ", commandToSend) 
    ser.write(str(commandToSend).encode()) 
    time.sleep(1) 
    while True: 
     try: 
      print ("Attempt to Read") 
      readOut = ser.readline().decode('ascii') 
      time.sleep(1) 
      print ("Reading: ", readOut) 
      break 
     except: 
      pass 
    print ("Restart") 
    ser.flush() #flush the buffer 

輸出,根據需要:

Writing: 1 
Attempt to Read 
Reading: 20 
Restart 
Writing: 1 
Attempt to Read 
Reading: 22 
Restart 
Writing: 1 
Attempt to Read 
Reading: 24 
Restart 
Writing: 1 
Attempt to Read 
Reading: 22 
Restart 
Writing: 1 
Attempt to Read 
Reading: 26 
Restart 
Writing: 1 
Attempt to Read 
Reading: 35 
Restart 
Writing: 1 
Attempt to Read 
Reading: 36 
0

在我看來,你的ser.timeout = None可能在這裏造成問題。你的while循環的第一個循環似乎很好,但是當它第二次嘗試ser.readline()時程序掛起。

有幾種方法可以解決這個問題。我的首選方法是指定一個非None超時,也許是一秒鐘。這將允許ser.readline()即使在設備不發送結束字符時也返回一個值。

另一種方法是將ser.readline()更改爲ser.read(ser.in_waiting)ser.read(ser.inWaiting()),以便返回緩衝區中可用的所有字符。

+0

我試過兩種方法,結果讀取的數據行被打印了5次,但是沒有任何值。在這一點上,我也懷疑寫功能是否正常工作,因爲我沒有看到命令對激光器的影響。該設備甚至可能不會收到命令,更不用說回覆了。 –