Docs

Micro-controllers, wireless transmission and database

Head

WS2812 NeoPixel addressable LED with Blue Pill using STM32CubeIDE

Prerequisites

This project assumes you have already installed STM32CubeIDE. You need to have previously done a basic blink sketch with blue-pill using STM32CubeIDE. I have made a complete video from installing STM32CubeIDE to LED blink program. You can watch it by clicking this link. https://www.youtube.com/watch?v=kXg467nVd_A

Wiring Diagram

Diagram

Transmitter Module

STM32CubeIDE Settings

Click RCC → High Speed Clock (HSE) to Crystal/Ceramic Resonator

Click Clock Configuration tab → HCLK (MHz) to 72

Click Pinout and Configuration tab

Click Timer → Click TIM3 →

Clock Source set to Internal Clock

Channel1 set to PWM Generation CH1

Configuration → Parameter Settings →

Prescaler set to 30-1

Counter Period 3-1

Click DMA Settings tab Click add button

Select TIM3_CH1 and Select Memory to Peripheral

Keep Data width Half Word

------------- Test Code ------------

    uint16_t pwmData[384]; //16*24=384 (No of LEDs 16 and 24 Pulses for each LED)
    for (int i=0; i<384; i++) pwmData[i] = 2;
    HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)pwmData, 384);
    HAL_Delay (10);
    HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1);
    HAL_Delay (500);
    for (int i=0; i<384; i++) pwmData[i] = 1;
    HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)pwmData, 384);
    HAL_Delay (10);
    HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1);
    HAL_Delay (500);

------------- END Test Code ------------

Additional code on top of STM32CubeIDE generated code (main.c)

/* USER CODE BEGIN 0 */
#define noOfLEDs 16
uint16_t pwmData[24*noOfLEDs];

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1);
    htim3.Instance->CCR1 = 0;
}

void resetAllLED (void)
{
    for (int i=0; i<24*noOfLEDs; i++) pwmData[i] = 1;
}

void setAllLED (void)
{
    for (int i=0; i<24*noOfLEDs; i++) pwmData[i] = 2;
}

void setLED (int LEDposition, int Red, int Green, int Blue)
{
    for (int i=7; i>=0; i--) // Set the first 8 out of 24 to green
    {
        pwmData[24*LEDposition + 7 - i] = ((Green >> i) & 1) + 1;
    }
    for (int i=7; i>=0; i--) // Set the second 8 out of 24 to red
    {
        pwmData[24*LEDposition + 15 - i] = ((Red >> i) & 1) + 1;
    }
    for (int i=7; i>=0; i--) // Set the third 8 out of 24 to blue
    {
        pwmData[24*LEDposition + 23 - i] = ((Blue >> i) & 1) + 1;
    }
}

void ws2812Send(void)
{
    HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)pwmData, 24*noOfLEDs);
}
/* USER CODE END 0 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    resetAllLED();
    ws2812Send();
    setLED(0, 255, 0, 0);     // Red
    ws2812Send();
    HAL_Delay (500);
    setLED(1, 0, 255, 0);     // Green
    ws2812Send();
    HAL_Delay (500);
    setLED(2, 0, 0, 255);     // Blue
    ws2812Send();
    HAL_Delay (500);
    setLED(3, 255, 255, 0);   // Yellow
    ws2812Send();
    HAL_Delay (500);
    setLED(4, 0, 255, 255);   // Magenta
    ws2812Send();
    HAL_Delay (500);
    setLED(5, 255, 0, 255);   // Cyan
    ws2812Send();
    HAL_Delay (500);
    resetAllLED();
    ws2812Send();
    setLED(6, 255, 255, 255); // Specific color
    ws2812Send();
    HAL_Delay (3000);
    resetAllLED();
    ws2812Send();
    for (int i=255; i>0; i--) // Set brighness for red (Dimm)
    {
        setLED(7, i, 0, 0);
        ws2812Send();
        HAL_Delay (20);
    }
    for (int i=0; i<255; i++) // Set brighness for green (Up)
    {
        setLED(7, 0, i, 0);
        ws2812Send();
        HAL_Delay (20);
    }
    for (int i=255; i>0; i--) // Set brighness for blue (Dimm)
    {
        setLED(7, 0, 0, i);
        ws2812Send();
        HAL_Delay (20);
    }
    /* USER CODE END WHILE */