cancel
Showing results for 
Search instead for 
Did you mean: 

WS2812B sporadic wrong color - DMA issue or?

KKjel.1
Senior

I have a custom designed board using a single WS2812B RGB LED.

I use the DMA to control, just as "all" examples and drivers use it.

Fairly simple, and it works as a charm.

99% of the time...

Symptom:

Once in while, it starts to show a wrong color.

Fx. if I want to blink 3 times yellow, it may show 1*white + 2*yellow. Or other variations.

Green sometimes get cyan-like.

Red may also show as white.

More rare: OFF shows as green.

The wrong color is not completely random: It is most often white (-ish), or it is the wanted color but in a brighter version.

The LED can work OK for hours, and suddenly fails for a couple of minutes. Then OK again.

Tests performed:

Checked with oscilloscope: The timing is spot-on, and the control signal is sharp and OK.

Debugged code = OK

Hardware/Software

STM32H730

WS2812B is driven and controlled directly form 3V3 supply and MCU pins

Also running other timer interrupts. Running FreeRTOS.

Possible causes:

I am running out of ideas where to search for the problem.

I have searched everywhere for similar problems, but can't find any.

Do you have any ideas in which direction I should go?

- Timing ?

- Supply voltage ?

- Or ?

Thanks in advance !

28 REPLIES 28

Yes, that is correct.

MCU and WS2812B is powered from the same 3V3.

I could try that.

AScha.3 suggests to insert 100 ohm in series with the signal, but I guess this is not sufficient, as it would result in less than 100 uV :)

I don't have access to our lab these days (tons of snow, so working from home...), but I can test the hardware changes maybe friday.

Oo...

AScha3_0-1704318362091.png

typ: 

AScha3_1-1704318417869.png

and

AScha3_2-1704318454197.png

cpu :

AScha3_3-1704318520264.png

--> so can you try: supply -> 3,6V for both. 

or 3v3 for cpu , but 4V for WSxx . 

Just to check, whether ds of WSxx is right or doesn't matter.

(When i was using WSxx , always drive from LiPo (~ 4V ) or 5V reg. and 5V - level cpu  => no problems)

If you feel a post has answered your question, please click "Accept as Solution".

Yes, I know we are a bit out of spec. We did consider this before making the design.

We tested a prototype, and searched for information.

The test worked, and other designs works fine with the 3V3 supply, so we decided to go for it.

We also only has this single WS2812B and very short traces.

 

The way it fails is not totally random. There is som kind of system in what happens.

The failing color is typically the same, but it is random when it happens.

If it was the power supply/signal voltage, I would expect a more distinct work/fail appearance.

 

That said, I am not too convinced, not until I find the problem :)

The typical way to operate the WS2812 is by DMA/PWM.

I generate an array of timer values for each bit, and the DMA controls a PWM signal on the pin.

If the application try to update the DMA before it is done, plus some extra time to let the WS2812 reset before next data, I simply ignore that update.

> If the application try to update the DMA before it is done, plus some extra time

How does the application know that update is not done yet?

One simple way to confirm if this may or may not be the source of problem is to toggle a GPIO pin whenever you make a change of the output array, and then on oscilloscope observe both this and the timer-to-LED-output waveform; using appropriate persistence setting or some advanced trigger mode to capture eventual violation.

> ... I simply ignore that update.

So, can't that be the reason of your problem? Say if you say do a fade, and you ignore the last change for this reason?

Of course there can be other software reasons, too. If you have a LA, you can try to capture a longer sequence, stopping when you see the error occurring, and then decode the last or few last output sequences manually.

JW


@KKjel.1 wrote:

I could try that.

 


I used a 10k linear pot (across the MCU signal out and GND, wiper to the WS Din).


@KKjel.1 wrote:

The typical way to operate the WS2812 is by DMA/PWM.

I generate an array of timer values for each bit, and the DMA controls a PWM signal on the pin.


Actually, this is quite bad and inefficient way of controlling WS2812. See these topics:

https://community.st.com/t5/stm32-mcus-products/stm32103-bluepill-bare-metal-ws2812b-neopixel-driver-no/m-p/622687#M230914

https://community.st.com/t5/stm32-mcus-products/ws2812-library-does-not-work-on-stm32f40/td-p/603041

Some tips for your timer+DMA:

Voltage levels - some WS2812 versions are sensitive to too-low logic high voltage. common tricks here are: powering the first WS2812 in a string via a diode to lower its voltage slightly or setting the output to open drain and using 1.5 kOhm resistor as pullup to 5 V.

Make sure that you output logic low of the proper duration as reset pulse - set PWM duty to 0 at the end of transfer and keep it at 0 until the next transfer.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Actually, this is quite bad and inefficient way of controlling WS2812. See these topics:

Why do you think DMA is inefficient? Almost no coding, and everything is handled in the background by the DMA controller, with no MCU load.

 

Make sure that you output logic low of the proper duration as reset pulse - set PWM duty to 0 at the end of transfer and keep it at 0 until the next transfer.


This might be interesting, because I have played around with the RESET periode after the GRB data:

The best result is actually with a single 1,25us, which is much lower than required (50us).

Very long periode, > 400us, showed extreme bad behavior. Spec says >280us, so anything above should not make it fail.

Using the correct 50-60us,  seems worse than 1,25 us.

My control signal turns HIGH after the RESET periode. The datasheet indicates this is OK. But you and some searching shows a LOW signal, but without mentioning if this is a must.

 

> Why do you think DMA is inefficient?

gbm did not say DMA is inefficient, in fact he's using DMA, too. What he says is inefficient is using timer to transmit data, he's using UART.

> Very long periode, > 400us, showed extreme bad behavior.

That in fact is a good starting point to debug. Find out, why. This indeed indicates problem with the control voltage/thresholds.

Also, reconsider ground arrangement - LEDs can draw significant current and the fact that there's a common "power ground" with the control signal return in effect lowers the control signal's voltage as seen by the LED controller.

Try to construct a level shifter of some sort.

JW