marcelbuesing / bme680

Pure Rust BME680 implementation
MIT License
29 stars 27 forks source link

Multiple calls to set forced power mode necessary to get a valid read #23

Closed tiziano88 closed 3 years ago

tiziano88 commented 3 years ago

First of all, thanks for making this crate available!

I am trying to use it to retrieve sensor data, but it seems that I need to set forced power mode no less than three times in order to be able to get a valid read.

My code looks as follows:

fn main() {
    // env_logger::init();
    env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init();

    let i2c = hal::I2cdev::new("/dev/i2c-1").unwrap();
    let mut dev = Bme680::init(i2c, Delay {}, I2CAddress::Primary).unwrap();

    let settings = SettingsBuilder::new()
        .with_humidity_oversampling(OversamplingSetting::OS2x)
        .with_pressure_oversampling(OversamplingSetting::OS4x)
        .with_temperature_oversampling(OversamplingSetting::OS8x)
        .with_temperature_filter(IIRFilterSize::Size3)
        .with_gas_measurement(Duration::from_millis(1500), 320, 25)
        .with_temperature_offset(-2.2)
        .with_run_gas(true)
        .build();

    let profile_dur = dev.get_profile_dur(&settings.0).unwrap();
    info!("Profile duration {:?}", profile_dur);
    info!("Setting sensor settings");
    dev.set_sensor_settings(settings).unwrap();

    info!("Setting forced power modes");
    dev.set_sensor_mode(PowerMode::ForcedMode).unwrap();
    dev.set_sensor_mode(PowerMode::ForcedMode).unwrap();
    dev.set_sensor_mode(PowerMode::ForcedMode).unwrap();

    let (data, _state) = dev.get_sensor_data().unwrap();
    info!("Sensor Data {:?}", data);
    info!("Temperature {}°C", data.temperature_celsius());
    info!("Pressure {}hPa", data.pressure_hpa());
    info!("Humidity {}%", data.humidity_percent());
    info!("Gas Resistence {}Ω", data.gas_resistance_ohm());
}

If I remove even just one of the 3 calls to set_sensor_mode, I get consistently wrong results, e.g.:

Oct 16 22:26:34 raspberrypi hello-world[23731]: [2020-10-16T21:26:34Z INFO  hello_world] Temperature 31.24°C
Oct 16 22:26:34 raspberrypi hello-world[23731]: [2020-10-16T21:26:34Z INFO  hello_world] Pressure 655.98hPa
Oct 16 22:26:34 raspberrypi hello-world[23731]: [2020-10-16T21:26:34Z INFO  hello_world] Humidity 100%
Oct 16 22:26:34 raspberrypi hello-world[23731]: [2020-10-16T21:26:34Z INFO  hello_world] Gas Resistence 806516Ω

Could it be some race condition, or am I doing something wrong?

jgosmann commented 3 years ago

I'm seeing the same effect.

jgosmann commented 3 years ago

The example from the documentation is missing a sleep to wait for the sensor data being ready. You can get the necessary sleep duration like this:

let profile_duration = dev.get_profile_dur(&settings.0).map_err(Bme680Error)?;

and then you do a sleep in-between setting the forced power mode and reading the sensor data:

std::thread::sleep(profile_duration);