DEV Community

Cover image for Embedded Rust on the ESP32 : Interfacing Button with ESP32
Vaishnav-sabari-girish
Vaishnav-sabari-girish

Posted on

Embedded Rust on the ESP32 : Interfacing Button with ESP32

In my previous blog, we blinked an LED.

Now, we shall interface a button (inbuilt Flash Button), which is connected to GPOI0 to read button presses.

Getting Started

Let us create our new project

esp-generate --chip=esp32 button_press
Enter fullscreen mode Exit fullscreen mode

Open src/bin/main.rs file and type the below code

#![no_std]
#![no_main]
#![deny(
    clippy::mem_forget,
    reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
    holding buffers for the duration of a data transfer."
)]

use esp_backtrace as _;
use esp_hal::{
    delay::Delay,
    gpio::Level,
    gpio::{Input, InputConfig},
    gpio::{Output, OutputConfig},
    main
};
use esp_println::println;
esp_bootloader_esp_idf::esp_app_desc!();

#[main]
fn main() -> ! {
    let peripherals = esp_hal::init(esp_hal::Config::default());
    let mut led = Output::new(peripherals.GPIO2, Level::Low, OutputConfig::default());
    let button = Input::new(peripherals.GPIO0, InputConfig::default());
    let delay = Delay::new();

    loop {
        if button.is_low() {
            led.set_high();
            println!("Button Pressed");
            delay.delay_millis(50);

        }
        else {
            led.set_low();
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Into the Code : Line-by-line explanation

#![no_std] 
Enter fullscreen mode Exit fullscreen mode
  • Removes the standard library to suit bare-metal embedded systems.
#![no_main] 
Enter fullscreen mode Exit fullscreen mode
  • Disables Rust's default entry point, enabling use of a custom embedded main function.
#![deny(
    clippy::mem_forget,
    reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
    holding buffers for the duration of a data transfer."
)] 
Enter fullscreen mode Exit fullscreen mode
  • Prevents using mem::forget, which can cause resource leaks with peripherals like GPIOs.
use esp_backtrace as _; 
Enter fullscreen mode Exit fullscreen mode
  • Provides support for backtraces during panics, aiding debugging.
use esp_hal::{
    delay::Delay,
    gpio::Level,
    gpio::{Input, InputConfig},
    gpio::{Output, OutputConfig},
    main,
}; 
Enter fullscreen mode Exit fullscreen mode
  • Brings in delay functionality, GPIO level enums, input/output pin types, and the custom entry macro.
use esp_println::println; 
Enter fullscreen mode Exit fullscreen mode
  • Enables logging via println!, useful for debugging over serial.
esp_bootloader_esp_idf::esp_app_desc!(); 
Enter fullscreen mode Exit fullscreen mode
  • Embeds metadata (app version, timestamp, etc.) into the firmware.

#[main]
fn main() -> ! {
Enter fullscreen mode Exit fullscreen mode
  • Entry point of the application. Uses -> ! since it loops forever.
    let peripherals = esp_hal::init(esp_hal::Config::default());
Enter fullscreen mode Exit fullscreen mode
  • Initializes peripherals using default configuration.
    let mut led = Output::new(peripherals.GPIO2, Level::Low, OutputConfig::default());
Enter fullscreen mode Exit fullscreen mode
  • Configures GPIO2 as an output pin, initially set to Low (LED off).
    let button = Input::new(peripherals.GPIO0, InputConfig::default());
Enter fullscreen mode Exit fullscreen mode
  • Configures GPIO0 as an input pin (for reading a button's state).
    let delay = Delay::new();
Enter fullscreen mode Exit fullscreen mode
  • Initializes a delay instance for blocking waits.
    loop {
Enter fullscreen mode Exit fullscreen mode
  • Begins an infinite loop to continuously check the button and control the LED.
        if button.is_low() {
Enter fullscreen mode Exit fullscreen mode
  • Checks if the button is pressed (logic Low, assuming pull-up setup).
            led.set_high();
Enter fullscreen mode Exit fullscreen mode
  • Turns the LED on.
            println!("Button Pressed");
Enter fullscreen mode Exit fullscreen mode
  • Logs button press to serial console.
            delay.delay_millis(50);
Enter fullscreen mode Exit fullscreen mode
  • Adds a small delay for button debounce.
        }
        else {
            led.set_low();
        }
Enter fullscreen mode Exit fullscreen mode
  • If the button is not pressed, turns the LED off.
    }
}
Enter fullscreen mode Exit fullscreen mode

Outputs

Terminal Output

terminal op

Hardware Output


Important Links

  1. Getting Started Blog
  2. Blinking an LED Blog
  3. GitHub Repository

Top comments (0)