Build an embedded system RGB LED Blinker with Rust on ESP32 using ESP-IDF

Zacchaeus Oluwole
3 min readSep 17, 2023

Introduction

In the world of embedded systems development, the ESP-IDF (Espressif IoT Development Framework) is a popular choice for building applications for ESP32 and ESP8266 microcontrollers. In this article, we’ll explore how to create a simple RGB LED blinker using ESP-IDF, leveraging its capabilities for GPIO control and task management.

Who this article is for

This article is for anyone who has experience in Rust, embedded systems and electronics. But for those without prior knowledge, I recommend:

  1. Learn Rust programming language.
  2. Write and run Rust program in a personal computer.
  3. Learn embedded systems development and electronics.

Requirements

Before we get started, make sure you have the following prerequisites in place:

  1. ESP32 development board.
  2. Rust programming environment set up.
  3. RGB LED.
  4. Basic knowledge of Rust programming and embedded system.

Setting Up the Project/Generate the project template

We’ll create a Rust project for our RGB LED blinker using ESP-IDF. Ensure that you have the necessary Rust environment set up with ESP-IDF support. You can use the esp-idf-sys crate to access the ESP-IDF functionalities from Rust. In this article, we will be using ESP-IDF-Template.

Install the prerequisites here and enter the command below to generate the project template or check here.

cargo generate esp-rs/esp-idf-template cargo

Now, let’s begin the code explanation.

1. Importing Dependencies

use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use log::*;

use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::gpio::*;
use esp_idf_hal::peripherals::Peripherals;

In the code snippet above, we import the required crates and modules for our project, including GPIO control and FreeRTOS-based delays.

2. Initializing the Logger and link_patches

We’ll use the log crate to log messages, making it easier to debug our application. Initialize the logger like this:

esp_idf_sys::link_patches();
esp_idf_svc::log::EspLogger::initialize_default();

esp_idf_sys::link_patches(); is a necessary initialization step when developing with ESP-IDF in Rust, as it ensures that your Rust code can interact with the ESP-IDF system correctly and take full advantage of the hardware features provided by the microcontroller.

3. Configuring GPIO Pins

Next, we need to configure the GPIO pins to control the RGB LED. We assume that you have connected the RGB LED to GPIO pins 2 (Red), 4 (Green), and 5 (Blue). We’ll set these pins as outputs.

let peripherals = Peripherals::take().unwrap();
let mut r_pin = PinDriver::output(peripherals.pins.gpio2).expect("Error: Unable to set pin(r) gpio2 Output");
let mut g_pin = PinDriver::output(peripherals.pins.gpio4).expect("Error: Unable to set pin(g) gpio4 Output");
let mut b_pin = PinDriver::output(peripherals.pins.gpio5).expect("Error: Unable to set pin(b) gpio5 Output");

4. Creating the LED Blinker Loop

Now comes the fun part — creating the LED blinker loop. We’ll alternate the colors of the RGB LED with one-second intervals.

loop{
r_pin.set_high().expect("Error: Unable to set pin r high");
FreeRtos::delay_ms(1000);
r_pin.set_low().expect("Error: Unable to set pin r low");
g_pin.set_high().expect("Error: Unable to set pin g high");
FreeRtos::delay_ms(1000);
g_pin.set_low().expect("Error: Unable to set pin g low");
b_pin.set_high().expect("Error: Unable to set pin b high");
FreeRtos::delay_ms(1000);
b_pin.set_low().expect("Error: Unable to set pin b low");
}

In the loop, we sequentially turn on the Red, Green, and Blue LEDs, each for one second, and then turn them off. This creates a simple RGB LED blinker effect.

Get the complete code here

5. Install Rust & Clang toolchains for Espressif SoCs (with espup)

In the project directory, run the following commands:

espup install
.~/export-esp.sh

6. Building and Flashing the Project

To build and flash your project onto your ESP32 board, ensure that you are in the root of the generated project and use the commands below:

cargo build
espflash flash target/xtensa-esp32-espidf/debug/your-project-name

7. Conclusion

In this article, we’ve learned how to create a simple RGB LED blinker using Rust and ESP-IDF. We configured GPIO pins, set up the LED blinker loop, and created a basic embedded application. You can extend this project by adding more complex LED patterns or integrating other sensors and modules. ESP-IDF and Rust provide a powerful combination for embedded systems development, allowing you to build robust and efficient applications for your microcontroller projects.

If you’d like to see the result in action, check out this YouTube video demonstrating the RGB LED blinker project on an ESP32 board. Happy coding!

--

--

Zacchaeus Oluwole

Software & IoT developer || Dart/Flutter & Rust 🦀 || Mobile, Desktop, Web || Backend, Embedded Systems, Network || 🧑‍💻