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

Thread: TeensyDMX and FastLED - cant get them to work simultaneously

  1. #1

    TeensyDMX and FastLED - cant get them to work simultaneously

    Hi All,

    I am currently setting up my new project to drive some WS2815 LED strips using incoming DMX data.

    I'm using the TeensyDMX library to read the incoming DMX data, and driving the FastLED from the incoming values.

    I know the setup is working as i have used the BasicReceive example and working perfectly - the serial monitor is correctly showing any change in channel 1 data and channel 10, 11 & 12.

    I have also created a super basic "moving dot" sketch for driving the LEDs with FastLED, this also works perfectly.

    However, when i come to add the "moving dot" sketch into the BasicReceive sketch to use the values to change the dots colour, it doesnt work - the lights flicker int he right direction like its trying to do the moving dot (but they do change colour according to DMX data), and serial monitor does show the right values however after a significant lag and erratic. Its seems that the teensy is unable to drive the WS2815 LEDs and ALSO receive the serial data at the same time.

    I have included the code below:

    Code:
    #include <FastLED.h>
    #define DATA_PIN  8
    
    #define NUM_LEDS_PER_STRIP 72
    #define NUM_STRIPS 1
    #define NUM_LEDS   NUM_LEDS_PER_STRIP  
    CRGB leds[NUM_LEDS_PER_STRIP * NUM_STRIPS];
    
    volatile byte r1 = 255;
    volatile byte g1 = 255;
    volatile byte b1 = 0;
    
    
    #include <cstring>
    #include <TeensyDMX.h>
    namespace teensydmx = ::qindesign::teensydmx;
    
    // Create the DMX receiver on Serial1.
    teensydmx::Receiver dmxRx{Serial1};
    
    // The last value on the channel, for knowing when to print a change
    // (Example 1).
    uint8_t lastValue = 0;
    
    // Buffer in which to store packet data (Example 2).
    uint8_t packetBuf[3]{0};
    
    // The last values received on channels 10-12, initialized to zero.
    uint8_t rgb[3]{0};
    
    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 BasicReceive.");
    
      // Turn on the LED, for indicating activity
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWriteFast(LED_BUILTIN, HIGH);
    
      // Start the receiver
      dmxRx.begin();
    
      // Print the first values
      lastValue = dmxRx.get(1);
      Serial.printf("Channel 1: %d\n", lastValue);
    
      // Note: If this reads < 3 bytes then the other values will stay at zero
      // (because 'rgb' was initialized to zero, above)
      dmxRx.readPacket(rgb, 10, 3);
      Serial.printf("RGB: %d %d %d\n", rgb[0], rgb[1], rgb[2]);
    
    
    FastLED.addLeds<NUM_STRIPS, WS2812B,DATA_PIN,GRB>(leds, NUM_LEDS_PER_STRIP);
    
      
    }
    
    void loop() {
      // The following two examples print values when they change
    
      // Example 1. Get the current value of channel 1.
      // This will return zero for no data (and also for data that's zero)
      uint8_t v = dmxRx.get(1);
      if (v != lastValue) {
        lastValue = v;
        Serial.printf("Channel 1: %d\n", v);
      }
    
      // Example 2. Read channels 10-12.
      // A return of -1 means no data, and a value < 3 means that there was data,
      // but the received packet wasn't large enough to contain channels 10-12
      int read = dmxRx.readPacket(packetBuf, 10, 3);
      if (read == 3) {
        if (memcmp(packetBuf, rgb, 3) != 0) {
          memcpy(rgb, packetBuf, 3);
          Serial.printf("RGB: %d %d %d\n", rgb[0], rgb[1], rgb[2]);
        }
      }
    
    
    
      for(int dot = 0; dot < NUM_LEDS; dot++) { 
                leds[dot].r = rgb[0];
                leds[dot].g = rgb[1];
                leds[dot].b = rgb[2];
                FastLED.show();
                
                // clear this led for the next time around the loop
                leds[dot].r = 0;
                leds[dot].g = 0;
                leds[dot].b = 0;
                delay(50);
            }
    }

  2. #2
    Member
    Join Date
    Apr 2020
    Location
    Germany, NRW
    Posts
    85
    You could do a quick test and add

    __disable_irq();

    before FastLED.show();

    and

    __enable_irq();

    after. In my experiments it has shown that the WS2815 strips are very timing sensitive.

Posting Permissions

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