【问题标题】:pyserial data gapspyserial 数据缺口
【发布时间】:2018-09-14 13:23:07
【问题描述】:

我有从 2 个设备获取串行数据并写入 .txt 文件的 python 代码。每 4-15 分钟,.txt 文件中就会丢失大约 30-45 秒的数据,这对于我们的用例来说是不可接受的。我花了几个小时在谷歌上搜索和搜索关于多处理和串行端口数据采集的 SO,但还没有提出解决方案。

这是我的代码

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

数据库

【问题讨论】:

  • if () is not None: ---> 什么?为什么会有ser.flushInput; ser.flushOutput() ...;里面?
  • 1.关于 if () is not none 的思考过程是查看函数是否返回一个值以返回该值,如果它是 none,则不返回任何内容。我猜我可能不需要那个声明? 2.ser.flushinput()是清空传入串口数据的缓冲区。这有意义吗?
  • 编辑了更新的代码并添加了上下文的时间中断图片。

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


【解决方案1】:

当我使用 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 inWaiting() == 0 循环。 readline() 调用应该是阻塞的,所有 inWaiting() 循环都在消耗 cpu,直到至少有 1 个字节可用,之后您的代码将阻塞在 readline() 中,直到该行的其余部分到达。跨度>
  • 我已经删除了 inWaiting 循环,但是我仍然遇到同样的问题。数据库
  • 单独运行 gps 和传感器回路,以确定差距是由这些设备之一还是由这些设备组合引起的。
  • 我单独运行 gps 和传感器回路。发现 gps 接收器的电源有噪音。解决了这个问题,它确实减少了问题,但没有消除。所以我在不同的线程上运行了 gps 和传感器,这也无助于解决这个问题(我认为它不应该)。感谢您提出单独运行 gps 和传感器的想法。我将继续研究可能发生的其他情况
【解决方案2】:

您不应该刷新串行端口输入。数据按自己的时间到达驱动程序中的缓冲区,而不是在读取发生时,因此您在刷新时丢弃了数据。您可能需要添加代码以与输入流同步。

【讨论】:

  • 我更新了删除flushinput()的脚本。在那之后仍然得到同样的休息时间。关于如何添加代码以与输入流同步,您有什么建议、示例或想法吗?
【解决方案3】:

我将线程与队列一起使用,并将我的主循环更改为如下所示。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多