Compare commits

...

2 commits

3 changed files with 216 additions and 8 deletions

84
firmware/Cargo.lock generated
View file

@ -94,6 +94,16 @@ version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bme280"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "169ac81b9123f316fde5b0e00175294dcdcdd800c1a6c92a4b58caf42a14cf1f"
dependencies = [
"embedded-hal 1.0.0",
"maybe-async-cfg",
]
[[package]]
name = "bstr"
version = "1.12.0"
@ -621,8 +631,11 @@ dependencies = [
name = "firmware"
version = "0.1.0"
dependencies = [
"bme280",
"embuild",
"esp-idf-hal",
"esp-idf-svc",
"esp-idf-sys",
"log",
]
@ -890,6 +903,43 @@ version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "manyhow"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
dependencies = [
"manyhow-macros",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.104",
]
[[package]]
name = "manyhow-macros"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
dependencies = [
"proc-macro-utils",
"proc-macro2",
"quote",
]
[[package]]
name = "maybe-async-cfg"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627"
dependencies = [
"manyhow",
"proc-macro2",
"pulldown-cmark",
"quote",
"syn 1.0.109",
]
[[package]]
name = "memchr"
version = "2.7.5"
@ -1038,6 +1088,17 @@ dependencies = [
"syn 2.0.104",
]
[[package]]
name = "proc-macro-utils"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
dependencies = [
"proc-macro2",
"quote",
"smallvec",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
@ -1047,6 +1108,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
dependencies = [
"bitflags 2.9.1",
"memchr",
"unicase",
]
[[package]]
name = "quote"
version = "1.0.40"
@ -1214,6 +1286,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@ -1365,6 +1443,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "unicase"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
[[package]]
name = "unicode-ident"
version = "1.0.18"

View file

@ -25,6 +25,9 @@ experimental = ["esp-idf-svc/experimental"]
[dependencies]
log = "0.4"
esp-idf-svc = "0.51"
bme280 = "0.5.1"
esp-idf-hal = "0.45.2"
esp-idf-sys = { version = "0.36.1", features = ["binstart"] }
# --- Optional Embassy Integration ---
# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] }

View file

@ -1,10 +1,131 @@
fn main() {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
esp_idf_svc::sys::link_patches();
use bme280::{i2c::BME280, Error};
use esp_idf_hal::{
adc::{
attenuation,
oneshot::{config::AdcChannelConfig, AdcChannelDriver, AdcDriver},
ADC2,
},
delay::Delay,
i2c::{I2cConfig, I2cDriver, I2cError},
prelude::Peripherals,
};
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
log::info!("Hello, world!");
struct InitResult<'s, I2C> {
bme280: BME280<I2C>,
no2_adc: AdcChannelDriver<'s, esp_idf_hal::gpio::Gpio4, AdcDriver<'s, ADC2>>,
}
fn main() {
let mut peripherals = init();
loop {
let measurement = peripherals
.bme280
.measure(&mut Delay::new_default())
.unwrap();
println!(
"temperature:{0}°C, pressure:{1}",
measurement.temperature, measurement.pressure
);
match peripherals.no2_adc.read() {
Ok(v) => {
println!("NO2 ADC voltage: {v}");
}
Err(err) => log::error!("Failed to read ADC for NO2 value with error {err}"),
};
Delay::default().delay_ms(1000);
}
}
fn init<'a>() -> InitResult<'a, I2cDriver<'a>> {
//set up logger
esp_idf_sys::link_patches(); // Important!
esp_idf_svc::log::EspLogger::initialize_default();
log::info!("Meow :3");
// Initialize peripherals
let peripherals = Peripherals::take().unwrap();
// Define SCL and SDA pins
let sda = peripherals.pins.gpio21;
let scl = peripherals.pins.gpio22;
// Create I2C config
let config = I2cConfig::new().baudrate(100000.into());
log::info!("Initializing I2C bus…");
// Initialize I2C driver
let i2c_bus = match I2cDriver::new(
peripherals.i2c0, // or i2c1/i2c2 based on board
sda,
scl,
&config,
) {
Ok(i2c_connection) => i2c_connection,
Err(err) => {
log::error!("Initializing I2C connection failed with {err}!");
panic!()
}
};
log::info!("I2C up!");
log::info!("Initializing bme280…");
let mut bme280 = BME280::new_primary(i2c_bus);
//initialize Sensor
match bme280.init(&mut Delay::new(100000)) {
Ok(_) => {}
Err(err) => {
log::error!("Error initializing bme280 sensor:");
handle_i2c_error(err);
}
}
log::info!("BME280 up!");
//initialize adc2 for MICS2714
let adc2 = match AdcDriver::new(peripherals.adc2) {
Ok(driver) => driver,
Err(err) => {
log::error!("Failed to initialize AdcDriver with error {err}");
panic!()
}
};
log::info!("Initializing ADC2 on GPIO4 for NO2 sensor…");
// Define channel config with desired attenuation
let mut channel_config = AdcChannelConfig::new();
channel_config.attenuation = attenuation::DB_11;
let adc_channel_driver: AdcChannelDriver<'a, esp_idf_hal::gpio::Gpio4, AdcDriver<'_, ADC2>> =
match AdcChannelDriver::new(adc2, peripherals.pins.gpio4, &channel_config) {
Ok(channel) => channel,
Err(err) => {
log::error!("Failed to initialize AdcChannelDriver with error {err}");
panic!()
}
};
log::info!("ADC2 channel driver@GPIO4 initialized!");
InitResult {
bme280: bme280,
no2_adc: adc_channel_driver,
}
}
fn handle_i2c_error(error: Error<I2cError>) {
match error {
bme280::Error::CompensationFailed => log::error!("Failed to compensate a raw measurement"),
bme280::Error::Bus(buserr) => log::error!("Bus error: {}", buserr),
bme280::Error::InvalidData => log::error!("Failed to pare sensor data!"),
bme280::Error::NoCalibrationData => log::error!("No calibration data is available (probably forgot to call or check BME280::init for failure)"),
bme280::Error::UnsupportedChip => log::error!("Chip ID doesn't match expected value"),
bme280::Error::Delay => log::error!("Delay error"),
}
}