Search code examples
multithreadingpyserialserial-communication

pyserial only flushes on 1 thread


I have 2 virtual COM ports and a client on each port. The connection works fine for reading. But it only writes on 1 of the threads. eg: when i write on the write_thread it sends it to he serial port and prints it to the console. But on the connected client it only shows what write_worker's output when it receives a response from the read_worker. Any help?

import serial
import time
import threading

def read_worker():
    """"constantly reads and responds back"""
    while True:
        read_text = ser.readline()
        read = read_text.decode("utf-8")
        print(read)

        response = "response to: " + read
        ser.write(response.encode())
        ser.flush()
        print(response)
        time.sleep(.1)

def write_worker():
    """Constantly writes to see if it can"""
    i = 0
    while True:
        i += 1

        response = "Writing: " + str(i)
        ser.write(response.encode())
        print(response)
        time.sleep(2)


ser = serial.Serial(
    port="COM1",
    baudrate=115200,
    bytesize=serial.EIGHTBITS,
    stopbits=serial.STOPBITS_ONE,
    rtscts=True)

threading.Thread(target=read_worker).start()
threading.Thread(target=write_worker).start()

Solution

  • Updated answer

    Sometimes buffers are only flushed when a newline is received, therefore I would try to change

    response = "Writing: " + str(i)
    

    into

    response = "Writing: " + str(i) + "\r\n"
    

    Still valid, but not the problem

    A serial port can only be opened once. You are now transmitting bytes to COM1, it is thus not possible to open the same COM1 in another thread and read these bytes.

    Your setup should be something as follows:

    COM1 == virtual null-modem (!important as tx/rx pairs must be crossed) == COM2

    You can then for example write to COM1 and read the result on COM2.