Makuna / NeoPixelBus

An Arduino NeoPixel support library supporting a large variety of individually addressable LEDs. Please refer to the Wiki for more details. Please use the GitHub Discussions to ask questions as the GitHub Issues feature is used for bug tracking.
GNU Lesser General Public License v3.0
1.17k stars 259 forks source link

Using APA-106 LEDs fails to update pixels correctly, Esp8266 with DMA mode fails but BitBang is ok #280

Closed dwalker-uk closed 5 years ago

dwalker-uk commented 5 years ago

Minimal example code shown below - basically, in BitBang mode this works as expected with 2 pixels. In my original DMA mode, only one of the LEDs (the first) changes - nothing makes it way through to the second pixel. No physical changes at all between the two tests - just re-flashing the same board in place without touching the LEDs. (With Arduino IDE 1.8.9, NeoPixelBus 2.5.0, ESP 2.5.2)

#include <NeoPixelBus.h>

NeoPixelBus<NeoRgbFeature, NeoEsp8266Dma800KbpsMethod>* neoPixelRgbDma;
NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod>* neoPixelRgbBitBang;

RgbColor myColour(50, 0, 0);

void setup() {
//  neoPixelRgbDma = new NeoPixelBus<NeoRgbFeature, NeoEsp8266Dma800KbpsMethod>(2);
//  neoPixelRgbDma->Begin();
//  neoPixelRgbDma->ClearTo(myColour);  
//  neoPixelRgbDma->Show();
  neoPixelRgbBitBang = new NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod>(2, 3);
  neoPixelRgbBitBang->Begin();
  neoPixelRgbBitBang->ClearTo(myColour);
  neoPixelRgbBitBang->Show();
}

void loop() {
}

Any ideas? Setting pixel count to 3 rather than 2 doesn't make a difference.

Makuna commented 5 years ago

I will look deeper when I get some time in the next few days.

What Freq are you setting the esp8266 to run at?

Something to try, increase the count of LEDs in the constructor (doesn't matter if you actually have more physical LEDs attached) and see if it still doesn't work as expected. Start with 4 and increment up to 8 or when the problem goes away.

Then try moving the show to the loop rather than from setup.
NOTE, internally, it tracks if the pixels are "dirty" and will skip doing the actual data send if the pixels have not changed. This means two things for this test. You must remove the call to Show from setup (as this will mark it clean) and calling Show in the loop multiple times will actually only send the data once, since it was marked clean after the first time and you won't dirty it.

Makuna commented 5 years ago

AND, not sure ClearTo has anything to do with this issue.
If you call SetPixelColor twice instead, it should act the same

dwalker-uk commented 5 years ago

Hi, so I’ve found the issue... I think mostly my fault, but does expose an oddity worth highlighting for others between the DMA and BitBang methods.

I’m using a mix of WS2812, WS2813, and APA-106 (in 5mm through-hole format) pixels. I’ve been swapping the colour mode (between NeoRgbFeature and NeoGrbFeature) but always using the NeoEsp8266xxxxx800KbpsMethod’s.

The problem occurs (for me) in that the 800KbpsMethod doesn’t work beyond the first pixel if they’re APA-106 pixels, if using DMA mode - though BitBang is fine. Switching to the 400KbpsMethod version seems to work perfectly in both cases. Which is a little odd, as both Methods (DMA and BitBang) should as I understand it be putting out exactly the same signal with the same timing...? But also that the spec sheet for the APA-106 suggests it works at up to 800KHz, which I assume meant 800Kbps mode - though maybe that’s a wrong assumption.

Anyway, long story short is that it works now, in 400Mbps mode, but might be a useful tip to add to the documentation that APA-106 should be treated as 400Mbps if having issues.

Also, just to answer your earlier questions, I’m running at 80MHz, moving even up to 8 pixels in the constructor doesn’t make a difference, and you’re right that SetPixelColor does exactly the same so ClearTo was a red herring. I also tried moving Show to the loop, and looping around three different colours every 1/2sec, but made no difference. Though very occasionally the 2nd pixel would change - most times to the correct colour, but sometimes to something random.

Makuna commented 5 years ago

You may not have noticed, but 800KbpsMethod is the older style methods, and there are chip specific methods, like NeoWs2813Method, NeoWs2812xMethod, and NeoSk6812Method. There is not a chip specific for the APA106 yet.

Looking at the spec, the APA106 does have different timing than other similar LEDs. Not by much though. But it might be just enough to put signal out of spec for it. An example, the 1 bit high pulse and 0 bit low pulse needs to be 1.2us - 1.5us for the APA106; this is long compared to other LEDs and is not what is actually sent. Normally the 1 bit high is about 800us. The opposite pulses are the same as others. This explains why slowing down to 400mhz solves the problem.

I am leaving this open, as I want to track the ability to adjust the pulse to support these APA106 at full comms speeds.

NOTE: When the spec states internal frequency of 800mhz, this means the frequency that it PWM the actual LEDs to obtain desired brightness and color, not the communications speed.

dwalker-uk commented 5 years ago

Brilliant thank you, super supportive and knowledgeable as ever!

I've just installed my prototype 2-LED string in the garden (mostly to test its waterproofness), but with your response above means I'm completely happy that the circuit is right now so can start finalising the PCB and making up my waterproof string of pixels.

Thanks!

Makuna commented 5 years ago

https://github.com/Makuna/NeoPixelBus/pull/281

Makuna commented 5 years ago

2.5.1