Python-TKinter程序,使用多线程从串行端口读取

时间:2019-07-19 12:34:07

标签: python multithreading arduino pyserial

我正在使用Python程序(该程序是TKinter GUI来控制Arduino)来读写Arduino。

从串行端口读取始终会暂停程序,如果执行其他任何操作(如移动窗口),它会崩溃。我以为这是因为程序正在运行serial.read(),并且它只是在等待输入而没有超时(我需要不断从串行端口读取数据)。

作为一种可能的解决方案,我希望从另一个线程上的串行端口读取数据,以避免崩溃程序。我已经在网上和其他类似的StackOverflow问题上进行了研究,但是似乎没有一个人对如何针对我的特定情况做任何见识。

我程序中的相关代码如下:

from multiprocessing.pool import ThreadPool
import serial
import time
import sys
import glob

# global variables for module
start_marker = b'<' 
end_marker = b'>'

#========================

def setupSerial(ser_port):
    print("SETUPSERIAL -- ser_port is: ", ser_port)
    global  ser

    # NOTE the user must ensure that the serial port and baudrate are correct
    #~ ser_port = "/dev/ttyS81"

    baudRate = 9600

    try:
        ser = serial.Serial(port = ser_port, 
                            baudrate = baudRate)
                            # time_out = 10)
    except:
        raise

    print("Serial port " + ser_port + " opened  Baudrate " + str(baudRate))

    waitForArduino()

#===========================

def waitForArduino():

    # wait until the Arduino sends 'R' (arbitrarily chose ready character)- allows time for Arduino reset
    # it also ensures that any bytes left over from a previous message are discarded

    print("Waiting for Arduino to reset")

    pool = ThreadPool(processes=1)
    recv_async_result = pool.apply_async(recvFromArduino, (10, ''))

    msg = b''   # 'Null' in unicode
    while msg != b'R':   # 'R' in unicode
        print("3")
        print("WAITING for Arduino -- Data type of msg is: ", type(msg), " -- msg is: ", msg)


        msg = recv_async_result.get()

        print(msg)
        print()  

#============================

def recvFromArduino(time_out, nothing): # time_out in seconds eg 1.5, # nothing is for multithreading to have iterable arguments

    global start_marker, end_marker, ser

    data_buf = b''  # 'Null' in unicode/empty byte
    x = b'z' # Any value that is not an end- or start_marker
    start_time = time.time()
    #~ print "Start %s" %(start_time)

    # wait for the start marker
    while  x != start_marker:
        print("1")
        if time.time() - start_time >= time_out:
            return('<<')
        print("NOT FOUND marker -- Data type of x is: ", type(x), " -- x is: ", x)
        x = ser.read()


    # save data until the end marker is found
    while x != end_marker:
        print("2")
        if time.time() - start_time >= time_out:
            return('>>')
        if x != start_marker:
            print("FOUND marker -- Data type of x is: ", type(x), " -- x is: ", x)
            print("FOUND marker -- Data type of data_buf is: ", type(data_buf), " -- data_buf is: ", data_buf)
            # data_buf = data_buf + str(x, 'utf-8')
            data_buf = data_buf + x
        x = ser.read()

    return(data_buf)

完整的代码会运行并产生输出。但是,如果尝试执行其他任何操作,它似乎仍然会使我的程序崩溃。在尝试多线程之后,它似乎不再从串行端口读取,因为它总是比编写的手动超时代码超时(返回“ << >>”)。

我只是想知道我是否正确进行此操作。我什至需要多线程吗?我试图编写的代码只是垃圾吗?我尝试多线程是完全错误的吗? (这是我第一次尝试多线程)

任何建议和帮助将不胜感激。如果需要更多信息,请告诉我。

0 个答案:

没有答案