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