There are several libraries for asynchronous DMX, where the driver basically freewheels in the background to produce a constant spew of the latest values, and the user code simply pokes new values in at random and moves on. That's fine for a general-purpose project that's easy to code, and has some pretty lax timing requirements (even at worst-case 44Hz, a human is not going to notice), but I have a more complex project that does raise some concerns about overall latency, and so each individual component gets squeezed tighter than it would by itself.
Essentially:
I want that entire chain to be as fast as possible, so if the user decides to use a soft button on a touchscreen, all the way at the start of the chain, instead of a physical button attached to the Teensy, it still feels at least somewhat responsive. Or an audio lowpass in the same off-the-shelf PC DMX Controller to connect a strobe to the kick drum, etc.
Async effectively has random latency per frame, or possibly per channel, depending on how each library actually works, anywhere between zero and one full frame. I want as close to zero as possible, and constant. Thus, no transmission from the Teensy until a frame is received, so it's all ready to go immediately when it comes, then modify that one frame and send it out. Then no transmission until the next frame, etc. So the "easy to use" async libraries are probably not going to work for this.
The AVR at the end, automatically switches to its own stored data when its input stops, so that the fixtures' no-signal behavior is not triggered. When the AVR does have an incoming stream, it's transparent with 1 byte of latency. (just enough to read from the UART and stuff it back in again)
I also had thoughts of the Teensy being both an RDM master and slave on different ports, to talk to some fixtures and to respond to an upstream controller, but as I continue to lay things out, it looks more and more "not worth it", at least as a master, towards the fixtures. I'd have to get RDM past the AVR in both directions, for one thing...
Anyway, my first thought was to have a fully standards-compliant DMX stream from the Teensy, except that it's synchronous to the incoming data from the PC and therefore may stop at any time and that's okay. But I suspect the better solution would be to *require* the AVR downstream from it, to convert from my own standard into DMX in addition to providing that safety net.
Either way, I think I need a physical Serial driver on a Teensy 4.1 that can take a buffer of 513 bytes all at once (the Teensy's processing could modify anything, so I can't send any of it until that's done), send it immediately, break at the end, and stop there until the next buffer is available. Or it could break first and then send 513 bytes, and just run out of data and stop.
The break could be done by messing with the baud rate and transmitting a zero like the libraries do, or by a GPIO and an external AND with the TX pin.
Is there a library that already does that? Or if not, how hard is it to make one? No RX, just TX. Just break, and dump a buffer.
---
For a possible upstream DMX controller that connects to the Teensy and gets fed upstream from there to the PC Controller, it pretty much has to be async, and so the existing libraries are probably fine. Since that connection is pretty much standard, I wonder about allowing RDM *there*? And since RDM is *half-duplex*, I also wonder if I can break the rule about not using the same UART for both TX and RX?
As I understand, the reason that rule exists is because this hardware doesn't actually have a break character like some do. So to avoid using another pin, it changes the baud rate, transmits a zero, and changes it back. That completely wrecks reception, hence the rule, but again this is *half-duplex*. I'm not going to try to receive during a break.
Do the more mature DMX libraries support *that*? Half-duplex DMX/RDM on the same UART, plus a GPIO to control the direction of a transceiver chip? The README's and manuals aren't exactly clear about that, except to say "don't combine directions" and why, which leaves this question.
Essentially:
Code:
+----------------- PC -----------------+ +----- Teensy 4.1 -----+ +---------- AVR ----------+
| | | | | |
| network_loopback | | | | |
| | | USB_Serial | | UART | | DMX
| [DMX Controller] --> [Custom App] -------------------> [more processing] ------------> [capture and replay] ---------> [Fixtures]
| | | | | |
+--------------------------------------+ +----------------------+ +-------------------------+
I want that entire chain to be as fast as possible, so if the user decides to use a soft button on a touchscreen, all the way at the start of the chain, instead of a physical button attached to the Teensy, it still feels at least somewhat responsive. Or an audio lowpass in the same off-the-shelf PC DMX Controller to connect a strobe to the kick drum, etc.
Async effectively has random latency per frame, or possibly per channel, depending on how each library actually works, anywhere between zero and one full frame. I want as close to zero as possible, and constant. Thus, no transmission from the Teensy until a frame is received, so it's all ready to go immediately when it comes, then modify that one frame and send it out. Then no transmission until the next frame, etc. So the "easy to use" async libraries are probably not going to work for this.
The AVR at the end, automatically switches to its own stored data when its input stops, so that the fixtures' no-signal behavior is not triggered. When the AVR does have an incoming stream, it's transparent with 1 byte of latency. (just enough to read from the UART and stuff it back in again)
I also had thoughts of the Teensy being both an RDM master and slave on different ports, to talk to some fixtures and to respond to an upstream controller, but as I continue to lay things out, it looks more and more "not worth it", at least as a master, towards the fixtures. I'd have to get RDM past the AVR in both directions, for one thing...
Anyway, my first thought was to have a fully standards-compliant DMX stream from the Teensy, except that it's synchronous to the incoming data from the PC and therefore may stop at any time and that's okay. But I suspect the better solution would be to *require* the AVR downstream from it, to convert from my own standard into DMX in addition to providing that safety net.
Either way, I think I need a physical Serial driver on a Teensy 4.1 that can take a buffer of 513 bytes all at once (the Teensy's processing could modify anything, so I can't send any of it until that's done), send it immediately, break at the end, and stop there until the next buffer is available. Or it could break first and then send 513 bytes, and just run out of data and stop.
The break could be done by messing with the baud rate and transmitting a zero like the libraries do, or by a GPIO and an external AND with the TX pin.
Is there a library that already does that? Or if not, how hard is it to make one? No RX, just TX. Just break, and dump a buffer.
---
For a possible upstream DMX controller that connects to the Teensy and gets fed upstream from there to the PC Controller, it pretty much has to be async, and so the existing libraries are probably fine. Since that connection is pretty much standard, I wonder about allowing RDM *there*? And since RDM is *half-duplex*, I also wonder if I can break the rule about not using the same UART for both TX and RX?
As I understand, the reason that rule exists is because this hardware doesn't actually have a break character like some do. So to avoid using another pin, it changes the baud rate, transmits a zero, and changes it back. That completely wrecks reception, hence the rule, but again this is *half-duplex*. I'm not going to try to receive during a break.
Do the more mature DMX libraries support *that*? Half-duplex DMX/RDM on the same UART, plus a GPIO to control the direction of a transceiver chip? The README's and manuals aren't exactly clear about that, except to say "don't combine directions" and why, which leaves this question.