Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

esp32-rust-workspace

A bare-metal Rust workspace for ESP32 microcontroller projects using esp-hal with optional Embassy async support.

Overview

This project provides templates and examples for running Rust on an ESP32-WROOM-32 module without an operating system (no_std). It supports both blocking (synchronous) and async (Embassy) programming models.

Hardware

  • Target: ESP32 (Xtensa LX6 dual-core)
  • Module: ESP32-WROOM-32
  • Bootloader: esp-idf compatible

Prerequisites

  • Rust installed via rustup
  • USB cable for connecting to your ESP32 board

Development Environment Setup

1. Install the ESP Rust toolchain

cargo install espup --locked
espup install

2. Set up environment variables

For the current shell session:

. $HOME/export-esp.sh

To make it permanent, add to your shell config:

# For bash
echo '. $HOME/export-esp.sh' >> ~/.bashrc

# For zsh
echo '. $HOME/export-esp.sh' >> ~/.zshrc

3. Install development tools

# Flashing tool
cargo install espflash --locked

# Project generator (optional, for creating new projects)
cargo install esp-generate --locked

# Debugging tools (optional)
cargo install probe-rs-tools

Building and Flashing

Build the project

cargo build --release

Flash and run a specific binary

cargo run --release --bin test

This will compile, flash to the connected ESP32, and open a serial monitor.

Flash only (without monitor)

espflash flash target/xtensa-esp32-none-elf/release/<binary-name>

Monitor serial output

espflash monitor

Project Structure

esp32-rust-workspace/
├── Cargo.toml              # Project dependencies and binary definitions
├── build.rs                # Build script for linker configuration
├── rust-toolchain.toml     # Specifies the esp Rust toolchain
├── docs/                   # Documentation
│   ├── std-vs-no_std.md
│   ├── converting-to-embassy.md
│   ├── rust-macros.md
│   ├── esp32-pinout-reference.md
│   ├── esp32-cheatsheet.md
│   ├── rust-cheatsheet.md
│   └── rust-project-organization.md
└── src/
    ├── lib.rs              # Shared library code
    ├── bin/                # Binary targets (defined in Cargo.toml)
    ├── examples/           # Working example projects
    │   ├── tp223_touch_sensor.rs   # TP223 touch sensor with Embassy
    │   └── lm75_temperature.rs     # LM75 I2C temperature sensor
    └── scraps/             # Templates and work-in-progress
        ├── template_embassy.rs     # Template using esp_hal_embassy (async)
        ├── template_blocking.rs    # Template using blocking esp_hal
        ├── test.rs                 # LED blink test
        └── touch.rs                # Touch input test

Templates

template_embassy.rs (Async with Embassy)

Use this template for projects that benefit from async/await:

  • Non-blocking delays with Timer::after_millis().await
  • Task spawning with #[embassy_executor::task]
  • Power-efficient (CPU sleeps during delays)
  • Best for: multi-tasking, power-sensitive applications

template_blocking.rs (Synchronous)

Use this template for simple, straightforward projects:

  • Blocking delays with busy-wait loops
  • No async runtime overhead
  • Simpler mental model
  • Best for: simple applications, learning esp-hal basics

Examples

tp223_touch_sensor.rs

Demonstrates using a TP223 capacitive touch sensor (TK43 module) with Embassy async:

  • GPIO input with edge detection
  • Async polling with non-blocking delays
  • Touch/release event detection

lm75_temperature.rs

Demonstrates I2C communication with an LM75 temperature sensor:

  • I2C master setup on GPIO21 (SDA) and GPIO22 (SCL)
  • Device detection and error handling
  • Temperature reading with 0.5°C resolution
  • Output in Celsius and Fahrenheit
cargo run --release --bin lm75_temperature

Wiring:

LM75 Pin ESP32 Pin
VCC 3.3V
GND GND
SDA GPIO21
SCL GPIO22

Dependencies

Crate Version Purpose
esp-hal 0.23 Hardware abstraction layer for ESP32
esp-hal-embassy 0.6 Embassy async runtime integration
esp-backtrace 0.15 Panic handler with backtrace support
esp-println 0.13 Serial output (println! macro)
embassy-executor 0.7 Async task executor
embassy-time 0.4 Async timers and delays
embedded-hal 1.0 Hardware abstraction traits for drivers
critical-section 1.2 Interrupt-safe critical sections

Important: no_std Environment

This is a bare-metal (no_std) project. You cannot use standard library crates designed for desktop applications. See docs/std-vs-no_std.md for details.

What you CAN'T use

  • env_logger, log with std backends - use esp-println instead
  • std::time - use esp_hal::time or embassy_time instead
  • std::io - use embedded-io traits instead
  • Most crates that don't explicitly support no_std

Serial Output

Use esp-println for debugging:

use esp_println::println;

println!("Hello from ESP32!");
println!("Counter: {}", counter);

GPIO Notes

The following pins have special functions on the ESP32-WROOM-32:

Bootstrap pins (usable, but check datasheet):

  • GPIO0, GPIO2, GPIO5, GPIO12, GPIO15

Reserved pins (used by the module's flash - do not use):

  • GPIO6-11, GPIO16, GPIO20

See docs/esp32-pinout-reference.md for detailed pinout information.

Adding New Binaries

  1. Create your .rs file in src/bin/ or reference a file elsewhere
  2. Add a [[bin]] entry to Cargo.toml:
[[bin]]
name = "my_project"
path = "./src/bin/my_project.rs"
  1. Build and run:
cargo run --release --bin my_project

Troubleshooting

"linker xtensa-esp32-elf-gcc not found"

The ESP toolchain environment isn't loaded. Run:

. $HOME/export-esp.sh

Errors about Option, Iterator, Copy not found

You've added a dependency that requires the standard library. Remove the incompatible dependency and find a no_std alternative.

No output after boot messages

Your code compiles but produces no visible output. Add esp-println and use println!() for debug output.

Embassy timer not working

Make sure to initialize Embassy with a timer:

let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_hal_embassy::init(timg0.timer0);

Resources

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages