// DMXRelay example program.
// This relays DMX data from a receiver to a transmitter,
// with some optional filtering and modification.
#include <TeensyDMX.h>
namespace teensydmx = ::qindesign::teensydmx;
// Timeout after which it's considered that DMX is no longer
// sending, in milliseconds.
constexpr uint32_t kDMXTimeout = 1000; // 1 second
// Create the DMX receiver on Serial1.
teensydmx::Receiver dmxRx{Serial1};
// Create the DMX sender on Serial1.
teensydmx::Sender dmxTx{Serial2};
// DMX input buffer.
uint8_t packetBuf[513]{0};
// Time since the last frame was received.
elapsedMillis lastFrameTimer = 0;
// Indicates whether we've seen a packet within the timeout.
bool connected = false;
void setup() {
// Serial initialization, for printing things
Serial.begin(115200);
while (!Serial && millis() < 4000) {
// Wait for initialization to complete or a time limit
}
Serial.println("Starting DMXRelay.");
// Use the LED to indicate activity
// You could also use the LED to indicate different modes,
// for example flashing or on or off to indicate active
// reception, etc.
pinMode(LED_BUILTIN, OUTPUT);
digitalWriteFast(LED_BUILTIN, LOW); // Start with the LED off
// Start the receiver
dmxRx.begin();
// Don't start the transmitter here because we may not yet
// be receiving any data
// Note: Everything happens asynchronously. This means
// that if data is set on the transmitter, it will
// keep transmitting the same thing until told
// otherwise.
}
void loop() {
// Try reading a packet
int read = dmxRx.readPacket(packetBuf, 0, 513);
if (read > 0) {
// A new packet was received
lastFrameTimer = 0; // Reset the timer to zero
// We want to transmit the same packet size that we
// received. Other options would be to set the remaining
// bytes to zero, track statistics, filter by start
// code, etc. There are many things you could do here.
if (read != dmxTx.packetSize()) {
// Atomically set the packet size
// We want to ensure the transmitted packet size
// matches the data, so ensure nothing happens
// between the two calls
__disable_irq();
dmxTx.setPacketSize(read);
dmxTx.set(0, packetBuf, read);
__enable_irq();
// Instead of this approach, you could also leave the
// packet at 513 bytes and just set anything past the
// end of the current received packet to zero
} else {
dmxTx.set(0, packetBuf, read);
}
}
// Connect or disconnect
if (lastFrameTimer <= kDMXTimeout) {
if (!connected) {
// Start up the transmitter
dmxTx.begin();
digitalWriteFast(LED_BUILTIN, HIGH);
connected = true;
}
} else {
if (connected) {
// Stop transmitting
// Another approach would be to just fill the output
// with all zeros instead of disabling the transmitter
dmxTx.end();
digitalWriteFast(LED_BUILTIN, LOW);
connected = false;
}
}
}