Fundamentals 12 min read

Control a Three‑Color LED via Bluetooth Serial on STM32 – Step‑by‑Step Guide

This tutorial shows how to wire a three‑color LED to an STM32F103C8T6, configure a HC‑08 Bluetooth module for UART communication, and write C code that toggles each LED based on received keywords (green, yellow, red) using the STM32 HAL library.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Control a Three‑Color LED via Bluetooth Serial on STM32 – Step‑by‑Step Guide

Introduction

The article demonstrates a simple embedded project: using a Bluetooth serial connection to control a three‑color LED on an STM32F103C8T6 board. It walks through hardware wiring, UART configuration, and the required C code, allowing a smartphone to turn each LED on or off by sending specific keywords.

Prerequisites

Readers should be familiar with STM32 development basics, such as flashing firmware, using the MDK toolchain, and UART communication. The author provides links to introductory tutorials on flashing STM32, using MDK, and basic USART handling.

Project Requirements

The goal is to control three LEDs (green, yellow, red) via Bluetooth. When the phone sends the keyword green, the green LED toggles; yellow toggles the yellow LED; red toggles the red LED.

Hardware Wiring

The required components are:

STM32F103C8T6 development board

HC‑08 Bluetooth module

Three‑color LED module

USB‑to‑TTL serial adapter

ST‑LINK V2 programmer

Connections are summarized in the table below (VCC, RXD, TXD, GND, and LED pins). The ST‑LINK V2 pins (SWCLK, SWDIO, GND, 3.3V) are also wired accordingly.

LED Initialization Code

void led_init(void) {
    GPIO_InitTypeDef gpio_init_struct;
    LED1_GPIO_CLK_ENABLE();
    LED2_GPIO_CLK_ENABLE();
    LED3_GPIO_CLK_ENABLE();

    gpio_init_struct.Pin = LED1_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init_struct.Pull = GPIO_PULLUP;
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);

    gpio_init_struct.Pin = LED2_GPIO_PIN;
    HAL_GPIO_Init(LED2_GPIO_PORT, &gpio_init_struct);

    gpio_init_struct.Pin = LED3_GPIO_PIN;
    HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct);

    LED1(0);
    LED2(0);
    LED3(0);
}

The accompanying led.h defines pin mappings and helper macros for turning LEDs on/off, toggling, and initializing.

Bluetooth UART Setup

UART_HandleTypeDef bt_uart_handle;
uint8_t bt_uart_rx_buf[BT_RX_BUF_SIZE];
uint8_t bt_uart_tx_buf[BT_TX_BUF_SIZE];
uint16_t bt_uart_rx_len = 0;

void bt_init(uint32_t baudrate) {
    bt_uart_handle.Instance = BT_INTERFACE;
    bt_uart_handle.Init.BaudRate = baudrate;
    bt_uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
    bt_uart_handle.Init.StopBits = UART_STOPBITS_1;
    bt_uart_handle.Init.Parity = UART_PARITY_NONE;
    bt_uart_handle.Init.Mode = UART_MODE_TX_RX;
    bt_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    bt_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&bt_uart_handle);
}

void bt_rx_clear(void) {
    memset(bt_uart_rx_buf, 0, sizeof(bt_uart_rx_buf));
    bt_uart_rx_len = 0;
}

void BT_IRQHandler(void) {
    uint8_t receive_data = 0;
    if (__HAL_UART_GET_FLAG(&bt_uart_handle, UART_FLAG_RXNE) != RESET) {
        if (bt_uart_rx_len >= sizeof(bt_uart_rx_buf)) {
            bt_uart_rx_len = 0;
        }
        HAL_UART_Receive(&bt_uart_handle, &receive_data, 1, 1000);
        bt_uart_rx_buf[bt_uart_rx_len++] = receive_data;
    }
    if (__HAL_UART_GET_FLAG(&bt_uart_handle, UART_FLAG_IDLE) != RESET) {
        printf("recv: %s
", bt_uart_rx_buf);
        control_led();
        bt_rx_clear();
        __HAL_UART_CLEAR_IDLEFLAG(&bt_uart_handle);
    }
}

void bt_send(char *fmt, ...) {
    va_list ap;
    uint16_t len;
    va_start(ap, fmt);
    vsprintf((char *)bt_uart_tx_buf, fmt, ap);
    va_end(ap);
    len = strlen((const char *)bt_uart_tx_buf);
    HAL_UART_Transmit(&bt_uart_handle, bt_uart_tx_buf, len, HAL_MAX_DELAY);
}

LED Control Logic

void control_led() {
    if (strstr((const char *)bt_uart_rx_buf, "green") != NULL) {
        LED1_TOGGLE();
    }
    if (strstr((const char *)bt_uart_rx_buf, "yellow") != NULL) {
        LED2_TOGGLE();
    }
    if (strstr((const char *)bt_uart_rx_buf, "red") != NULL) {
        LED3_TOGGLE();
    }
}

Main Function

int main(void) {
    HAL_Init();
    sys_stm32_clock_init(RCC_PLL_MUL9);
    delay_init(72);
    usart_init(115200);
    bt_init(9600);
    led_init();
    printf("蓝牙控制灯……
");
    while (1) {
        bt_send("bt send
");
        delay_ms(1000);
    }
}

Running the Demo

After flashing the firmware, connect the board to a PC via USB and open a serial terminal at 115200 bps to view debug output. Pair the HC‑08 module with a smartphone Bluetooth assistant app, then send the keywords green, yellow, or red. The corresponding LED toggles, and the terminal prints the received command.

Conclusion

The guide provides a complete end‑to‑end example of integrating Bluetooth UART communication with hardware control on an STM32 platform, laying a foundation for more advanced IoT or smart‑home projects.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BluetoothembeddedC programmingSTM32UARTHardware TutorialLED control
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.