climate-go/firmware/src/main.rs

131 lines
3.9 KiB
Rust

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,
};
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"),
}
}