With a single serial link, how to read continuous data every second (polling), and do other queries in the meantime?

106 views Asked by At

I communicate with a hardware device via serial link RS232 (no other option available).

  • I need to continuously poll some data "foo", every second (if possible).
  • Sometimes I also need to ask the device for other data, such as "bar" and "baz"

Of course, since it's a single serial link (and no high-level interface like HTTP), I cannot do both at the same time just by using 2 different threads: it's important to check that no concurrent data is being sent at the same time through the same wire.

This is my current solution:

class Device:
    def __init__(self):
        self.serial_port = serial.Serial(port="COM1", baudrate=9600, parity="N", stopbits=1)
        self.start_foo_polling()

    def start_foo_polling(self):
        self.foo_polling = True
        threading.Thread(target=self.get_foo_thread).start()

    def get_foo_thread(self):
        while self.foo_polling:
            self.serial_port.write(b"QUERY_FOO")
            data = self.serial_port.read(8)    # then, do something with data!
            time.sleep(1)
       
    def stop_foo_polling(self):
        self.foo_polling = False

    def query_bar(self):
        rerun_foo_polling = False                             # *
        if self.foo_polling:                                  # *
            rerun_foo_polling = True                          # *
            self.stop_foo_polling()                           # *
            time.sleep(1)   # wait for the thread to finish   # *   
        self.serial_port.write(b"QUERY_BAR")
        data = self.serial_port.read(8)
        if rerun_foo_polling:                                 # *
            self.start_foo_polling()                          # *

d = Device()
time.sleep(3.9)
d.query_bar()

but it would require some code duplication of the lines (*) for def query_baz(self): ..., and more generally it does not seem optimal.

What is the standard serial link solution to handle this concurrency problem?

0

There are 0 answers