WS2812B_STM32F4 icon indicating copy to clipboard operation
WS2812B_STM32F4 copied to clipboard

I have a problem when there is more to 5 strip.

Open Jeriomas opened this issue 6 years ago • 5 comments

Welcome. Has anyone tried this library on 16 channels? Works well when set to 5 channels. If more than 5 then 6, 7, 8 is left stuck. And when set 8 strips, start to work all wrong. Also on channel 16. When you ignite one pixel, a few more pixels creams light up around it. Maybe someone had this problem? I use 170 pixels i one strip, STM32f407vg.

Jeriomas avatar Jan 12 '20 21:01 Jeriomas

Hello, I tested it with 16 channels and few other people are also running their projects with F407 and morethan 8 strips.

  • Did you changed anything, is the uneditect code from repository working ok?
  • In case of different code please share complete project so I could check everything
  • What is your system clock frequency?
  • What is your compialtion optimization level?
  • In case of other IRQs in your code you have to set the DMA IRQ as the highest priority
  • In case of other DMA channels in use you have to lower their DMA priority.
  • Do you have proper level shifters from 3V to 5V?

hubmartin avatar Jan 13 '20 23:01 hubmartin

Hello everyone,

I also have a similar problem. I have 3 led strip per channel, using 16 channels in a nucleo F439ZI dev board.

Till 7 channels it's working fine, from there to 16 channels the problem starts to happen with some leds lighting up with a random color (I'm using PORTF).

Answering your first 3 questions:

  • Yes, I'm using stm32cubeIDE and unfortunately the code doesn't compile right as it is. I change the extern keyword from .cpp to .h in WS2812_Struct ws2812b to be able to compile. After that, if you wish I can send you the codifications I made.

  • I'm still trying your main code, I just implement a snake pattern to make some experiments.

  • HCLK / Cortex / FCLK: 168MHz APB1 periph: 42MHz APB1 Timer: 84MHz APB2 periph: 84MHz APB2 Timer: 168MHz
    48MHz Clock: 48MHz

FabioVasconcelos22 avatar Apr 06 '22 09:04 FabioVasconcelos22

Some code:

ws2812.h

// GPIO enable command
#define WS2812B_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
// LED outpualthought port
#define WS2812B_PORT GPIOF
// LED output pins
#define WS2812B_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)
// How many LEDs are in the series - only valid multiples by two
#define WS2812B_NUMBER_OF_LEDS 3

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

visEffect.c

// RGB Framebuffers
uint8_t frameBuffer[3*WS2812B_NUMBER_OF_LEDS];
uint8_t frameBuffer2[3*WS2812B_NUMBER_OF_LEDS];
uint8_t frameBuffer3[3*WS2812B_NUMBER_OF_LEDS];
uint8_t frameBuffer4[3*WS2812B_NUMBER_OF_LEDS];

(...)

void createChannel (uint8_t channel, uint8_t * buffer, uint32_t size) {
	// If you need more parallel LED strips, increase the WS2812_BUFFER_COUNT value
	ws2812b.item[channel].channel = channel;
	// Your RGB framebuffer
	ws2812b.item[channel].frameBufferPointer = buffer;
	// RAW size of framebuffer
	ws2812b.item[channel].frameBufferSize = size;
}

(...)
void visInit()
{
  createChannel (0, frameBuffer, sizeof(frameBuffer));
  createChannel (1, frameBuffer, sizeof(frameBuffer));
  createChannel (2, frameBuffer, sizeof(frameBuffer));
  createChannel (3, frameBuffer, sizeof(frameBuffer));
  createChannel (4, frameBuffer2, sizeof(frameBuffer2));
  createChannel (5, frameBuffer2, sizeof(frameBuffer2));
  createChannel (6, frameBuffer2, sizeof(frameBuffer2));
  createChannel (7, frameBuffer2, sizeof(frameBuffer2));
  createChannel (8, frameBuffer3, sizeof(frameBuffer3));
  createChannel (9, frameBuffer3, sizeof(frameBuffer3));
  createChannel (10, frameBuffer3, sizeof(frameBuffer3));
  createChannel (11, frameBuffer3, sizeof(frameBuffer3));
  createChannel (12, frameBuffer4, sizeof(frameBuffer4));
  createChannel (13, frameBuffer4, sizeof(frameBuffer4));
  createChannel (14, frameBuffer4, sizeof(frameBuffer4));
  createChannel (15, frameBuffer4, sizeof(frameBuffer4));

ws2812b_init();
}

FabioVasconcelos22 avatar Apr 06 '22 11:04 FabioVasconcelos22

Hi, unfortunatelly I'm not able to fully support this code anymore on large numbers of MCUs and IDEs. But if it is working reliable on lower number of strips, then issues with more outputs could be because DMAs/IRQs cannot fill data in time because of priorities or low computing power (code optimizations). Please check and let me know:

  • What is your compialtion optimization level? -O1,2,3,s ?
  • In case of other IRQs in your code you have to set the DMA IRQ as the highest priority
  • In case of other DMA channels in use you have to lower their DMA priority.

hubmartin avatar Apr 07 '22 16:04 hubmartin

I noticed that WS2812B_NUMBER_OF_LEDS has a comment that it needs to be even number, not sure why after all those years :)

hubmartin avatar Apr 07 '22 16:04 hubmartin