created_at2023-09-08 13:22:01.752935
updated_at2023-09-12 15:18:57.834563
descriptionThis crate enables sensor sampling & LED strips control over Wifi/MQTT on ESP Rust Board
Cyril Marpaud (cyril-marpaud)




OxidESPark is a Rust library for the Rust ESP Board embedding an ESP32-C3 microcontroller (RISC-V). It uses the ESP-IDF framework and provides tools to easily build applications that interact with the physical world.

Its two main goals are:

  • Interfacing various I2C sensors through a simple TOML configuration file
  • Allowing control of various devices


See the ESP-IDF template for a detailed guide on how to setup a project.

A complete example can be found in the examples folder of this repository.

Configuration file

OxidESPark is configured through a TOML configuration file. A full configuration example can be found in the examples folder of this repository.


As no file system is available on a microcontroller, OxidESPark requires a &'static str to embed the configuration file inside the binary. The include_str macro can be used to that end:

use oxide_spark::utils::init::Init;


That init() call also initializes the logging facilities (see the Logging section below).


The log crate can be used with OxidESPark. Logging facilities are initialized with the library, the only requirement is to set the log_level field in the configuration file:

uuid = "esp1"
log_level = "Info"
use log::info;
use oxide_spark::utils::config::CONFIG;

info!("Hello, world!");
info!("Configuration:\n{:#?}", *CONFIG);

warn!("This is a warning!");
error!("This is an error!");

I2c sensors

Any number of sensors can be declared in the configuration file through the optional sensors section:

freq = 5
id = "sensor1"
kind = "Shtc3"
metrics = { "Temperature" = "t","Humidity" = "h" }

After that, one must configure the I2C bus and call the init() function to initialize the sensors and start measuring:

use esp_idf_hal::peripherals::Peripherals;
use oxide_spark::{network::i2c::I2c, models::sensor::Metric, sensors::Sensors};

let peripherals = Peripherals::take().unwrap();

let i2c = I2c::init(

let channel_size = 10;
let (data_sender, data_receiver) = sync_channel::<Metric>(channel_size);

Sensors::init(i2c, &data_sender, None).unwrap();

Supported internal sensors (embedded on the board)

  • SHTC3: temperature and humidity
freq = 5
id = "sensor1"
kind = "Shtc3"
metrics = { "Temperature" = "t","Humidity" = "h" }

Coming soon:

Supported external sensors

Each external sensor must be connected to the board's I2C bus (SCL and SDA pins are respectively GPIO 8 and 10).

  • TSL2561: visible and infrared light
freq = 3
id = "sensor2"
kind = "Tsl2561"
metrics = { "InfraredLight" = "il", "VisibleInfraredLight" = "vil" }

Coming soon:

  • BME280: temperature, humidity and pressure
  • MPU9250: accelerometer, gyroscope and magnetometer

Supported devices

  • WS2812B: RGB LED strips (including the embedded "1-LED strip" on GPIO 2)
use oxide_spark::models::led_strip::LedStripBuilder;
use oxide_spark_utils::{color::Color::{Chartreuse, Red}, command::led_strip_mode::LedStripMode};

let rgb_led = LedStripBuilder::new()




Wifi connection is available (though optional) through the configuration file:

auth_method = "WPA2Enterprise"
pwd = "wifi_password"
ssid = "wifi_ssid"
timeout = 8

See AuthMethod for a list of available authentication methods.

use esp_idf_hal::peripherals::Peripherals;
use oxide_spark::network::wifi::Wifi;

let peripherals = Peripherals::take().unwrap();


After the init() call, the Wifi connection is established. If a timeout occurs, the device automatically reboots.


MQTT connection is also available (and optional). It requires a Wifi connection to be established first and a broker must of course be running at the given IP and port:

channel_size = 10
ip = ""
port = 1883
use oxide_spark::network::mqtt::Mqtt;

let (data_sender, cmd_receiver) = Mqtt::init().unwrap();

data_sender is the sending half of a sync channel used to send data (namely, sensor measures) while cmd_receiver is the receiving half of a sync channel used to receive remote commands.

Commit count: 241

cargo fmt