Embedded Rust with Rust ESP Board (ESP32-C3-DevKit-RUST-1)
About
This project contains examples and tutorials for programming the Rust ESP Board (ESP32-C3-DevKit-RUST-1) using embedded Rust with the esp-hal hardware abstraction layer.
Hardware
Board: ESP32-C3-DevKit-RUST-1 (Rust ESP Board)
Pinout
Left Side
| Pin Number | Description | SoC |
|---|---|---|
| 1 | Reset | EN/CHIP_PU |
| 2 | 3V3 | |
| 3 | N/C | |
| 4 | GND | |
| 5 | IO0/ADC1-0 | GPIO0 |
| 6 | IO1/ADC1-1 | GPIO1 |
| 7 | IO2/ADC1-2 | GPIO2 |
| 8 | IO3/ADC1-3 | GPIO3 |
| 9 | IO4/ADC2-0 | GPIO4 |
| 10 | IO5/ADC2-1 | GPIO5 |
| 11 | IO6/MTCK | GPIO6 |
| 12 | IO7/MTDO/LED | GPIO7 |
| 13 | IO9/LOG | GPIO8 |
| 14 | IO21/U0RXD | GPIO21 |
| 15 | IO20/U0TXD | GPIO20 |
| 16 | IO9/BOOT | GPIO9 |
Right Side
| Pin Number | Description | SoC |
|---|---|---|
| 1 | VBAT | |
| 2 | EN [1] | |
| 3 | VBUS [2] | |
| 4 | NC | |
| 5 | NC | |
| 6 | NC | |
| 7 | NC | |
| 8 | NC | |
| 9 | IO18/USB_D- | GPIO18 |
| 10 | IO19/USB_D+ | GPIO19 |
| 11 | IO8/SCL | GPIO8 |
| 12 | IO10/SDA | GPIO10 |
- MCU: ESP32-C3 (RISC-V single-core processor)
- On-board peripherals:
- WS2812 RGB LED on GPIO2
- SHTC3 temperature/humidity sensor (I2C)
- ICM42670p 6-axis IMU (I2C)
- User button on GPIO9
- I2C pins:
- SDA: GPIO10
- SCL: GPIO8
Examples
Basic Examples
blinky
Blinks the on-board LED to verify your setup is working.
cargo run --example blinky
button
Reads the user button state and prints to console.
cargo run --example button
button-interrupt
Demonstrates interrupt-driven button handling for more efficient code.
cargo run --example button-interrupt
Digital Input Examples
hc_sr501
This example demonstrates how to interface with an HC-SR501 PIR motion sensor. It tracks the motion state and logs "Motion detected!" and "Motion ended!" on transitions. It also controls the onboard WS2812 RGB LED on GPIO2 (turns Red when motion is detected).
cargo run --example hc_sr501
Hardware:
- Sensor: HC-SR501 PIR Motion Sensor
- Connection: Direct wiring
Wiring:
| HC-SR501 Pin | Rust ESP Board | Notes |
|---|---|---|
| VCC | 5V / VBUS | 5V required for sensor |
| GND | GND | |
| OUT | GPIO1 | Digital input |
graph LR
subgraph ESP32 ["Rust ESP Board"]
V5["5V / VBUS"]
GND_M["GND"]
GPIO1["GPIO1 (Input)"]
GPIO2["GPIO2 (WS2812 LED)"]
end
subgraph PIR ["HC-SR501 Sensor"]
VCC_S["VCC"]
GND_S["GND"]
OUT_S["OUT"]
end
V5 -- Red --> VCC_S
GND_M -- Black --> GND_S
OUT_S -- Yellow --> GPIO1
GPIO2 -.-> |"Onboard LED"| GPIO2
rgBlinky
Controls the on-board WS2812 addressable RGB LED on GPIO2. Displays a smooth rainbow animation cycling through all colors using HSV color space with gamma correction.
cargo run --example rgBlinky
Features:
- Uses ESP32 RMT peripheral for precise timing
- HSV to RGB color conversion
- Gamma correction for better color appearance
- Configurable brightness (default: 10/255)
I2C Examples
i2c_scan
Scans the I2C bus for connected devices and prints their addresses. Useful for debugging I2C connections.
cargo run --example i2c_scan
Expected devices on the Rust ESP Board:
0x44- SHTC3 temperature/humidity sensor0x68- ICM42670p IMU
shtc3
Reads temperature and humidity from the on-board SHTC3 sensor and prints values continuously.
cargo run --example shtc3
Output: Temperature in °C and humidity in %
icm42670p
Demonstrates reading both the SHTC3 sensor and the ICM42670p gyroscope simultaneously using shared I2C bus.
cargo run --example icm42670p
Output: Temperature, humidity, and gyroscope X/Y/Z values
bme280_i2c
Reads temperature, humidity, and atmospheric pressure from an external BME280 sensor. This is a popular environmental sensor that measures all three parameters in one device.
This example is configured for the Adafruit BME280 breakout board connected via Qwiic/STEMMA QT cable.
cargo run --example bme280_i2c
Hardware:
- Sensor: Adafruit BME280 Temperature Humidity Pressure Sensor
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and sensor - no separate wires needed!
BME280 Pin -> Rust ESP Board
---------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (blue) -> GPIO10
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["3.3V"]
GND_M["GND"]
GPIO8["GPIO8 (SCL)"]
GPIO10["GPIO10 (SDA)"]
end
subgraph BME280 ["BME280 Sensor"]
VCC_S["VCC"]
GND_S["GND"]
SCL_S["SCL"]
SDA_S["SDA"]
end
VCC_M -- Red --> VCC_S
GND_M -- Black --> GND_S
GPIO8 -- Yellow --> SCL_S
GPIO10 -- Blue --> SDA_S
I2C Address:
- Adafruit BME280:
0x77(configured in code) - Generic modules: Often
0x76(change toBME280::new_primary()in code)
Output: Temperature in °C, humidity in %, and atmospheric pressure in hPa
hs3003_i2c
Reads temperature and humidity from the Renesas HS3003 sensor using a custom driver implementation. This example is configured for the Arduino Modulino Thermo connected via Qwiic/STEMMA QT cable.
cargo run --example hs3003_i2c
Hardware:
- Sensor: Arduino Modulino Thermo (Renesas HS3003)
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and Modulino Thermo - no separate wires needed!
Modulino Pin -> Rust ESP Board
------------ --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow) -> GPIO8
SDA (blue) -> GPIO10
I2C Address:
- HS3003:
0x44(fixed address)
Features:
- 14-bit resolution for temperature and humidity
- Temperature: -40°C to +125°C (±0.2°C accuracy)
- Humidity: 0-100% RH (±1.5% accuracy)
- Custom driver implementation (no external crate needed)
Output: Temperature in °C and humidity in %
bh1750_i2c
Reads ambient light levels in lux from a BH1750 digital light sensor. This example is configured for the Adafruit BH1750 breakout board connected via Qwiic/STEMMA QT cable.
cargo run --example bh1750_i2c
Hardware:
- Sensor: Adafruit BH1750 Light Sensor
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and sensor - no separate wires needed!
BH1750 Pin -> Rust ESP Board
---------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (blue) -> GPIO10
I2C Address:
- Adafruit BH1750:
0x23(ADDR pin to GND, default) - Alternative:
0x5C(ADDR pin to VCC)
Features:
- Wide range and high resolution (1-65535 lx)
- Spectral response close to human eye
- Three resolution modes: Low (4 lx), High (1 lx), High2 (0.5 lx)
- Automatic mode cycling demonstration
- Low power consumption
Output: Light level in lux, cycling through different resolution modes
adxl345_i2c
Reads accelerometer data (X, Y, Z) from an ADXL345 sensor over I2C.
cargo run --example adxl345_i2c
Hardware:
- Sensor: ADXL345 Accelerometer
- Connection: I2C
- I2C Address:
0x53(default) or0x1D
Wiring:
| Sensor Pin | ESP32-C3 | Notes |
|---|---|---|
| VCC | 3.3V | |
| GND | GND | |
| SDA | GPIO10 | |
| SCL | GPIO8 | |
| CS | VCC | I2C mode (high) |
| SDO/ALT | GND | Address 0x53 (low) |
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["3.3V"]
GND_M["GND"]
GPIO8["GPIO8 (SCL)"]
GPIO10["GPIO10 (SDA)"]
end
subgraph SENSOR ["ADXL345 Sensor"]
VCC_S["VCC"]
GND_S["GND"]
SCL_S["SCL"]
SDA_S["SDA"]
CS_S["CS"]
SDO_S["SDO"]
end
VCC_M --> VCC_S
GND_M --> GND_S
GPIO8 --> SCL_S
GPIO10 --> SDA_S
VCC_M --> CS_S
GND_M --> SDO_S
ltr559_i2c
Reads ambient light (lux) and proximity data from an LTR559 sensor. This example is configured for the Pimoroni Enviro+ FeatherWing.
cargo run --example ltr559_i2c
Hardware:
- Sensor: LITE-ON LTR559 (on Pimoroni Enviro+ FeatherWing)
- Connection: I2C (configured for ESP32-C3)
- I2C Address:
0x23(default)
Wiring:
- SDA: GPIO 10
- SCL: GPIO 8
- VCC: 3.3V
- GND: GND
Features:
- Reads Proximity and Light (Lux) data
- Custom driver implementation (no external crate needed)
- Lux calculation using Pimoroni's formula
- Verified gain settings against reference drivers
Output: Proximity value and Light level in Lux
bme280alt_i2c
Reads temperature, humidity, and atmospheric pressure from a BME280 sensor at address 0x76. This example is configured for the Pimoroni Enviro+ FeatherWing or other modules using the alternative I2C address.
cargo run --example bme280alt_i2c
Hardware:
- Sensor: Pimoroni Enviro+ FeatherWing (BME280)
- I2C Address:
0x76(SDO to GND)
bmp580_i2c
Reads temperature and atmospheric pressure from the Bosch BMP580 sensor using a custom local driver implementation. This example is configured for the Adafruit BMP580 connected via Qwiic/STEMMA QT cable.
cargo run --example bmp580_i2c
Hardware:
- Sensor: Adafruit BMP580 (High-performance barometric pressure sensor)
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and BMP580 - no separate wires needed!
BMP580 Pin -> Rust ESP Board
----------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (blue) -> GPIO10
I2C Address:
- Adafruit BMP580:
0x47(default) - Alternative:
0x46(SDA pulled to GND/logic low)
Features:
- High precision pressure sensing (±0.5 hPa accuracy)
- Temperature sensing
- Custom driver implementation (no external crate needed)
- Normal power mode with 50Hz ODR (default)
- 4x pressure oversampling for low noise
Output: Atmospheric pressure in hPa and temperature in °C
bme680_i2c
Reads temperature, humidity, atmospheric pressure, and gas resistance (VOCs) from a BME680 or BME688 sensor. This example is configured for the Adafruit BME688 breakout board connected via Qwiic/STEMMA QT cable.
cargo run --example bme680_i2c
Hardware:
- Sensor: Adafruit BME688 Temperature Humidity Pressure Gas Sensor
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and sensor - no separate wires needed!
BME688 Pin -> Rust ESP Board
----------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (blue) -> GPIO10
I2C Address:
- Adafruit BME688:
0x77(configured in code asDeviceAddress::Secondary) - Alternative:
0x76(change toDeviceAddress::Primaryin code)
Features:
- Temperature sensing (-40°C to +85°C)
- Humidity sensing (0-100% RH)
- Pressure sensing (300-1100 hPa)
- Gas resistance measurement for VOC detection (volatile organic compounds)
- Uses
bosch-bme680crate for full sensor support - Gas resistance ranges from ~1kΩ (polluted air) to ~100MΩ (clean air)
Output: Temperature in °C, humidity in %, atmospheric pressure in hPa, and gas resistance in Ohms
scd40_i2c
Reads CO2 concentration, temperature, and humidity from an SCD40/SCD41 sensor. This example is configured for the Apollo Automation SCD40 Breakout (or compatible Sensirion SCD4x) connected via I2C.
cargo run --example scd40_i2c
Hardware:
- Sensor: SCD40/SCD41 CO2 Sensor
- Connection: I2C (Qwiic/STEMMA QT recommended)
Wiring:
- SDA: GPIO 10
- SCL: GPIO 8
- VCC: 3.3V
- GND: GND
Features:
- CO2 measurement (ppm)
- Temperature measurement (°C)
- Humidity measurement (%RH)
- Periodic measurement mode (5 seconds)
sgp30_i2c
Reads eCO2 (equivalent CO2) and TVOC (Total Volatile Organic Compounds) from an SGP30 air quality sensor. This example is configured for the Adafruit SGP30 breakout board connected via Qwiic/STEMMA QT cable.
cargo run --example sgp30_i2c
Hardware:
- Sensor: Adafruit SGP30 Air Quality Sensor Breakout - VOC and eCO2
- Connection: Qwiic/STEMMA QT cable (plug and play I2C connection)
Wiring with Qwiic/STEMMA QT:
Simply connect the Qwiic/STEMMA QT cable between the board and sensor - no separate wires needed!
SGP30 Pin -> Rust ESP Board
----------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (blue) -> GPIO10
I2C Address:
- SGP30:
0x58(fixed address, cannot be changed)
Features:
- eCO2 (equivalent CO2) measurement: 400-60000 ppm
- TVOC (Total Volatile Organic Compounds) measurement: 0-60000 ppb
- Dynamic baseline compensation algorithm
- On-chip humidity compensation support
- Baseline values can be stored and restored for faster warm-up
- Uses
sgp30crate for full sensor support
Warm-up Timeline:
- First 15-20 seconds (15-20 measurements): Fixed baseline values (400 ppm CO2, 0 ppb TVOC)
- Next 20 minutes (~1200 measurements): Sensor settling period for reliable readings
- First 12 hours (~43,200 measurements): Baseline calibration period
- Brand new sensors: 48-hour factory burn-in recommended
Important Notes:
- The sensor must be read every 1 second to maintain proper baseline compensation
- Expose sensor to fresh outdoor air for 10 minutes to help establish baseline
- Save baseline values after 12+ hours of operation for faster subsequent startups
- Test VOC detection by breathing near sensor or using hand sanitizer
- The example shows changes in real-time and displays baseline values every 5 minutes
Output: eCO2 in ppm (parts per million) and TVOC in ppb (parts per billion), with change detection and status updates
Arduino Modulino Examples
These examples demonstrate how to use Arduino Modulino modules with the Rust ESP Board using the modulino crate. All modules connect via I2C using the Qwiic/STEMMA QT connector.
Wiring for all Modulino modules:
- Black (GND) -> GND
- Red (VCC) -> 3.3V
- Yellow (SCL) -> GPIO8
- Blue (SDA) -> GPIO10
modulino_buttons_i2c
Reads button states from the Modulino Buttons module and controls its LEDs.
cargo run --example modulino_buttons_i2c
Features:
- Reads 3 buttons (A, B, C)
- Controls 3 LEDs corresponding to buttons
- Interrupt-style edge detection simulation
modulino_buzzer_i2c
Plays a melody on the Modulino Buzzer module.
cargo run --example modulino_buzzer_i2c
Features:
- Plays notes and melodies
- Uses I2C command interface
modulino_distance_i2c
Reads distance from the Modulino Distance (VL53L4CD) Time-of-Flight sensor.
cargo run --example modulino_distance_i2c
Features:
- High-accuracy distance measurement
- Millimeter precision
modulino_joystick_i2c
Reads joystick position and button state from the Arduino Modulino Joystick module.
cargo run --example modulino_joystick_i2c
Features:
- Reads X and Y position
- Detects push-button state
- Calculates angle and magnitude
- Uses I2C command interface
modulino_knob_i2c
Reads the rotary encoder value and push-button state from the Modulino Knob.
cargo run --example modulino_knob_i2c
Features:
- precise rotary encoder reading
- Configurable range (0-100 in example)
- Integrated push-button detection
modulino_latch_relay_i2c
Demonstrates how to control the Arduino Modulino Latch Relay module.
cargo run --example modulino_latch_relay_i2c
Features:
- Controls a latching relay (maintains state without power)
- Checks and toggles relay state
- Uses I2C command interface
modulino_movement_i2c
Reads accelerometer and gyroscope data from the Arduino Modulino Movement module.
cargo run --example modulino_movement_i2c
Features:
- Reads 3-axis accelerometer (g)
- Reads 3-axis gyroscope (dps)
- Uses LSM6DSOX sensor via
modulinocrate
modulino_pixels_i2c
Controls 8 RGB LEDs on the Arduino Modulino Pixels module.
cargo run --example modulino_pixels_i2c
Features:
- Individual control of 8 RGB LEDs
- Adjustable brightness
- Demo animations: Rainbow, Knight Rider, Color Fade
modulino_thermo_i2c
Reads temperature and humidity from the Modulino Thermo (HS3003) sensor.
cargo run --example modulino_thermo_i2c
Features:
- Temperature (°C) and Humidity (%) monitoring
- Uses
modulinocrate driver (alternative tohs3003_i2cexample)
modulino_vibro_i2c
Demonstrates various vibration patterns on the Arduino Modulino Vibro module.
cargo run --example modulino_vibro_i2c
Features:
- Different vibration power levels (Gentle to Maximum)
- Patterns: Pulses, Continuous, Sweeps
Analog Examples
mics6814
Reads values from the MICS6814 analog gas sensor (Oxidising, Reducing, and NH3 channels). Configured for the Pimoroni Enviro+ FeatherWing.
cargo run --example mics6814
Hardware:
- Sensor: MICS6814 (on Pimoroni Enviro+ FeatherWing)
- Connection: Analog inputs (configured for ESP32-C3 ADC)
gp2y1010au0f_dust
Reads dust density (PM2.5/PM10 particles) from the Sharp GP2Y1010AU0F optical dust sensor. This example is configured for the Waveshare Dust Sensor module.
cargo run --example gp2y1010au0f_dust
Hardware:
- Sensor: Waveshare Dust Sensor (Sharp GP2Y1010AU0F)
- Connection: 4-wire interface (VCC, GND, AOUT, ILED)
- Voltage: 5V (sensor requires 4.5V-5.5V)
Wiring:
The Waveshare Dust Sensor breakout board includes all required components onboard. Simply connect the 4-wire cable directly:
Waveshare Dust Sensor Breakout -> ESP32-C3 Rust Board
-------------------------------- ---------------------
VCC (red) -> 5V/VUSB or 3.3V
GND (black) -> GND
AOUT (yellow) -> GPIO0 (ADC input)
ILED (blue) -> GPIO1 (digital output)
Onboard Components (included on Waveshare breakout):
- 150Ω resistor for LED current limiting
- 220µF capacitor for power stabilization
- PT1301 DC/DC converter (2.5V-5.5V input → 5V output for sensor)
- Transistor Q1 for LED pulse control
- Resistor divider for output voltage scaling
Note: If using the raw Sharp GP2Y1010AU0F sensor (not the Waveshare module), you will need to add external 150Ω resistor and 220µF capacitor.
How it Works:
The GP2Y1010AU0F uses an infrared LED and photodetector to measure dust particles:
- LED is pulsed ON for 0.32ms every 10ms
- After 0.28ms delay, the analog output is sampled
- Dust particles reflect LED light, increasing the output voltage
- Output voltage is proportional to dust density (0.5V per 0.1mg/m³)
Sensor Characteristics:
- Clean air baseline: ~1.35V (with Waveshare board)
- Dusty air: increases from baseline
- Sensitivity: 0.5V per 0.1mg/m³ above baseline
Calibration:
The example includes voltage offset correction for accurate readings:
- Default
VOLTAGE_OFFSET = 1.35V(typical for Waveshare board) - Measures clean air baseline and subtracts it before calculating dust density
- Adjustable in code if your sensor's baseline differs
- Without offset correction, clean air would incorrectly show as "Poor" quality
Air Quality Levels:
- Good: < 0.035 mg/m³ (clean indoor air)
- Moderate: 0.035 - 0.075 mg/m³ (some dust present)
- Poor: > 0.075 mg/m³ (dusty/smoky air)
Testing:
- Clean air: Should read near 0.000 mg/m³
- Breathe near sensor: Should increase to 0.04-0.08 mg/m³
- Smoke/incense: Should spike above 0.1 mg/m³
Output: ADC raw value, voltage, dust density in mg/m³, running average, and air quality assessment
UART Examples
pms5003
Reads PM1.0, PM2.5, and PM10 air quality data from a PMS5003 sensor connected via UART.
cargo run --example pms5003
Wiring:
- Sensor TX -> GPIO21 (RX)
- Sensor RX -> GPIO20 (TX)
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["5V/VUSB"]
GND_M["GND"]
GPIO20["GPIO20 (TX)"]
GPIO21["GPIO21 (RX)"]
end
subgraph PMS ["PMS5003 Sensor"]
VCC_S["VCC"]
GND_S["GND"]
RX_S["RXD"]
TX_S["TXD"]
end
VCC_M -- Red --> VCC_S
GND_M -- Black --> GND_S
GPIO20 -- "MCU TX to Sensor RX" --> RX_S
GPIO21 -- "MCU RX from Sensor TX" --> TX_S
ld2410
Reads human presence, distance, and energy levels from an HLK-LD2410C mmWave radar sensor connected via UART at 256000 baud.
cargo run --example ld2410
Wiring:
- VCC: 5V / VBUS (sensor requires 5V)
- GND: GND
- Sensor TX: GPIO21 (MCU RX)
- Sensor RX: GPIO20 (MCU TX)
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["5V/VUSB"]
GND_M["GND"]
GPIO20["GPIO20 (TX)"]
GPIO21["GPIO21 (RX)"]
end
subgraph LD2410 ["HLK-LD2410C Sensor"]
VCC_S["VCC (5V)"]
GND_S["GND"]
RX_S["RX"]
TX_S["TX"]
end
VCC_M -- Red --> VCC_S
GND_M -- Black --> GND_S
GPIO20 -- "MCU TX to Sensor RX" --> RX_S
GPIO21 -- "MCU RX from Sensor TX" --> TX_S
Wi-Fi Examples
http_client
Connects to a Wi-Fi network and performs a simple HTTP GET request.
cargo run --example http_client
Configuration:
- Requires
SSIDandPASSWORDenvironment variables to be set at compile time.
Display Examples (SSD1306 OLED - I2C)
These examples require an external 128x64 SSD1306 OLED display connected via I2C.
Wiring for SSD1306 Display
Display Pin -> Rust ESP Board
----------- --------------
GND (black) -> GND
VCC (red) -> 3.3V
SCL (yellow)-> GPIO8
SDA (green) -> GPIO10
ssd1306
Displays a Rust logo image on the OLED screen.
cargo run --example ssd1306
Features:
- 1-bit black and white graphics
- Buffered rendering
- Static image display
ssd1306_text
Demonstrates text rendering and drawing shapes on the OLED display.
cargo run --example ssd1306_text
Features:
- Text rendering with built-in fonts
- Drawing primitives (lines, rectangles, circles)
- Shows "Rust ESP Board Demo" with graphics
Display Examples (SH1107 OLED - I2C)
These examples require an Adafruit 128x64 OLED FeatherWing (SH1107) connected via I2C.
Hardware: Adafruit 128x64 OLED FeatherWing
Wiring for Adafruit OLED FeatherWing
Display Pin -> Rust ESP Board
----------- --------------
GND -> GND
3V -> 3.3V
SCL -> GPIO8
SDA -> GPIO10
adafruit_feather_sh1107_text
Demonstrates text rendering and drawing shapes on the SH1107 OLED using a local driver implementation.
cargo run --example adafruit_feather_sh1107_text
Features:
- Custom local driver (no external crate dependency issues)
- 128x64 pixel resolution
- Text and shape rendering using
embedded-graphics - Safe for USB debugging (uses I2C, not SPI)
adafruit_feather_sh1107
Displays two 64x64 bitmap images side-by-side using the local driver.
cargo run --example adafruit_feather_sh1107
Features:
- Displays
ferris64x64bw.bmp(converted from RGB to 1-bit BMP) - Displays
rust.raw(raw 1-bit image data) - Demonstrates loading images with
tinybmpandImageRaw - Includes
convert_ferris.pyscript for converting images
Display Examples (ST7735S LCD - SPI)
These examples require a Waveshare 0.96 inch LCD module (80x160 pixels) with ST7735S controller connected via SPI.
Note: For round 240x240 displays, see the GC9A01 examples below.
Wiring for Waveshare 0.96" LCD Module
LCD Pin -> Rust ESP Board
------- ----------------------
VCC -> 3.3V
GND -> GND
DIN -> GPIO7 (MOSI)
CLK -> GPIO6 (SCK)
CS -> GPIO5 (Chip Select)
DC -> GPIO4 (Data/Command)
RST -> GPIO3 (Reset)
BL -> GPIO2 (Backlight)
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["3.3V"]
GND_M["GND"]
GPIO7["GPIO7 (MOSI)"]
GPIO6["GPIO6 (SCK)"]
GPIO5["GPIO5 (CS)"]
GPIO4["GPIO4 (DC)"]
GPIO3["GPIO3 (RST)"]
GPIO2["GPIO2 (BL)"]
end
subgraph LCD ["ST7735S LCD"]
VCC_S["VCC"]
GND_S["GND"]
DIN_S["DIN"]
CLK_S["CLK"]
CS_S["CS"]
DC_S["DC"]
RST_S["RST"]
BL_S["BL"]
end
VCC_M --> VCC_S
GND_M --> GND_S
GPIO7 --> DIN_S
GPIO6 --> CLK_S
GPIO5 --> CS_S
GPIO4 --> DC_S
GPIO3 --> RST_S
GPIO2 --> BL_S
Pin Functions:
- VCC: Power supply (3.3V)
- GND: Ground
- DIN (MOSI): SPI data input - transmits pixel data
- CLK (SCK): SPI clock - synchronizes data transmission
- CS: Chip select (active low) - enables the display
- DC: Data/Command select (Low=Command, High=Data)
- RST: Reset (active low) - resets the display controller
- BL: Backlight control (HIGH=on, LOW=off)
SPI Configuration:
- SPI Mode: 0 (CPOL=0, CPHA=0)
- Clock Speed: 26 MHz
- Display Resolution: 80x160 pixels (landscape mode)
- Color Format: RGB565 (16-bit color, 65,536 colors)
st7735s_spi
Displays Ferris and Rust logo images on the color LCD.
cargo run --example st7735s_spi
Features:
- Full RGB565 color support (16-bit, 65K colors)
- Displays raw RGB565 image format (Ferris)
- Displays BMP image format (Rust logo)
- Hardware SPI for fast rendering
st7735s_spi_text
Demonstrates text rendering and colorful shapes on the LCD display.
cargo run --example st7735s_spi_text
Features:
- Multiple font sizes (6x10, 9x15 bold)
- Text styling with colors and backgrounds
- Drawing colorful primitives (rectangles, circles, lines)
- Multiple colors: white, blue, yellow, green, red, orange
- Shows "Rust ESP Board" title with graphics
enviro_display_spi
[EXPERIMENTAL/PROBLEMATIC] Demonstrates driving the ST7735s display on the Pimoroni Enviro+ FeatherWing.
Warning
CRITICAL HARDWARE CONFLICT: This example uses GPIO 18 and 19 for DC and CS pins, which are the USB D-/D+ pins on the ESP32-C3-DevKit-RUST-1. Running this example WILL BREAK YOUR USB CONNECTION (logs/flashing) until you manually reset the board into bootloader mode.
BACKLIGHT: The backlight pin is not connected by default on the Rust Board and requires a manual jumper wire.
cargo run --example enviro_display_spi
Features:
- Reference for
mipidsi0.8.0 configuration - Handling specific display offsets and color orders
- Using onboard RGB LED as a status "heartbeat" when USB is lost
Display Examples (ILI9341 TFT LCD - SPI)
These examples require an ILI9341 TFT LCD module (240x320 pixels) connected via SPI. This is a common rectangular display used in many projects.
Hardware: 2.8" TFT SPI 240x320 V1.2 Display Module
This module includes a resistive touchscreen (T_CLK, T_CS, T_DIN, T_DO, T_IRQ pins) which is not used in these basic display examples.
Wiring for 2.8" TFT SPI 240x320 V1.2 Module
LCD Pin -> Rust ESP Board
---------- ----------------------
VCC -> 3.3V
GND -> GND
CS -> GPIO5 (Chip Select)
RESET -> GPIO3 (Reset)
DC -> GPIO4 (Data/Command)
SDI (MOSI) -> GPIO7 (SPI MOSI/Data)
SCK -> GPIO6 (SPI Clock)
LED -> 3.3V (Backlight)
SDO (MISO) -> GPIO1 (optional)
Touchscreen pins (not connected in these examples):
T_CLK -> (not used)
T_CS -> (not used)
T_DIN -> (not used)
T_DO -> (not used)
T_IRQ -> (not used)
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["3.3V"]
GND_M["GND"]
GPIO5["GPIO5 (CS)"]
GPIO3["GPIO3 (RST)"]
GPIO4["GPIO4 (DC)"]
GPIO7["GPIO7 (MOSI)"]
GPIO6["GPIO6 (SCK)"]
BL_M["3.3V (BL)"]
GPIO1["GPIO1 (MISO)"]
end
subgraph LCD ["ILI9341 LCD"]
VCC_S["VCC"]
GND_S["GND"]
CS_S["CS"]
RST_S["RESET"]
DC_S["DC"]
SDI_S["SDI (MOSI)"]
SCK_S["SCK"]
LED_S["LED"]
SDO_S["SDO (MISO)"]
end
VCC_M --> VCC_S
GND_M --> GND_S
GPIO5 --> CS_S
GPIO3 --> RST_S
GPIO4 --> DC_S
GPIO7 --> SDI_S
GPIO6 --> SCK_S
BL_M --> LED_S
GPIO1 -.-> SDO_S
Pin Functions:
- VCC: Power supply (3.3V or 5V depending on module)
- GND: Ground
- CS: Chip select for LCD (active low)
- RESET: Reset (active low)
- DC: Data/Command select (Low=Command, High=Data)
- SDI (MOSI): SPI data input to display
- SCK: SPI clock
- LED: Backlight power (can connect to GPIO for PWM control)
- SDO (MISO): SPI data output (optional, rarely needed)
SPI Configuration:
- SPI Mode: 0 (CPOL=0, CPHA=0)
- Clock Speed: 40 MHz (ILI9341 supports up to 60 MHz)
- Display Resolution: 240x320 pixels (portrait mode)
- Color Format: RGB565 (16-bit color, 65,536 colors)
ili9341_spi
Displays colorful text and Rust logo on the TFT LCD.
cargo run --example ili9341_spi
Features:
- Full RGB565 color support (16-bit, 65K colors)
- 240x320 pixel rectangular display
- Multiple colored text examples
- Displays BMP image format (Rust logo)
- High-speed 40 MHz SPI for fast rendering
ili9341_spi_text
Demonstrates comprehensive text rendering and colorful shapes on the LCD.
cargo run --example ili9341_spi_text
Features:
- Multiple font sizes (6x10, 9x15 bold, 10x20)
- Text styling with colors and backgrounds
- Drawing primitives (rectangles, circles, lines)
- Multiple colors: red, green, blue, yellow, cyan, magenta, white
- Title bar with background color
- Demonstrates rectangular layout for portrait display
zermatt
Displays a full-screen 320x240 landscape image of Zermatt on the ILI9341 display.
cargo run --example zermatt
Features:
- Full-screen landscape image display (320×240)
- Uses BMP format with tinybmp library
- Demonstrates landscape orientation (90° rotation)
- BGR color order for correct colors
- Includes Python script for JPEG to BMP conversion
Image Conversion:
python3 examples/convert_jpg_to_bmp.py examples/zermatt_320x240.jpg examples/zermatt_320x240.bmp
Display Examples (GC9A01 Round LCD - SPI)
These examples require a GC9A01 round LCD module (240x240 pixels) connected via SPI. This is a circular display commonly used in smartwatches and circular gauge displays.
Hardware: UNI128-240240-RGB-7-V1.0 Display Module (7 pins)
Important Note: Despite the module having pins labeled SCL/SDA, this is an SPI display, not I2C! The presence of DC (Data/Command) and CS (Chip Select) pins confirms it's SPI. The pin labels mean:
- SCL = SPI Clock (same as SCK/SCLK)
- SDA = SPI Data (same as MOSI - Master Out Slave In)
Wiring for UNI128-240240-RGB-7-V1.0 Module
LCD Pin -> Rust ESP Board
------- ----------------------
VCC -> 3.3V
GND -> GND
SCL -> GPIO6 (SPI Clock)
SDA -> GPIO7 (SPI MOSI/Data)
DC -> GPIO4 (Data/Command)
CS -> GPIO5 (Chip Select)
RST -> GPIO3 (Reset)
graph LR
subgraph ESP32 ["Rust ESP Board"]
VCC_M["3.3V"]
GND_M["GND"]
GPIO6["GPIO6 (SCK)"]
GPIO7["GPIO7 (MOSI)"]
GPIO4["GPIO4 (DC)"]
GPIO5["GPIO5 (CS)"]
GPIO3["GPIO3 (RST)"]
end
subgraph LCD ["GC9A01 LCD"]
VCC_S["VCC"]
GND_S["GND"]
SCL_S["SCL (SCK)"]
SDA_S["SDA (MOSI)"]
DC_S["DC"]
CS_S["CS"]
RST_S["RST"]
end
VCC_M --> VCC_S
GND_M --> GND_S
GPIO6 --> SCL_S
GPIO7 --> SDA_S
GPIO4 --> DC_S
GPIO5 --> CS_S
GPIO3 --> RST_S
Pin Functions:
- VCC: Power supply (3.3V)
- GND: Ground
- SCL: SPI clock (labeled SCL but it's actually SPI SCK)
- SDA: SPI data output (labeled SDA but it's actually SPI MOSI)
- DC: Data/Command select (Low=Command, High=Data)
- CS: Chip select (active low) - enables the display
- RST: Reset (active low) - resets the display controller
Note: This 7-pin module has no separate backlight control pin - the backlight is always on when powered.
SPI Configuration:
- SPI Mode: 0 (CPOL=0, CPHA=0)
- Clock Speed: 60 MHz (GC9A01 supports up to 62.5 MHz)
- Display Resolution: 240x240 pixels (round/circular)
- Color Format: RGB565 (16-bit color, 65,536 colors)
- Display Shape: Circular (visible area is round)
gc9a01_spi
Displays Ferris and Rust logo images on the round color LCD.
cargo run --example gc9a01_spi
Features:
- Full RGB565 color support (16-bit, 65K colors)
- 240x240 pixel round display
- Displays raw RGB565 image format (Ferris)
- Displays BMP image format (Rust logo)
- High-speed 60 MHz SPI for fast rendering
- Uses mipidsi driver for robust display control
gc9a01_spi_text
Demonstrates text rendering and colorful shapes optimized for the circular display.
cargo run --example gc9a01_spi_text
Features:
- Multiple font sizes (6x10, 9x15 bold, 10x20)
- Text styling with colors and backgrounds
- Circular shapes to match the round display form factor
- Drawing primitives optimized for circular layout
- Multiple colors: white, blue, yellow, green, red, cyan, magenta, orange
- Shows "GC9A01 Display" title with circular graphics
- Demonstrates lines radiating from center
max7219_8x8_matrix
A comprehensive demo with 20 animations on a MAX7219 8x8 LED matrix. Logical parity with original RP235x version.
cargo run --example max7219_8x8_matrix
Hardware:
- Controller: MAX7219 8x8 LED Matrix module
- Connection: SPI
Wiring:
| MAX7219 Pin | Rust ESP Board | Notes |
|---|---|---|
| VCC | 5V / VBUS | |
| GND | GND | |
| DIN | GPIO7 | SPI MOSI |
| CS | GPIO5 | |
| CLK | GPIO6 | SPI SCK |
graph LR
subgraph ESP32 ["Rust ESP Board"]
V5["5V / VBUS"]
GND_M["GND"]
GPIO7["GPIO7 (MOSI)"]
GPIO5["GPIO5 (CS)"]
GPIO6["GPIO6 (SCK)"]
end
subgraph MATRIX ["MAX7219 8x8 Matrix"]
VCC_S["VCC"]
GND_S["GND"]
DIN_S["DIN"]
CS_S["CS"]
CLK_S["CLK"]
end
V5 -- Red --> VCC_S
GND_M -- Black --> GND_S
GPIO7 -- Yellow --> DIN_S
GPIO5 -- Orange --> CS_S
GPIO6 -- Green --> CLK_S
Features:
- 20 classic animations (Bouncing Ball, Pong, Game of Life, etc.)
- Alphabetical demo sequence
- 5-second per-animation timing
- Robust coordinate clipping
Dependencies
Key dependencies used in this project:
- esp-hal - Hardware abstraction layer for ESP32
- embedded-hal - Standard embedded traits
- esp-hal-smartled - WS2812/smart LED support via RMT
- smart-leds - Color manipulation and LED traits
- ssd1306 - OLED display driver (I2C)
- st7735-lcd - ST7735S color LCD driver (SPI)
- mipidsi - Universal MIPI display driver (supports GC9A01 and many others)
- display-interface-spi - SPI display interface for mipidsi
- embedded-graphics - 2D graphics library for displays
- tinybmp - BMP image format support
- shtcx - SHTC3 sensor driver
- icm42670 - ICM42670 IMU driver
- bme280 - BME280 environmental sensor driver
- bh1750 - BH1750 light sensor driver
- defmt - Efficient logging framework
Building and Flashing
To build and flash any example:
# Build only cargo build --example <example_name> # Build and flash to device cargo run --example <example_name>
Development Setup
- Install Rust and cargo
- Install probe-rs:
cargo install probe-rs-tools --locked - Add RISC-V target:
rustup target add riscv32imc-unknown-none-elf - Clone this repository
- Connect your Rust ESP Board via USB
- Run examples with
cargo run --example <name>
Note: This project uses probe-rs for flashing and debugging. The .cargo/config.toml is configured to use probe-rs as the runner.
Resources
- ESP-RS Book
- ESP-HAL Documentation
- BME280 Temperature, Humidity & Pressure
- BME680/BME688 Temperature, Humidity, Pressure & Gas (VOC)
- ICM42670 Accel/Gyro
- Rust ESP Board GitHub
License
This project is licensed under the same terms as the Rust ESP Board examples.
