Open robin7331 opened 3 years ago
Update: Just hooked up my logic analyzer. Coincidentally it has a protocol analyzer for the LED protocol. It seems like my MCU is sending all white. For every LED.| Any idea why?
Hi,
did you set correctly the framebuffer? Try to set framebuffer to some value and comment out the animating effects.
Can you see that the data is exactly for 12 LEDs you set in WS2812B_NUMBER_OF_LEDS
?
Is the systick and the HAL_GetTick working correctly? does the code gets inside this if block? https://github.com/hubmartin/WS2812B_STM32F4/blob/master/Src/visEffect.c#L109
If the IRQs are triggered and its generating correct waveform with white color, then the core code works fine and it seems like the issue is really in assingning the data to the buffer.
So you have to set some data to frameBuffer
or frameBuffer2
to something like
frameBuffer[0] = 0xff;
frameBuffer[1] = 0x00;
frameBuffer[2] = 0x00;
to set RED (or maybe blue color,since WS2812 has BGR if I' not mistaken)
Do not forget to disable/comment visHandle2
which does animation and would rewrite your framebuffer values
https://github.com/hubmartin/WS2812B_STM32F4/blob/master/Src/visEffect.c#L163
Also check that your level shifter works correctly. I always used proper push-pull driver, not sure how fast that 10k pull-up resistor is. Check that with analog oscilloscope. It might be fine but I would check that.
Just had the same issue and thought I'd quickly post the solution for anyone from the future:
The critical point is, that the channel
value does not correspond to the rank of the pins as given in WS2812B_PINS, but only to the pin number on the port.
What happened in this case is that reducing WS2812_BUFFER_COUNT
to 1 meant, that only the first element in the ws2812b
item list was still available, however, the visInit()
assigns items to pins 0 through 7 in order. Therefore, the only item (item 0) that was still active was assigned to pin 0 that was not only disabled, but also had nothing connected.
WS2812B_PINS
to the pin numbers that will be active, order doesn't matter. This is only a mask to activate the pins, it is not used after the init.WS2812_BUFFER_COUNT
to the number of pins you will be using, no matter how they are distributed along the portws2812b.item[n].channel
to the pin numbers you want to use. You have WS2812_BUFFER_COUNT
items ws2812b.item[n]
where n are the numbers 0
through WS2812_BUFFER_COUNT-1
. You can use these in any order you like. To configure item[3] to output data on PC12 set ws2812b.item[3].channel = 12
This is a valid configuration:
#define WS2812B_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define WS2812B_PORT GPIOB
#define WS2812B_PINS (GPIO_PIN_6 | GPIO_PIN_13 | GPIO_PIN_9)
#define WS2812B_NUMBER_OF_LEDS 12
#define WS2812_BUFFER_COUNT 3
...
ws2812b.item[0].channel = 9
...
ws2812b.item[1].channel = 6
...
ws2812b.item[2].channel = 13
This is not:
#define WS2812B_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define WS2812B_PORT GPIOB
#define WS2812B_PINS (GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_0)
#define WS2812B_NUMBER_OF_LEDS 12
#define WS2812_BUFFER_COUNT 4 //not the same number of buffers as pins
...
ws2812b.item[0].channel = 1 //pin PB1 is not active!
...
ws2812b.item[1].channel = 2` //pin PB2 is not active!
...
ws2812b.item[2].channel = 3` //this will output data on PB3
...
ws2812b.item[3].channel = 0 //this will output data on PB0
...
ws2812b.item[4].channel = 2 //you have only activated 4 channels, this would be the fifth (also, don't repeat pin numbers)
Another thing while I'm at it:
The library doesn't compile anymore with newer compilers, it throws <long path>\tools\arm-none-eabi\bin\ld.exe: ./Core/Src/ws2812b.o:<long path>/ws2812b.h:88: multiple definition of 'ws2812b'; ./Core/Src/blink_controller.o:<long path>/ws2812b.h:88: first defined here
instead.
To fix it change line 20 of ws2812b.c to WS2812_Struct ws2812b;
and line 88 of ws2812b.h to extern WS2812_Struct ws2812b;
(basically swapping the lines).
Hey! I like your approach of using DMA and a timer to generate the signal. However, I cannot achieve the rainbow or Christmas animation with my current setup.
I left your DMA channel/stream configuration as it is since I do not need TIM1 or this DMA configuration elsewhere.
My setup contains 12 chained
WS2812-2020
LEDs. The PCB on which they are mounted to has a 5v and a 3v3 supply. The LEDs are driven by 5v and that data signal has a level shifter to connect to the 3v3 GPIO pin of the STM32F4.DATA_IN
is directly connected toPB1
of the STM32.The only modifications I have done to your code so far are those here 👇
My problem is that those LEDs are only lighting up in bright white. No animation no nothing.
(every button has a pair of two leds. But all 12 LEDs are chained. There is only one Data-In for the entire module)
When I set breakpoints into the
DMA_TransferCompleteHandler()
orDMA_TransferHalfHandler()
I can confirm that those are being called.Also the two
visHandle()
andvisInit()
methods are called properly.Having the white lights turned on means that the communication works. If there was an issue with the GPIO pin, DMA or Timers I would see nothing.. right?
Thanks for your help!