Python3双向串行通信:读入数据
Python3 Two-Way Serial Communication: Reading In Data
我正在尝试通过 Python3 建立双向通信。有一个激光测距仪插入了我的一个 USB 端口,我想向它发送 send/receive 命令。我有一个 sheet 可以发送的命令以及它们会发送什么 return,所以这部分已经存在了。
我需要的是一种方便的实时方式。到目前为止,我有以下代码:
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()" 功能和 return 以毫米为单位的距离。我在 Putty 上试过这个并且它有效,returns 距离最多 4 位数。但是,当我启动上面的 Python 脚本时,我的输出只有以下内容:
Starting Up Serial Monitor
Exception: Opening serial port: Port is already open.
write data: 1
read data:
它永远存在。没有读取数据或任何内容。
我哪里弄错了?
在我看来,您的 ser.timeout = None
可能会导致这里出现问题。 while
循环的第一个循环似乎运行良好,但程序在第二次尝试 ser.readline()
时挂起。
有几种方法可以解决这个问题。我的首选方法是指定一个非 None
超时,也许是一秒。这将允许 ser.readline()
到 return 一个值,即使设备不发送结束符也是如此。
另一种方法是将 ser.readline()
更改为 ser.read(ser.in_waiting)
或 ser.read(ser.inWaiting())
之类的内容,以便 return 缓冲区中的所有可用字符。
显然更简单的代码版本解决了这个问题。
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
试试这个代码
try:
ser = serial.Serial("/dev/ttyS0", 9600) #for COM3
ser_bytes = ser.readline()
time.sleep(1)
inp = ser_bytes.decode('utf-8')
print (inp)
except:
pass
我正在尝试通过 Python3 建立双向通信。有一个激光测距仪插入了我的一个 USB 端口,我想向它发送 send/receive 命令。我有一个 sheet 可以发送的命令以及它们会发送什么 return,所以这部分已经存在了。
我需要的是一种方便的实时方式。到目前为止,我有以下代码:
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()" 功能和 return 以毫米为单位的距离。我在 Putty 上试过这个并且它有效,returns 距离最多 4 位数。但是,当我启动上面的 Python 脚本时,我的输出只有以下内容:
Starting Up Serial Monitor
Exception: Opening serial port: Port is already open.
write data: 1
read data:
它永远存在。没有读取数据或任何内容。
我哪里弄错了?
在我看来,您的 ser.timeout = None
可能会导致这里出现问题。 while
循环的第一个循环似乎运行良好,但程序在第二次尝试 ser.readline()
时挂起。
有几种方法可以解决这个问题。我的首选方法是指定一个非 None
超时,也许是一秒。这将允许 ser.readline()
到 return 一个值,即使设备不发送结束符也是如此。
另一种方法是将 ser.readline()
更改为 ser.read(ser.in_waiting)
或 ser.read(ser.inWaiting())
之类的内容,以便 return 缓冲区中的所有可用字符。
显然更简单的代码版本解决了这个问题。
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
试试这个代码
try:
ser = serial.Serial("/dev/ttyS0", 9600) #for COM3
ser_bytes = ser.readline()
time.sleep(1)
inp = ser_bytes.decode('utf-8')
print (inp)
except:
pass