首页 > 解决方案 > 存储和处理串行数据时的问题

问题描述

我正在读取串行数据并尝试对单个数据包进行排序和显示。问题是当我收到一个数据包时,我可以使用 print() 打印它,并且数据包打印得很好。但是当我将此数据包添加到 list[] 或尝试将数据包添加到 Listbox(tkinter) 时,这些数据包有时会被合并/加扰,我会得到两个数据包显示为一个更长的数据包。

这是我到目前为止所尝试的:

我尝试了许多代码变体,但都失败了。打印功能正确显示数据包,但是当我尝试对它们做任何事情时,即将它们排序到列表中或将它们添加到列表框中,一些数据包被合并......。似乎当数据包以最小的时间延迟突然出现时,python 处理它们的速度不够快?但是打印功能确实跟上了,当我运行单独的线程将数据包放入队列和单独的线程将它们从队列中读取时,时间应该不是问题,对吧?

请帮忙,我已经用尽了我所有的想法......</p>

我正在使用串行读取线功能来获取数据包:

def serial_read_line(port):
    ser = serial.Serial(port, 115200, timeout=0.01)
    ser.flushInput()
    while 1:
        x = ser.readline()
        if len(x) < 1:
            pass
        else:
            y = str(x.decode('utf-8'))
            if y != x:
                x = y
                return y

上述函数在单独的线程中运行,因此不会阻塞程序。

# *********** Scanning for packets **********
# scan for incoming packets
# set global variable for start/stop packet scan
stop = 1
q1 = queue.Queue()


def ser_packet_scan():
    port = serial_port_selection.get()
    global q1
    while True:
        packet_1 = sio.serial_read_line(port)
        q1.put(packet_1)
        process_packets()
        if stop == 1:
            break


# starting thread for packet scan
def start_thread():
    global stop
    stop = 0
    th = Thread(target=ser_packet_scan)
    th.start()
    th2 = Thread(target=process_packets)
    th2.start()


# stopping thread for packet scan
def stop_thread():
    global stop
    stop = 1

该处理在单独的线程中运行,我也尝试在主程序线程中运行它。

def process_packets():
    # sort packets into lists
    global q1
    pckt_r = q1.get()
    print(pckt_r)
    pck.sort_into_lists(pckt_r)
    # update packet lists
    if list_box_selection.get() == 'Running':
        list_box_display.insert(0, pckt_r)
        # limit listbox display size
        if list_box_display.size() > 100:
            list_box_display.delete(END)
…
…
    # time.sleep(0.5) have tried with the sleep and without it… no diference...
    q1.task_done()

标签: pythonqueuepython-multithreadingpyserial

解决方案


好的,我找到了解决方案。我还发现了几个问题。

  • print() 函数会自动换行并理解 \r,因此即使数据包由两个或多个数据包组成,我的打印输出也始终正确。
  • 内置函数 readline() 不能很好地工作。即使存在 \r 字符,某些数据包也会被合并。

解决方案:我已将内置 readline() 替换为自定义函数:

def read_line_c(ser):
    buf = bytearray()
    i = buf.find(b"\r")
    if i >= 0:
        r = buf[:i + 1]
        buf[i + 1:]
        return r
    while True:
        i = max(1, min(2048, ser.in_waiting))
        data = ser.read(i)
        i = data.find(b"\r")
        if i >= 0:
            r = buf + data[:i + 1]
            buf[0:] = data[i + 1:]
            return r
        else:
            buf.extend(data)

使用此自定义 readline 数据包似乎一切正常,但我需要对其进行更多测试以查看是否有任何问题...或者我可以使用内置的 readline(),然后查找具有 \r 的数据包在他们里面并分裂他们......


推荐阅读