Teensy 4.0 WS2812 slow.

Hi.

I've had a search on here but couldn't find the answer to my question.

This is my first time using a Teensy and I only know enough about coding to be dangerous so apologies if I am making some stupid mistake.

I am working on a project that needs lights and sound, after some research I decided to try a Teensy 4.0 with the Rev D audio board and some Neopixels.

I'm just at the stage of connecting bits together on a breadboard and getting some basic code running.

I am using a 74ahct125 between the Teensy and the pixels.

I downloaded the WS2812Serial - Non-Blocking WS2812B / NeoPixel LEDs Library and loaded and started playing with the examples.

After a bit of time i realised that the 7 pixels i had running seems to be updating slower than I remembered when using them with a Arduino.

I wrote some code that lights all the pixels at full red then dims it, from 255 - 0, without adding any delays.

The results were that my Arduino Nano is able to light and dim the 7 pixels around 8 times a second whereas the simular code running on the Teensy can only do the same around twice a second.

If there were and differences I would have expected the Teensy to be faster that the Nano rather than the other way round.

Is this some limitation on the non-blocking library or do I have a problem somewhere?

Program running on the Teensy.
Code:
#include "Arduino.h"
#include <WS2812Serial.h>

const int numled = 7;
const int pin = 1;

byte drawingMemory[numled*3];         //  3 bytes per LED
DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED

WS2812Serial leds(numled, displayMemory, drawingMemory, pin, WS2812_GRB);

void setup() {
  leds.begin();
}

void test(int hue) {
  for(int i=0;i<leds.numPixels();i++){
    leds.setPixel(i, hue,0,0);
  }
  leds.show();
}

void loop() {
  for(int i=255;i>=0;i--){
    test(i);
  }
}

Program running on the Nano.
Code:
#include <Adafruit_NeoPixel.h>
#define PIN            3

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      7

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);



void setup() {
  pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {
  for(int i=255;i>=0;i--){
    test(i);
  }
}

void test(int hue) {
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(hue,0,0));
  }
  pixels.show(); // This sends the updated pixel color to the hardware.
}

Any help of tips greatly appreciated.

Thanks.
 
Well i've tried a few other things.

If i use the OctoWS2811 library the Teensy now dims the pixels and the same speed the Nano does.

I'm only going to be running a couple of dozen pixels connected as a strip so the OctoWS2811 would seem to be extremely overkill as well as using up a lot of pins I could be using for other things.

Code using the Octo library for reference.
Code:
#include <OctoWS2811.h>

const int ledsPerStrip = 7;

DMAMEM int displayMemory[ledsPerStrip*6];
int drawingMemory[ledsPerStrip*6];

const int config = WS2811_GRB | WS2811_800kHz;

OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);

void setup() {
  leds.begin();
  leds.show();
}


void loop() {
  for(int i=255;i>=0;i--){
    test(i);
  }
}

void test(int hue) {
  for(int i=0;i<leds.numPixels();i++){
    leds.setPixel(i, hue,0,0);
  }
  leds.show();
  
}
 
Thanks for the suggestion.

Unfortunately that was something I have already tried with no change.

Code:
#include "Arduino.h"
#include <WS2812Serial.h>
#define USE_WS2812SERIAL
#include <FastLED.h>

const int numled = 7;
const int pin = 1;

//byte drawingMemory[numled*3];         //  3 bytes per LED
//DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED

// Define the array of leds
CRGB leds[numled];

//WS2812Serial leds(numled, displayMemory, drawingMemory, pin, WS2812_GRB);

void setup() {
  //leds.begin();

  LEDS.addLeds<WS2812SERIAL,pin,RGB>(leds,numled);

}

void test(int hue) {
  for(int i=0;i<numled;i++){
    leds[i].setRGB( hue, 0, 0);
  }
  FastLED.show();
  
}

void loop() {
  for(int i=255;i>=0;i--){
    test(i);
  }
}

I'm now in a catch 22 position where I am not sure if the slower updating of the pixels is likely to cause me any issues further down the line but I don't want to put lots of time into writing my code to find it wouldn't work requiring me to look at different controllers and audio boards etc.
 
Why not just use the same code you have shown for the Nano in the Teensy 4.0? It will also run faster.

You also don't have to use the Octo2811 adapter to use the Octo2811 library. The adapter is basically just replacing your 74AHCT125 plus throwing in a 100 ohm series resistor.
 
The code on the Nano is using the Adafruit Neopixel library.

From what i read online, because I am also going to be using the audio library I needed to use the non-blocking WS2812 library.

Here's the excerpt from the WS2812 library I am referring to.

Non-blocking allows other libraries, especially Audio and high speed serial communication to function properly while the LEDs update. Complex animation can also run faster, because the show() function does not wait for the LEDs to update, allowing your code more time to draw the next frame.

Although that seems to be at odd to what I am seeing as the show() function seems to be taking quite a bit longer in my case.

Also, in regards to the Octo2811 library, I am assuming that, by default, it takes control of all the pins listed in the example program which would reduce the amount of spare I/O's i have available. I'm also not sure is this would affect the audio board in anyway either.

Code:
  Required Connections
  --------------------
    pin 2:  LED Strip #1    OctoWS2811 drives 8 LED Strips.
    pin 14: LED strip #2    All 8 are the same length.
    pin 7:  LED strip #3
    pin 8:  LED strip #4    A 100 ohm resistor should used
    pin 6:  LED strip #5    between each Teensy pin and the
    pin 20: LED strip #6    wire to the LED strip, to minimize
    pin 21: LED strip #7    high frequency ringining & noise.
    pin 5:  LED strip #8
    pin 15 & 16 - Connect together, but do not use
    pin 4 - Do not use
    pin 3 - Do not use as PWM.  Normal use is ok.
 
Gotcha, I glossed over the fact that you were also going to use the Audio Adapter.

I made one project that used the Audio Adapter and and was also running WS2812 LEDs and ran into the blocking issue. In my case I found that it worked easier/better to just use a separate mini MP3/WAV file player rather than use the Audio Adapter, so I didn't spend much time trying to get the two to play nicely together.

You can select the number of pins and which pins you want to use with the Octo2811 library. There is an example that illustrates the use of that - File/Examples/OctoWS2811/Teensy4_PinList
 
Looking into this today. Indeed it is much slower. Tracked it down to this line in WS2812Serial::show()

Code:
        if (min_elapsed < 2500) min_elapsed = 2500;

I believe this is a leftover from the days when some WS2812 would do strange things if updated faster than their approx 450 Hz PWM rate. It limits the library from updating faster than 400 Hz. This limit can only come into play with short LED strips. With 74 or more LEDs, the 800 kbps data rate limits the refresh speed to slower than 400 Hz.

Maybe it's time to just get rid of this old limit...
 
works for me on simple set up with chain of ws2812bs, was 640ms a cycle now 130ms

typo on link above should be https://github.com/PaulStoffregen/WS2812Serial/commit/74c469ec35153639a6f9609c2e433bbf391c74c8

t4.jpg
 
Back
Top