Alright, so I've searched just about everywhere to find an answer to this and I've personally experimented a lot to try and find a solution.
The error I'm experiencing is Neopixel (WS2812B 12ct LED ring) flicker using the NeoPixel library (this is a requirement for the project. Otherwise I would use FastLED and see if that has the same issues)
The following is my setup: ESP32s (Node mcu brand esp32) using the Arduino IDE 3.7v LiPo OR USB power 2x WS2812B rings on pins 25/26 (i've also tried 16/17)
I have a LiPo battery hooked up in parallel with all the components (ESP32 on 5v pin, and both strips separately) with a proper shared ground. This hardware setup worked 100% perfectly when I use an Arduino CH340 Nano 3.3v + Adafruit BLE module separately.
What I've discovered is that the flickering ONLY occurs on patterns where I'm doing division on the pixel color. I.E. a fade or two color fade. Otherwise, in patterns like a Rainbow cycle or a simple Colorwipe, it works perfectly with no flickering on any pixel whatsoever. Occasionally, and much more rarely I get a similar issue when bitshifting to dim the color. The weirdest part is that after the pattern has run for 3 or 4 cycles, it "evens out" and stops flickering. The reason this is weird is that I'm not rebooting the board between patterns. I have an android bluetooth app I cooked up to send Serial BLE signals as a controller. So switching between my patterns, they all look great until I switch to a fading one.
void FadeUpdate()
{
uint16_t stepUp = (TotalSteps + 1);
uint8_t red = ((Red(Color1) * (stepUp - Index))) / stepUp;
uint8_t green = ((Green(Color1) * (stepUp - Index))) / stepUp;
uint8_t blue = ((Blue(Color1) * (stepUp - Index))) / stepUp;
ColorSet(Color(red, green, blue));
show();
Increment();
}
void TwoColorFadeUpdate()
{
// Calculate linear interpolation between Color1 and Color2
// Optimise order of operations to minimize truncation error
uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;
ColorSet(Color(red, green, blue));
show();
Increment();
}
uint32_t DimColor(uint32_t color)
{
// Shift R, G and B components one bit to the right
uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
return dimColor;
}
Blue, Green, and Red all just do bit shifting on the uint32_t to grab the uint8_t representation of that color portion
TotalSteps and Index are both a uint16_t (I tried uint32_t as well)
This leads me to believe that my pixel flicking issue is due to some kind of odd rounding error
Things I've tried:
- delay(1);
- portDISABLE_INTERRUPTS();
- casting to int instead of uint32_t for my colors
The first two actually did help slightly, and considering that the pixels flickering are the same ones, depending on the pattern (E.G. pixel 7 and 9 will flicker with X and Y pattern when Fade, but on TwoColorFade it will be pixel 1 and 8) this leads me to believe this could also be some kind of timing error as well.
Things I haven't tried yet:
- Attaching the vin of the pixels to the 3v3 pin on the board.
- Logic level shifter.
- Setting the board clock frequency
I have NOT tried these things yet because the code executes perfectly on the nano, which is also a 3.3v board. I want to test changing the clock frequency but that's next on my list of stuff to test.
I can also post my code, but its split across multiple .ino files because im a novice at Arduino dev, but I still want some organization in my project.
ColorSet(Color(red, green, blue));
to something likeColorSet(Color(red, 0, 0));
to see if it is just one color that flickers \$\endgroup\$