pyserial数据差距
pyserial data gaps
我有 python 代码,可从 2 个设备获取串行数据并写入 .txt 文件。 .txt 文件中每 4-15 分钟就会丢失大约 30-45 秒的数据,这对于我们的用例来说是不可接受的。我花了数小时在谷歌上搜索和搜索有关多处理和串行端口数据采集的信息,但没有提出解决方案。
这是我的代码
gpsser = input(("Enter GPS comport as 'COM_': "))
ser = serial.Serial(port=gpsser,
baudrate=38400,
timeout=2,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
root = Tk()
root.title("DualEM DAQ")
path = filedialog.asksaveasfilename() + ".txt"
file = glob.glob(path)
filename = path
with open(filename, 'wb') as f:
w = csv.writer(f, dialect='excel')
w.writerow(['header'])
def sensor():
while True:
try:
NMEA1 = dser.readline().decode("ascii")
while dser.inWaiting() == 0:
pass
NMEA1_array = NMEA1.split(',')
NMEA2_array = NMEA2.split(',')
NMEA3_array = NMEA3.split(',')
NMEA4_array = NMEA4.split(',')
if NMEA1_array[0] == '$PDLGH':
value1 = NMEA1_array[2]
value2 = NMEA1_array[4]
if NMEA1_array[0] == '$PDLG1':
value3 = NMEA1_array[2]
value4 = NMEA1_array[4]
if NMEA1_array[0] == '$PDLG2':
value5 = NMEA1_array[2]
value6 = NMEA1_array[4]
return (float(value1), float(value2), float(value3),
float(value4), float(value5), float(value6),
except (IndexError, NameError, ValueError, UnicodeDecodeError):
pass
def gps():
while True:
try:
global Status, Latitude, Longitude, Speed, Truecourse, Date
global GPSQuality, Satellites, HDOP, Elevation, Time
while ser.inWaiting() == 0:
pass
msg = ser.readline()
pNMEA = pynmea2.parse(msg)
if isinstance(pNMEA, pynmea2.types.talker.RMC):
Latitude = pynmea2.dm_to_sd(pNMEA.lat)
Longitude = -(pynmea2.dm_to_sd(pNMEA.lon))
Date = pNMEA.datestamp
Time = datetime.datetime.now().time()
if () is not None:
return (Longitude, Latitude, Date, Time)
except (ValueError, UnboundLocalError, NameError):
pass
while True:
try:
with open(filename, "ab") as f:
data = [(gps() + sensor())]
writer = csv.writer(f, delimiter=",", dialect='excel')
writer.writerows(data)
f.flush()
print(data)
except (AttributeError, TypeError) as e:
pass
程序正在写入文件,但我需要帮助了解为什么我经常丢失 30-45 秒的数据。导致这种情况发生的瓶颈在哪里?
这是休息时间的示例,请注意,在这种情况下,休息时间约为 50 秒。
Breaks in writing data to csv
数据库
您不应该刷新串口输入。数据按其自身的时间到达驱动程序中的缓冲区,而不是在您进行读取时到达,因此您在刷新时丢弃了数据。您可能需要添加代码以与输入流同步。
当我使用 PySerial 时,我是这样做的:
nbytes = ser.inWaiting()
if nbytes > 0:
indata = ser.read(nbytes)
#now parse bytes in indata to look for delimiter, \n in your case
#and if found process the input line(s) until delimiter not found
else:
#no input yet, do other processing or allow other things to run
#by using time.sleep()
另请注意,PySerial 的新版本 (3.0+) 将 .in_waiting 作为 属性 而不是方法,因此没有 (),它曾经是 .inWaiting().
我使用队列线程并将我的主循环更改为如下所示。
while True:
try:
with open(filename, "ab") as f:
writer = csv.writer(f, delimiter=",", dialect='excel')
data = []
data.extend(gpsdata())
data.extend(dualemdata())
writer.writerows([data])
f.flush()
f.close()
dser.flushInput()
ser.flushInput()
print(data)
sleep(0.05)
except (AttributeError, TypeError) as e:
pass
我必须在循环回读取函数之前刷新串行端口输入数据,以便它读取新的实时数据(这消除了传入数据流的任何滞后)。我已经 运行 进行了 30 分钟的测试,时间间隔似乎已经消失。感谢 Cmaster 给我一些诊断思路。
我有 python 代码,可从 2 个设备获取串行数据并写入 .txt 文件。 .txt 文件中每 4-15 分钟就会丢失大约 30-45 秒的数据,这对于我们的用例来说是不可接受的。我花了数小时在谷歌上搜索和搜索有关多处理和串行端口数据采集的信息,但没有提出解决方案。
这是我的代码
gpsser = input(("Enter GPS comport as 'COM_': "))
ser = serial.Serial(port=gpsser,
baudrate=38400,
timeout=2,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
root = Tk()
root.title("DualEM DAQ")
path = filedialog.asksaveasfilename() + ".txt"
file = glob.glob(path)
filename = path
with open(filename, 'wb') as f:
w = csv.writer(f, dialect='excel')
w.writerow(['header'])
def sensor():
while True:
try:
NMEA1 = dser.readline().decode("ascii")
while dser.inWaiting() == 0:
pass
NMEA1_array = NMEA1.split(',')
NMEA2_array = NMEA2.split(',')
NMEA3_array = NMEA3.split(',')
NMEA4_array = NMEA4.split(',')
if NMEA1_array[0] == '$PDLGH':
value1 = NMEA1_array[2]
value2 = NMEA1_array[4]
if NMEA1_array[0] == '$PDLG1':
value3 = NMEA1_array[2]
value4 = NMEA1_array[4]
if NMEA1_array[0] == '$PDLG2':
value5 = NMEA1_array[2]
value6 = NMEA1_array[4]
return (float(value1), float(value2), float(value3),
float(value4), float(value5), float(value6),
except (IndexError, NameError, ValueError, UnicodeDecodeError):
pass
def gps():
while True:
try:
global Status, Latitude, Longitude, Speed, Truecourse, Date
global GPSQuality, Satellites, HDOP, Elevation, Time
while ser.inWaiting() == 0:
pass
msg = ser.readline()
pNMEA = pynmea2.parse(msg)
if isinstance(pNMEA, pynmea2.types.talker.RMC):
Latitude = pynmea2.dm_to_sd(pNMEA.lat)
Longitude = -(pynmea2.dm_to_sd(pNMEA.lon))
Date = pNMEA.datestamp
Time = datetime.datetime.now().time()
if () is not None:
return (Longitude, Latitude, Date, Time)
except (ValueError, UnboundLocalError, NameError):
pass
while True:
try:
with open(filename, "ab") as f:
data = [(gps() + sensor())]
writer = csv.writer(f, delimiter=",", dialect='excel')
writer.writerows(data)
f.flush()
print(data)
except (AttributeError, TypeError) as e:
pass
程序正在写入文件,但我需要帮助了解为什么我经常丢失 30-45 秒的数据。导致这种情况发生的瓶颈在哪里?
这是休息时间的示例,请注意,在这种情况下,休息时间约为 50 秒。
Breaks in writing data to csv
数据库
您不应该刷新串口输入。数据按其自身的时间到达驱动程序中的缓冲区,而不是在您进行读取时到达,因此您在刷新时丢弃了数据。您可能需要添加代码以与输入流同步。
当我使用 PySerial 时,我是这样做的:
nbytes = ser.inWaiting()
if nbytes > 0:
indata = ser.read(nbytes)
#now parse bytes in indata to look for delimiter, \n in your case
#and if found process the input line(s) until delimiter not found
else:
#no input yet, do other processing or allow other things to run
#by using time.sleep()
另请注意,PySerial 的新版本 (3.0+) 将 .in_waiting 作为 属性 而不是方法,因此没有 (),它曾经是 .inWaiting().
我使用队列线程并将我的主循环更改为如下所示。
while True:
try:
with open(filename, "ab") as f:
writer = csv.writer(f, delimiter=",", dialect='excel')
data = []
data.extend(gpsdata())
data.extend(dualemdata())
writer.writerows([data])
f.flush()
f.close()
dser.flushInput()
ser.flushInput()
print(data)
sleep(0.05)
except (AttributeError, TypeError) as e:
pass
我必须在循环回读取函数之前刷新串行端口输入数据,以便它读取新的实时数据(这消除了传入数据流的任何滞后)。我已经 运行 进行了 30 分钟的测试,时间间隔似乎已经消失。感谢 Cmaster 给我一些诊断思路。