Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Board and library for 'simultaneous' sending and receiving DMX?

  1. #1
    Junior Member
    Join Date
    Aug 2020
    Posts
    5

    Board and library for 'simultaneous' sending and receiving DMX?

    Hello all,

    I want to receive DMX, remap/reprocess some values, then send DMX - in realtime. Assuming the processing is very lightweight, what most reliable approach?

    I have seen TeensyDMX which I would hope together with the 600Mhz Teensy 4 would do this.

    Any insights appreciated

    Cheers

  2. #2
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    518
    Haven't used the TeensyDMX library used myself but it seems mature, well documented and the author is active on this forum. Perhaps just give it a try?
    Found this thread on the forum where the author states it can be done using 2 serial ports.
    More threads can be found on this forum when searching for "TeensyDMX".

    Paul

  3. #3
    Senior Member
    Join Date
    Mar 2017
    Location
    Oakland, CA, USA
    Posts
    190
    Thanks, @PaulS. I just released TeensyDMX v4.1.0 and it works fine on the Teensy 4. I tested send, receive, and RDM. It should also be able to retransmit as you wish, per your question above.

    There's actually two ways to do it. The first is to continuously read values and send each received packet out the transmitter side. The second is event-based, where a handler is registered for packets having specific start codes; it would inform the main loop to then take the data and retransmit. The first is far simpler.

    Here's an over-built example that I haven't tested:
    Code:
    // 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;
        }
      }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •