· Stm32  · 4 min read

Getting Started with STM32 Nucleo-L433 and PlatformIO: C++ Development with VS Code

If you're exploring embedded C++ development on the STM32 Nucleo-L433RC-P board and want a modern, lightweight alternative to STM32CubeIDE, PlatformIO inside Visual Studio Code offers a fast and flexible workflow. This guide shows how to set up your environment, build your first firmware, and write clean, object-oriented code in C++ using the STM32Cube HAL framework.

If you’re exploring embedded C++ development on the STM32 Nucleo-L433RC-P board and want a modern, lightweight alternative to STM32CubeIDE, PlatformIO inside Visual Studio Code offers a fast and flexible workflow. This guide shows how to set up your environment, build your first firmware, and write clean, object-oriented code in C++ using the STM32Cube HAL framework.


Why Use PlatformIO Instead of STM32CubeIDE

STM32CubeIDE is useful for quick starts, but it’s Eclipse-based and can feel heavy and rigid. PlatformIO provides a lightweight, modern experience that integrates seamlessly into Visual Studio Code. It offers:

  • Better project structure for C++ development
  • Simple dependency management
  • Integration with Git and CI/CD tools
  • Compatibility with STM32Cube HAL for low-level control

This makes it well-suited for both prototyping and production firmware.


Prerequisites

Before you begin, make sure you have:

  • STM32 Nucleo-L433RC-P development board
  • Visual Studio Code installed on your system
  • PlatformIO extension for VS Code
  • STM32 ST-LINK USB drivers installed

Installing PlatformIO in VS Code

Open Visual Studio Code and navigate to the Extensions view. Search for “PlatformIO IDE” and install it. Once installed, you’ll see a PlatformIO alien head icon in the sidebar. Clicking it brings up the PlatformIO Home screen where you manage projects and boards.


Creating a New PlatformIO Project

Inside PlatformIO Home, click “New Project.” Give your project a name like stm32l433-cpp-blink. Select the board nucleo_l433rc_p and choose the STM32Cube framework. Click “Finish” to create the project.

PlatformIO will set up a clean directory structure:

stm32l433-cpp-blink/
├── include/         # Header files
├── lib/             # Optional libraries
├── src/             # C++ source files (place main.cpp here)
├── platformio.ini   # Project configuration

This layout makes it easy to organize classes and reusable code.


Inside the src folder, replace the contents of main.cpp with the following code:

#include "stm32l4xx.h"

#define LED_PIN                                GPIO_PIN_13
#define LED_GPIO_PORT                          GPIOB
#define LED_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()

int main(void)
{
  HAL_Init();
  
  LED_GPIO_CLK_ENABLE();
  
  GPIO_InitTypeDef GPIO_InitStruct;
  
  GPIO_InitStruct.Pin = LED_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct); 

  while (1)
  {
    HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN);
    
    HAL_Delay(1000);
  }
}

// Wrap the interrupt handler declarations in extern "C" to ensure they use C linkage and match the names expected by the STM32 startup code.
extern "C" {
    void SysTick_Handler(void) {
        HAL_IncTick();
    }

    void NMI_Handler(void) {
    }

    void HardFault_Handler(void) {
        while (1) {}
    }

    void MemManage_Handler(void) {
        while (1) {}
    }

    void BusFault_Handler(void) {
        while (1) {}
    }

    void UsageFault_Handler(void) {
        while (1) {}
    }

    void SVC_Handler(void) {
    }

    void DebugMon_Handler(void) {
    }

    void PendSV_Handler(void) {
    }
}

This toggles the LED on pin PA5 every 1 second.


Configuring platformio.ini

Edit your platformio.ini file to configure the build environment for STM32L433 with C++17:

[env:nucleo_l433rc_p]
platform = ststm32
board = nucleo_l433rc_p
framework = stm32cube
upload_protocol = stlink
build_flags = 
  -std=c++17
  -Wall

This tells PlatformIO to build with the STM32Cube HAL and upload firmware over the ST-LINK interface.


Building and Uploading Firmware

Click the checkmark icon in the bottom status bar to build the firmware. Click the right-arrow icon to upload it to your Nucleo board.

If everything is set up correctly, the on-board LED should blink every second.


Writing a C++ Class to Control the LED

For better structure, create a Blinker class to encapsulate LED control.

Create src/blinker.hpp:

#pragma once
#include "stm32l4xx_hal.h"

class Blinker {
public:
    Blinker(GPIO_TypeDef* port, uint16_t pin);
    void toggle();

private:
    GPIO_TypeDef* _port;
    uint16_t _pin;
};

And src/blinker.cpp:

#include "blinker.hpp"

Blinker::Blinker(GPIO_TypeDef* port, uint16_t pin) : _port(port), _pin(pin) {}

void Blinker::toggle() {
    HAL_GPIO_TogglePin(_port, _pin);
}

Update main.cpp to use your new class:

#include "stm32l4xx.h"
#include "blinker.hpp"

#define LED_PIN                                GPIO_PIN_13
#define LED_GPIO_PORT                          GPIOB
#define LED_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()

int main(void) {
    HAL_Init();
    
    LED_GPIO_CLK_ENABLE();
    
    GPIO_InitTypeDef GPIO_InitStruct;
    
    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct); 

    Blinker led(GPIOB, GPIO_PIN_13);

    while (1) {
        led.toggle();
        HAL_Delay(500);
    }
}

/// interrupt handlers as above

This keeps your logic cleaner and makes it easier to expand your project later.


Conclusion

Using PlatformIO with VS Code for STM32 Nucleo-L433 development creates a clean and modern workflow, perfect for writing modular and testable C++ firmware. Instead of relying on automatically generated code, you build your own startup and clock configuration, gaining a deeper understanding of how STM32 MCUs work.

This approach scales well for larger projects, integrates easily with Git, and gives you full control over how your firmware is organized. You’re now ready to move on to more advanced projects, like using FreeRTOS, I2C sensors, or building custom drivers in C++.

    Related articles

    View All Articles »

    Mastering C++ for Embedded Systems with STM32: Sending Hello World over UART Using PlatformIO

    This tutorial introduces modern C++ techniques in embedded development using an STM32 microcontroller and PlatformIO. You'll learn how to send Hello World over UART while applying essential C++ features such as classes, constructors, const, volatile, namespaces, and more. By encapsulating hardware access in a UART class, you'll build cleaner, safer, and more maintainable firmware — all without relying on dynamic memory allocation. Perfect for embedded developers looking to level up their C++ skills and structure their code more effectively.

    Toggling LEDs with Buttons Using STM32 and C++

    Learn how to build a classic embedded project — toggling an LED with a push button — while introducing key C++ concepts like classes, constructors, and encapsulation. This beginner-friendly guide uses STM32 HAL with PlatformIO and Visual Studio Code, showing how to organize low-level hardware control into clean, reusable C++ classes for better maintainability.

    STM32 Nucleo Embedded C++ Learning Roadmap with PlatformIO and VS Code

    Discover how to master STM32 Nucleo development using modern C++ and the powerful PlatformIO + VS Code toolchain. This practical roadmap guides you from blinking an LED to building real-world applications like data loggers, sensor interfaces, and multitasking systems with FreeRTOS. Whether you're new to embedded programming or moving from C to C++, learn to write clean, maintainable code, abstract hardware with classes, handle interrupts, and integrate peripheral interfaces—all without vendor lock-in. Perfect for makers, students, and engineers ready to level up their embedded skills using professional tools.

    Getting started with STM32 Nucleo 64 using STM32CubeIDE

    The STM32 Nucleo-64 (L433RC-P) is a powerful and accessible development board for prototyping and developing embedded applications. In this blog post, we’ll guide you through the essentials of getting started with the Nucleo-64 using STM32CubeIDE. From exploring the board’s components and pinouts to setting up the development environment and building a sample project, this tutorial provides a hands-on approach to mastering the STM32 ecosystem. Whether you’re new to STM32 or looking to streamline your workflow, this guide will help you unlock the potential of the Nucleo-64 for your next embedded project.