2025-03-26 10:21 AM
Hi everyone,
I'm having some strange issues with my ws2812b neopixels, and can't quite figure out what's causing them. Some color settings work perfectly, while others trigger this odd behaviour. Even weirder, certain fixes just seem to shift the issue to different color settings instead or resolving it entirely. And to make things more confusing - it doesn't happen every time.
When I send color data to my ws2812b, certain colors cause the first led to appear much brighter with an excessive amount of green. This happens only on the first led. No matter how many leds are in the chain, the rest display the correct colors. I've tested multiple ws2812b rings and strips, but the issue persists.
To rule out voltage level problems i added a level shifter to shift both, supply voltage and data line voltage to 5 volts. The problem remained, just brighter :) I can't quite put my finger on whats happening because it's just so bizarre.
I am using the nucleo stm32C071RB board. It works at 48MHz. I set the counter period to 60 (60-1) that leads to 1.25us for each bit (slight variations to the period have no effect). The T0H is 19 cycles high (0.395us) and the T1H is 38 cycles high (0.791us) - slight variations to the values have no effect. Changing reset time does not have any effects. Since I’m using DMA, I doubt it’s a timing issue.
Actual the issue appears when switching between red (r=102,g=b=0) and yellow (r=80,g=20,b=0) every 2 seconds. Red will be shown correctly but the yellow part shows the first led to bright with too much green. Therefore i got the issue by changing between red (r=100) and red (r=200) at r=200. Sometimes i even observe a strange cycle pattern:
1. All leds are red (right)
2. All yellow except the first which is too bright and green
3. All leds switch back to red, but too bright
4. All leds are yellow including the first one in the right color
This code transfers the data to dma. I've kept things simple for debugging purposes:
for (uint16_t index = 0; index < WS2812B_DMA_BUF_LEN; index++)
WS2812B_DMA_BUF[index] = 0;
uint16_t _bufIndex = 0;
for (uint16_t led = 0; led < START_LIGHTS; led++){
for (uint8_t greenIndex = 0; greenIndex < 8; greenIndex++){
if (WS2812B_DATA[led].g & (0x01 << (7-greenIndex)))
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T1H;
else
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T0H;
_bufIndex++;
}
for (uint8_t redIndex = 0; redIndex < 8; redIndex++){
if (WS2812B_DATA[led].r & (0x01 << (7-redIndex)))
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T1H;
else
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T0H;
_bufIndex++;
}
for (uint8_t blueIndex = 0; blueIndex < 8; blueIndex++){
if (WS2812B_DATA[led].b & (0x01 << (7-blueIndex)))
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T1H;
else
WS2812B_DMA_BUF[_bufIndex] = WS2812B_T0H;
_bufIndex++;
}
}
HAL_StatusTypeDef halStatus = HAL_TIM_PWM_Start_DMA(htim, TIM_CHANNEL_1, (uint32_t *) WS2812B_DMA_BUF, WS2812B_DMA_BUF_LEN);
I’d really appreciate any insights, suggestions, or experiences you can share. Thanks so much for your help!