4 releases
0.3.3 | Sep 12, 2023 |
---|---|
0.3.2 | Sep 11, 2023 |
0.3.1 | Sep 11, 2023 |
0.3.0 | Sep 8, 2023 |
#613 in Embedded development
36KB
815 lines
OxidESPark
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
Setup
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.
Initialization
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;
Init::init(include_str!("OxideSparkConfig.toml"))?;
That init()
call also initializes the logging facilities (see the Logging section below).
Logging
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:
[esp]
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:
[[sensors]]
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(
peripherals.i2c0,
peripherals.pins.gpio8,
peripherals.pins.gpio10,
).unwrap();
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
[[sensors]]
freq = 5
id = "sensor1"
kind = "Shtc3"
metrics = { "Temperature" = "t","Humidity" = "h" }
Coming soon:
- ICM-42670-P: accelerometer and gyroscope
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
[[sensors]]
freq = 3
id = "sensor2"
kind = "Tsl2561"
metrics = { "InfraredLight" = "il", "VisibleInfraredLight" = "vil" }
Coming soon:
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()
.channel(0)
.gpio(2)
.length(1)
.mode(LedStripMode::Full(Red))
.build()
.unwrap()
.init()
.unwrap();
rgb_led.send(LedStripMode::Full(Chartreuse)).unwrap();
Connectivity
Wifi
Wifi connection is available (though optional) through the configuration file:
[wifi]
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();
Wifi::init(peripherals.modem).unwrap();
After the init()
call, the Wifi connection is established. If a timeout occurs, the device automatically reboots.
MQTT
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:
[mqtt]
channel_size = 10
ip = "1.2.3.4"
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.
Dependencies
~7–16MB
~228K SLoC