Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32F401 - Can only get a solid white light #12

Open
robin7331 opened this issue Mar 29, 2021 · 4 comments
Open

STM32F401 - Can only get a solid white light #12

robin7331 opened this issue Mar 29, 2021 · 4 comments

Comments

@robin7331
Copy link

robin7331 commented Mar 29, 2021

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.

Screenshot 2021-03-29 at 09 12 37

DATA_IN is directly connected to PB1 of the STM32.

The only modifications I have done to your code so far are those here 👇

// GPIO enable command
#define WS2812B_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()

// LED output port
#define WS2812B_PORT GPIOB
// LED output pins
#define WS2812B_PINS (GPIO_PIN_1)
// How many LEDs are in the series - only valid multiples by two
#define WS2812B_NUMBER_OF_LEDS 12

// Number of paralel output LED strips. Each has its own buffer.
// Supports up to 16 outputs on a single GPIO port
#define WS2812_BUFFER_COUNT 1

My problem is that those LEDs are only lighting up in bright white.
No animation no nothing.

IMG_1934
(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() or DMA_TransferHalfHandler() I can confirm that those are being called.

Also the two visHandle() and visInit() methods are called properly.
Screenshot 2021-03-29 at 09 22 40

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!

@robin7331
Copy link
Author

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?

Screenshot 2021-03-30 at 09 45 21

@hubmartin
Copy link
Owner

hubmartin commented Apr 15, 2021

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

@hubmartin
Copy link
Owner

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.

@Treeed
Copy link

Treeed commented Feb 17, 2023

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.

How to fix this if you want to change the active pins:

  • set 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.
  • set WS2812_BUFFER_COUNT to the number of pins you will be using, no matter how they are distributed along the port
  • set ws2812b.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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants