pyserial数据缺口

时间:2018-04-04 20:50:04

标签: python-2.7 csv serial-port multiprocessing pyserial

我有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秒。

Breaks in writing data to csv

DB

3 个答案:

答案 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给我一些诊断想法。