I'm using a Teensy 3.2 with the pjrc library 'WS2812,' and was able to reproduce my problem with only the example codes. I'm running Teensyduino 1.4.8 on Arduino 1.8.9
I have added a few lines of code to time the 'leds.show()' function as well as report it to the console, and an additional delay (typically not necessary) to be absolutely sure the function is not getting called too fast (I know it will stall if the previous transfer is incomplete). I also changed the number of LEDs from 64 to 384, the number I am working with. Otherwise the example is unmodified, and my strip of lights still animates as expected (the extra delay slows the animation slightly).
I am seeing a return time that depends on the number of leds (!!), and that gets as high as 1200us with 384 leds (the number I am working with), but is still as high as 200us with 64 leds (the default).
I have found this blocking time changes by as much as a factor of 2 based on the compile options (384 leds ranges from 600us to 1200us), though I don't pretend to really know what those options are changing.
When I hacked up the library to add a bunch of intermediary timer variables, it looked like all the time was spent during the phase denoted
. The rest of the steps added up to less than 8uS.
I guess that means this is a soft blocking function, since I'd still be able to interrupt it during that time, which makes it more useful than other neopixel libraries, but it still caught me a little off guard that the leds.show() function takes nearly as long to return as other common neopixel libraries (it's a few times faster).
I guess what I'm trying to ask is: is this delay a hard limitation of the library? Would it be feasible to do the buffer copy in the background, a bit at a time?
I have added a few lines of code to time the 'leds.show()' function as well as report it to the console, and an additional delay (typically not necessary) to be absolutely sure the function is not getting called too fast (I know it will stall if the previous transfer is incomplete). I also changed the number of LEDs from 64 to 384, the number I am working with. Otherwise the example is unmodified, and my strip of lights still animates as expected (the extra delay slows the animation slightly).
I am seeing a return time that depends on the number of leds (!!), and that gets as high as 1200us with 384 leds (the number I am working with), but is still as high as 200us with 64 leds (the default).
I have found this blocking time changes by as much as a factor of 2 based on the compile options (384 leds ranges from 600us to 1200us), though I don't pretend to really know what those options are changing.
When I hacked up the library to add a bunch of intermediary timer variables, it looked like all the time was spent during the phase denoted
Code:
// copy drawing buffer to frame buffer
I guess that means this is a soft blocking function, since I'd still be able to interrupt it during that time, which makes it more useful than other neopixel libraries, but it still caught me a little off guard that the leds.show() function takes nearly as long to return as other common neopixel libraries (it's a few times faster).
I guess what I'm trying to ask is: is this delay a hard limitation of the library? Would it be feasible to do the buffer copy in the background, a bit at a time?
Code:
/* WS2812Serial BasicTest Example
Test LEDs by turning then 7 different colors.
This example code is in the public domain. */
#include <WS2812Serial.h>
const int numled = 384;
const int pin = 1;
// Usable pins:
// Teensy LC: 1, 4, 5, 24
// Teensy 3.2: 1, 5, 8, 10, 31 (overclock to 120 MHz for pin 8)
// Teensy 3.5: 1, 5, 8, 10, 26, 32, 33, 48
// Teensy 3.6: 1, 5, 8, 10, 26, 32, 33
byte drawingMemory[numled*3]; // 3 bytes per LED
DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED
unsigned long lngTime0 = 0;
unsigned long lngTime1 = 0;
WS2812Serial leds(numled, displayMemory, drawingMemory, pin, WS2812_GRB);
#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 setup() {
leds.begin();
Serial.begin(1000000);
}
void loop() {
// change all the LEDs in 1.5 seconds
int microsec = 1500000 / leds.numPixels();
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);
lngTime0 = micros();
leds.show();
lngTime1 = micros();
Serial.println(lngTime1-lngTime0);
delay(20);
delayMicroseconds(wait);
}
}