Multithreaded writing to serial ports?

Hi all. I’m working on a project where I’ll need to send LED data out over 10 serial ports (it’s a custom RS485 system, not Art-Net/sACN sadly so no DMX Out CHOP). When I’ve done something similar in a C++ app, the write to the serial port was quite slow, especially when done one at a time in a loop, and I had to do the writing on separate threads for good performance.

How is threading handled with the Serial DATs? I don’t see any parameters or methods on the class referencing threading so I’m assume it’s all the main thread. Is there a built-in way to handle this, or some pointers on how to implement?

If you’re comfortable with python, Threading works as outlined in the python3 documentation, as well as passing information back and forth via threadsafe queues - I would highly recommend switching to the new experimental (2019.30790) as the python version has jumped to 3.7.2. The only real ‘gotcha’ I encountered was when trying to run Threads from an extension, I had to write the code for the threads in an inline function inside of the function that creates the Threads, and not a separate function at the extension level, because Touch automatically inserts ‘self’ as the first argument for any extension functions, which breaks the way Threaded functions are called.

I can suggest an easier approach that I use for controllers I connect to via serial - just run a separate TouchDesigner process to handle the controller (or in your case led controller) logic, and feed information from a different TouchDesigner process via sharedmem, spout/syphon, or udp/tcp. This gives you much more flexibility and over all stability for your system, with the trade off of more complexity in managing both processes and how they communicate.

Hey Jonathan, thanks for this. Yea at this point I’ve been thinking about sending the data to a separate C++ app to handle the serial writing. A trickier part of the problem is the serial devices only have a 2048 byte buffer per port and the driver blocks until all data is written if you try to send a larger packet of data. I’ve already implemented chunked-write-by-buffer-size that is probably easier to reuse than to try and reimplement in Touch I think.

However, per your comment on python threading in touch, I wanted to ask: everything I’ve seen thus far has said to not interact with Touch objects from your threads as it’s not threadsafe. Essentially the core of what needs to happen in my thread is an op('serialN').sendBytes(...) - isn’t that asking for trouble? Have you been doing that without issue?

You are right. You would need to do the whole interaction with a python library.