Quick Start
Before diving into the theory and concepts of how everything works, let's jump straight into action. Use this simple code to turn on the onboard LED of the ESP32 DevKit.
Blink LED with ESP HAL
ESP HAL is "no_std Hardware Abstraction Layers for ESP32 microcontrollers"
Setup project
To start the project, use the esp-generate
command. Run the following:
esp-generate --chip esp32 blinky
This will open a screen asking you to select options. For now, we dont need to select any options. Just save it by pressing "s" in the keyboard.
Next, navigate to the project folder:
cd blinky
Open the src/bin/main.rs file. It will contain a simple "Hello, World" code. We will modify this code to blink an LED on the board.
Blinking Code
This code creates a blinking effect by toggling an LED connected to a GPIO pin between high and low states.
Import Required Module
Additional import we need to set the LED as output pin
#![allow(unused)] fn main() { use esp_hal::gpio::{Io, Level, Output}; }
Initialize ESP HAL peripherals
This code is already generated by the template. You have to change the "_peripherals" variable name to "peripherals".
#![allow(unused)] fn main() { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); }
Setup Output
Then lets set the LED GPIO pin "GPIO2" as an output pin with an initial state "High"(LED is turned on). The GPIO2 is the pin for the onboard LED.
#![allow(unused)] fn main() { let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default()); }
Helper function for delay
Let's write a small function to introduce a blocking delay that pauses execution for a specified duration.
#![allow(unused)] fn main() { fn blocking_delay(duration: Duration) { let delay_start = Instant::now(); while delay_start.elapsed() < duration {} } }
Blinking Loop
Create a loop to toggle the LED state(between High and Low).
#![allow(unused)] fn main() { loop { led.toggle(); blocking_delay(Duration::from_millis(500)); } }
The full code
#![no_std] #![no_main] use esp_hal::clock::CpuClock; use esp_hal::gpio::{Level, Output, OutputConfig}; use esp_hal::main; use esp_hal::time::{Duration, Instant}; #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } #[main] fn main() -> ! { // generator version: 0.3.1 let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); let mut led = Output::new(peripherals.GPIO2, Level::High, OutputConfig::default()); loop { led.toggle(); blocking_delay(Duration::from_millis(500)); } } fn blocking_delay(duration: Duration) { let delay_start = Instant::now(); while delay_start.elapsed() < duration {} }
Flash - Run Rust Run
All that's left is to flash the code onto our device and watch it go! The onboard LED should start blinking.
Run the following command from your project folder:
#![allow(unused)] fn main() { cargo run }
To run in release mode
#![allow(unused)] fn main() { cargo run --release }