gpt4 book ai didi

python - 使用pyserial读取多个串行设备时延迟较大

转载 作者:太空宇宙 更新时间:2023-11-03 15:49:10 24 4
gpt4 key购买 nike

我正在尝试使用 pyserial 从多个串行设备读取数据,其想法是将所有内容同步在一起。最后我希望代码能够:

- read serial from laser
- read serial from gps
- get a single string with [gps_reading, laser_reading]

GPS刷新率高达5hz激光器按需发送高达 20 Hz 左右的值

单独来看,它们都工作正常,并且我得到了快速的响应时间。然而,当我尝试读取多个内容时,我会遇到延迟,并且延迟会随着时间的推移而增加。

代码如下:

#!/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

运行代码时,如果我注释掉“pos = gps.gps_getData(gpsSerial)”和“print pos”,“激光”设备输出几乎是立即的。取消注释后,“激光”输出极其滞后。

如果相关的话,我正在台式机上运行代码。

任何人都可以建议我如何摆脱滞后吗?

  • 编辑:我已更改代码以在多个线程中运行这两个函数。遵循tutorialspoint中有关Python多线程的教程。

新代码如下:

#!/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()

正如评论中提到的,这“解决”了当前的问题。不幸的是,我仍然不太明白为什么需要这样做。

最佳答案

对于每个线程,都会有以下同步资源:

  • 指示周期何时结束以及接收到的数据的事件
  • 共享变量,存储要打印的数据
  • 另一个事件,指示何时可以开始新的周期。每个线程在开始循环之前都必须等待此标志,并且当两个线程结束各自的任务时将引发该标志。

我没有彻底检查以下代码的语法,因此可能存在一些语法错误。基本上,当线程都读取串行端口时,它们与主例程同步。当主例程允许开始新的循环时,它们再次并行读取端口。

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()

关于python - 使用pyserial读取多个串行设备时延迟较大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41461072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com