我尝试使用pyserial从多个串行设备读取数据,并将所有内容同步到一起。最后我希望代码:
- read serial from laser
- read serial from gps
- get a single string with [gps_reading, laser_reading]
GPS的刷新率高达5hz 激光器按需发送的值高达约20赫兹
孤立地,他们都工作正常,我得到快速的响应时间。但是,当我尝试从多个读取时,我会得到一个随时间推移而增加的延迟。
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
import gps
import laser
#serial
def serialGeneric(device, baudRate):
ser = serial.Serial(
port=device,
baudrate=baudRate,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
)
return ser
#Device 1
gpsSerial = serialGeneric("/dev/ttyUSB0",9600)
gps.gps_init(gpsSerial)
#Device 2
laserSerial = serialGeneric("/dev/ttyUSB1",19200)
i = 1
start_time = time.time()
while i<50:
dis = laser.lrf_getDistance(laserSerial)
print dis
pos = gps.gps_getData(gpsSerial)
print pos
i+=1
print("--- %s seconds ---" % (time.time() - start_time))
gps和激光功能只需发送适当的命令来请求数据: 即。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
def lrf_getDistance(ser):
i = 0
while i == 0:
ser.write("d\r\n")
ser.flush()
msg = ser.readline()
try:
msg = float(msg)
i == 1
return msg
except ValueError:
pass
运行代码时,如果我发表评论&#39; pos = gps.gps_getData(gpsSerial)&#39;和&#39; print pos&#39; &#34;激光&#34;设备输出几乎是即时的。取消注释&#34;激光&#34;输出非常滞后。
如果相关,我会在桌面计算机上运行代码。
任何人都可以建议我如何摆脱滞后?
新代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
import threading
import gps
import laser
#serial
def serialGeneric(device, baudRate):
ser = serial.Serial(
port=device,
baudrate=baudRate,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
#timeout=0
)
return ser
#Device 1
gpsSerial = serialGeneric("/dev/ttyUSB0",9600)
#Device 2
laserSerial = serialGeneric("/dev/ttyUSB1",19200)
class myThreadGPS (threading.Thread):
def __init__(self, ser):
threading.Thread.__init__(self)
self.ser = ser
def run(self):
print "Starting GPS"
gps.gps_getDataINF(self.ser)
class myThreadLAS (threading.Thread):
def __init__(self, ser):
threading.Thread.__init__(self)
self.ser = ser
def run(self):
print "Starting Laser"
laser.lrf_getDistanceINF(self.ser)
# Create new threads
thread1 = myThreadGPS(gpsSerial)
thread2 = myThreadLAS(laserSerial)
# Start new Threads
thread1.start()
thread2.start()
正如评论中所提到的,这个&#34;解决了&#34;手头的问题。不幸的是,我仍然不明白为什么需要这样做。
答案 0 :(得分:1)
对于每个线程,将有以下同步资源:
我没有彻底检查以下代码的语法,因此可能存在一些语法错误。基本上,线程在读取串行端口时与主程序同步。当主程序允许开始新的循环时,它们再次并行读取端口。
class myThreadGPS (threading.Thread):
def __init__(self, ser, start_event, end_event, pos):
threading.Thread.__init__(self)
self.ser = ser
self.start_event = start_event
self.end_event = end_event
self.pos = pos
def run(self):
self.start_event.wait()
self.start_event.clear()
print "Starting GPS"
self.pos[0] = gps.gps_getDataINF(self.ser)
self.end_event.set()
class myThreadLAS (threading.Thread):
def __init__(self, ser, start_event, end_event, dis):
threading.Thread.__init__(self)
self.ser = ser
self.start_event = start_event
self.end_event = end_event
self.dis = dis
def run(self):
self.start_event.wait()
self.start_event.clear()
print "Starting Laser"
self.dis[0] = laser.lrf_getDistanceINF(self.ser)
self.end_event.set()
#Declare the used events
gps_end_event = threading.Event()
laser_end_event = threading.Event()
gps_start_event = threading.Event()
laser_start_event = threading.Event()
#Initialize shared variables
pos = [None]
dis = [None]
# Create new threads
thread1 = myThreadGPS(gpsSerial, gps_start_event, gps_end_event, pos)
thread2 = myThreadLAS(laserSerial, laser_start_event, laser_end_event, dis)
# Start new Threads
thread1.start()
thread2.start()
#Start events initially set to True
gps_start_event.set()
laser_start_event.set()
while True:
#Wait for both threads to end and reset them.
gps_end_event.wait()
gps_end_event.clear()
laser_end_event.wait()
laser_end_event.clear()
#print the shared variables
print pos[0]
print dis[0]
gps_start_event.set()
laser_start_event.set()