我有python代码从2个设备获取串行数据并写入.txt文件。每隔4-15分钟,.txt文件中大约有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秒。
DB
答案 0 :(得分:0)
您不应该刷新串口输入。数据以其自己的时间到达驱动程序中的缓冲区,而不是在您的读取发生时,因此您将使用刷新丢弃数据。您可能需要添加代码以与输入流同步。
答案 1 :(得分:0)
当我使用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()。
答案 2 :(得分:0)
我在队列中使用了线程,并将我的主循环更改为这样。
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给我一些诊断想法。