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

Thread: OctoWS2811 with Teensy 4.1 Pinlist only supports 8 strips when using GRBW

  1. #1
    Junior Member
    Join Date
    Dec 2018
    Posts
    11

    OctoWS2811 with Teensy 4.1 Pinlist only supports 8 strips when using GRBW

    I am enjoying the additions of GRBW support and non-default pin lists for the OctoWS2811 library. I believe I have found that when using 4 channel GBRW LED strips and using a non-default pinlist, it appears that the pinlist has a max length of 8 pins. I have tested GRB strips up to the 28 PWM pins on the front of the 4.1 and that works fine. But if I go from 8 to 9 pins in the pinlist with
    const int config = WS2811_GRBW | WS2811_800kHz;
    then all of a sudden my oscilloscope sees only noise.

    Expected: adding one more pin I would see one more pin with signal on my oscilloscope.
    Observed: Adding one more pin with a GRBW setup makes all pins stop producing signal. With 3 LED channels the expected behavior is observed.

    Other notes and steps to reproduce:
    Using non standard pinlists works fine with <=8 strips for both 3 and 4 led channels. They do not have to be default pins, that makes no difference.
    I am using Teensyduino 1.54-beta5 and OctoWS2811 on the master branch from https://github.com/PaulStoffregen/OctoWS2811, most recently updated on 12/5. Please see the code examples below:

    The following fails to produce a signal on the output pins and is the problematic case:
    Code:
    #include <OctoWS2811.h>
    
    // NOTE THE 9 digital pins
    const int numPins = 9;
    byte pinList[numPins] = {2,3,4,5,6,7,8,9,10};
    const int ledsPerStrip = 20;
    
    // GRBW memory amounts
    DMAMEM int displayMemory[ledsPerStrip*8]; // 8 ints is 32 bytes
    int drawingMemory[ledsPerStrip*8]; // RGBW needs 32 bytes, RGB needs only 24
    // 4 channels of led color
    const int config = WS2811_GRBW | WS2811_800kHz;
    
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config, numPins, pinList);
    //OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    void setup() {
      leds.begin();
      leds.show();
    }
    
    void loop() {
      int microsec = 2000000 / leds.numPixels();  // change them all in 2 seconds
      # Note that the same thing happens with the standard colorWipe method
      colorCheck(microsec);
    }
    
    void colorCheck(int wait)
    {
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 10, 0, 0, 0); //Make then all Red at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 10, 0, 0); //Make then all Green at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 0, 10, 0); //Make then all Blue at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 10, 10, 10, 0); //Make then all Blue at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 0, 0, 10); //Make then all White at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
    }
    Howerver if I reduce the pinlist by 1, down to 8 then everything works as expected.
    The following fails to produce a signal on the output pins:
    Code:
    #include <OctoWS2811.h>
    
    // It works when assigning only 8 digital pins
    const int numPins = 8;
    byte pinList[numPins] = {3,4,5,6,7,8,9,10};
    const int ledsPerStrip = 20;
    
    // GRBW memory amounts
    DMAMEM int displayMemory[ledsPerStrip*8]; // 8 ints is 32 bytes
    int drawingMemory[ledsPerStrip*8]; // RGBW needs 32 bytes, RGB needs only 24
    // 4 channels of led color
    const int config = WS2811_GRBW | WS2811_800kHz;
    
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config, numPins, pinList);
    //OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    void setup() {
      leds.begin();
      leds.show();
    }
    
    void loop() {
      int microsec = 2000000 / leds.numPixels();  // change them all in 2 seconds
      // Note that the same thing happens with the standard colorWipe method
      colorCheck(microsec);
    }
    
    void colorCheck(int wait)
    {
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 10, 0, 0, 0); //Make then all Red at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 10, 0, 0); //Make then all Green at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 0, 10, 0); //Make then all Blue at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 10, 10, 10, 0); //Make then all Blue at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, 0, 0, 0, 10); //Make then all White at 10%
        leds.show();
        delayMicroseconds(wait);
      }
      delayMicroseconds(wait);
    }
    And for completeness, here is working code with GRB AND 28 pins:
    Code:
    #include <OctoWS2811.h>
    
    // Any group of digital pins may be used
    const int numPins = 28;
    byte pinList[numPins] = {0,1,2,3,4,5,6,7,8,9,10,11,12,24,25,28,29,13,14,15,18,19,22,23,33,36,37};
    
    const int ledsPerStrip = 120;
    
    // These buffers need to be large enough for all the pixels.
    // The total number of pixels is "ledsPerStrip * numPins".
    // Each pixel needs 3 bytes, so multiply by 3.  An "int" is
    // 4 bytes, so divide by 4.  The array is created using "int"
    // so the compiler will align it to 32 bit memory.
    DMAMEM int displayMemory[ledsPerStrip * numPins * 3 / 4];
    int drawingMemory[ledsPerStrip * numPins * 3 / 4];
    
    const int config = WS2811_GRB | WS2811_800kHz;
    
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config, numPins, pinList);
    
    void setup() {
      leds.begin();
      leds.show();
    }
    
    #define RED    0xFF0000
    #define GREEN  0x00FF00
    #define BLUE   0x0000FF
    #define YELLOW 0xFFFF00
    #define PINK   0xFF1088
    #define ORANGE 0xE05800
    #define WHITE  0xFFFFFF
    
    // Less intense...
    /*
    #define RED    0x160000
    #define GREEN  0x001600
    #define BLUE   0x000016
    #define YELLOW 0x101400
    #define PINK   0x120009
    #define ORANGE 0x100400
    #define WHITE  0x101010
    */
    
    void loop() {
      int microsec = 2000000 / leds.numPixels();  // change them all in 2 seconds
    
      // uncomment for voltage controlled speed
      // millisec = analogRead(A9) / 40;
    
      colorWipe(RED, microsec);
      colorWipe(GREEN, microsec);
      colorWipe(BLUE, microsec);
      colorWipe(YELLOW, microsec);
      colorWipe(PINK, microsec);
      colorWipe(ORANGE, microsec);
      colorWipe(WHITE, microsec);
    }
    
    void colorWipe(int color, int wait)
    {
      for (int i=0; i < leds.numPixels(); i++) {
        leds.setPixel(i, color);
        leds.show();
        delayMicroseconds(wait);
      }
    }

  2. #2
    Junior Member
    Join Date
    Dec 2018
    Posts
    11
    Update: I would love someone else to review this, but modifying the memory allocations solves the issue in my test cases with 5, 9 and 28 strips and a GRBW configuration. Note that this also matches the comments for 3 LED channel strips, eg RGB in the OctoWS2811 example Teensy4_PinList.ino.

    Previously in the examples:

    Code:
    // GRBW memory amounts
    DMAMEM int displayMemory[ledsPerStrip*8]; // 8 ints is 32 bytes
    int drawingMemory[ledsPerStrip*8]; // RGBW needs 32 bytes, RGB needs only 24
    Proposed modification:

    Code:
    DMAMEM int displayMemory[ledsPerStrip * numPins]; // Make the memory allocation dynamic based on the number of strips
    int drawingMemory[ledsPerStrip * numPins];        // In case of RBG strips these formulas should be multiplied by 3 / 4, i.e. ledsPerStrip * numPins * 3 / 4

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,977
    I've updated the pinlist example.

    https://github.com/PaulStoffregen/Oc...78013f833a6216

Posting Permissions

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