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?