Replace heat_dur u32 with Duration

This commit is contained in:
marcelbuesing 2018-05-24 22:02:23 +02:00
parent a8a7426888
commit d1fe4a972a
No known key found for this signature in database
GPG key ID: EF3934305E975944
3 changed files with 58 additions and 47 deletions

View file

@ -30,7 +30,7 @@ fn main() -> result::Result<
sensor_settings.tph_sett.filter = Some(2);
sensor_settings.gas_sett.run_gas = Some(0x01);
sensor_settings.gas_sett.heatr_dur = Some(1500);
sensor_settings.gas_sett.heatr_dur = Some(Duration::from_millis(1500));
sensor_settings.gas_sett.heatr_temp = Some(320);
let settings_sel = DesiredSensorSettings::OST_SEL | DesiredSensorSettings::OSP_SEL
@ -38,7 +38,7 @@ fn main() -> result::Result<
| DesiredSensorSettings::GAS_SENSOR_SEL;
let profile_dur = dev.get_profile_dur(&sensor_settings)?;
info!("Duration {}", profile_dur);
info!("Duration {:?}", profile_dur);
info!("Setting sensor settings");
dev.set_sensor_settings(settings_sel, &sensor_settings)?;
info!("Setting forced power modes");
@ -54,11 +54,10 @@ fn main() -> result::Result<
info!("Setting forced power modes");
dev.set_sensor_mode(PowerMode::ForcedMode)?;
info!("Retrieving sensor data");
let (data, state) = dev.get_sensor_data()?;
let (data, _state) = dev.get_sensor_data()?;
info!("Sensor Data {:?}", data);
info!("Temperature {}°C", data.temperature_celsius());
info!("Pressure {}hPa", data.pressure_hpa());
info!("Humidity {}%", data.humidity_percent());
}
Ok(())
}

View file

@ -1,17 +1,17 @@
use CalibData;
use std::time::Duration;
pub struct Calc {}
impl Calc {
pub fn calc_heater_res(calib: &CalibData, amb_temp: i8, temp: u16) -> u8 {
// cap temperature
let temp = if temp <= 400 { temp } else { 400 };
let var1 = amb_temp as (i32) * calib.par_gh3 as (i32) / 1000i32 * 256i32;
let var2 = (calib.par_gh1 as (i32) + 784i32)
* (((calib.par_gh2 as (i32) + 154009i32) * temp as (i32) * 5i32 / 100i32
+ 3276800i32) / 10i32);
* (((calib.par_gh2 as (i32) + 154009i32) * temp as (i32) * 5i32 / 100i32 + 3276800i32)
/ 10i32);
let var3 = var1 + var2 / 2i32;
let var4 = var3 / (calib.res_heat_range as (i32) + 4i32);
let var5 = 131i32 * calib.res_heat_val as (i32) + 65536i32;
@ -19,18 +19,21 @@ impl Calc {
((heatr_res_x100 + 50i32) / 100i32) as (u8)
}
pub fn calc_heater_dur(dur: u16) -> u8 {
pub fn calc_heater_dur(duration: Duration) -> u8 {
let mut factor: u8 = 0u8;
let mut dur = dur;
let durval =
if dur as (i32) >= 0xfc0i32 {
// TODO replace once https://github.com/rust-lang/rust/pull/50167 has been merged
const MILLIS_PER_SEC: u64 = 1_000;
const NANOS_PER_MILLI: u64 = 1_000_000;
let mut dur = (duration.as_secs() as u64 * MILLIS_PER_SEC)
+ (duration.subsec_nanos() as u64 / NANOS_PER_MILLI);
let durval = if dur as (i32) >= 0xfc0i32 {
0xffu8 // Max duration
} else {
loop {
if !(dur as (i32) > 0x3fi32) {
break;
}
dur = (dur as (i32) / 4i32) as (u16);
dur = (dur as (i32) / 4i32) as (u64);
factor = (factor as (i32) + 1i32) as (u8);
}
(dur as (i32) + factor as (i32) * 64i32) as (u8)
@ -65,8 +68,8 @@ impl Calc {
} else {
pressure_comp = ((pressure_comp << 1i32) as (u32)).wrapping_div(var1 as (u32)) as (i32);
}
var1 = calib.par_p9 as (i32)
* ((pressure_comp >> 3i32) * (pressure_comp >> 3i32) >> 13i32) >> 12i32;
var1 = calib.par_p9 as (i32) * ((pressure_comp >> 3i32) * (pressure_comp >> 3i32) >> 13i32)
>> 12i32;
var2 = (pressure_comp >> 2i32) * calib.par_p8 as (i32) >> 13i32;
let var3: i32 = (pressure_comp >> 8i32) * (pressure_comp >> 8i32) * (pressure_comp >> 8i32)
* calib.par_p10 as (i32) >> 17i32;
@ -81,8 +84,8 @@ impl Calc {
- (temp_scaled * calib.par_h3 as (i32) / 100i32 >> 1i32);
let var2: i32 = calib.par_h2 as (i32)
* (temp_scaled * calib.par_h4 as (i32) / 100i32
+ (temp_scaled * (temp_scaled * calib.par_h5 as (i32) / 100i32) >> 6i32)
/ 100i32 + (1i32 << 14i32)) >> 10i32;
+ (temp_scaled * (temp_scaled * calib.par_h5 as (i32) / 100i32) >> 6i32) / 100i32
+ (1i32 << 14i32)) >> 10i32;
let var3: i32 = var1 * var2;
let var4: i32 = calib.par_h6 as (i32) << 7i32;
let var4: i32 = var4 + temp_scaled * calib.par_h7 as (i32) / 100i32 >> 4i32;
@ -134,8 +137,8 @@ impl Calc {
250000u32,
125000u32,
];
let var1: i64 = (1340 + 5 * calib.range_sw_err as i64)
* lookup_table1[gas_range as usize] as i64 >> 16;
let var1: i64 =
(1340 + 5 * calib.range_sw_err as i64) * lookup_table1[gas_range as usize] as i64 >> 16;
let var2: u64 = (((gas_res_adc as i64) << 15) - 16777216 + var1) as (u64);
let var3: i64 = lookup_table2[gas_range as usize] as i64 * var1 >> 9;
let calc_gas_res: u32 = ((var3 + ((var2 as i64) >> 1i64)) / var2 as (i64)) as (u32);

View file

@ -10,6 +10,7 @@ use calc::Calc;
use hal::blocking::delay::DelayMs;
use hal::blocking::i2c::{Read, Write};
use std::result;
use std::time::Duration;
/** BME680 General config */
pub const BME680_POLL_PERIOD_MS: u8 = 10;
@ -262,7 +263,7 @@ pub struct GasSett {
pub heatr_ctrl: Option<u8>,
pub run_gas: Option<u8>,
pub heatr_temp: Option<u16>,
pub heatr_dur: Option<u16>,
pub heatr_dur: Option<Duration>,
}
impl Clone for GasSett {
@ -747,33 +748,39 @@ where
Ok(PowerMode::from(mode))
}
pub fn bme680_set_profile_dur(&mut self, tph_sett: TphSett, duration: u16) {
pub fn bme680_set_profile_dur(&mut self, tph_sett: TphSett, duration: Duration) {
let os_to_meas_cycles: [u8; 6] = [0u8, 1u8, 2u8, 4u8, 8u8, 16u8];
// TODO check if the following unwrap_ors do not change behaviour
// TODO replace once https://github.com/rust-lang/rust/pull/50167 has been merged
const MILLIS_PER_SEC: u64 = 1_000;
const NANOS_PER_MILLI: u64 = 1_000_000;
let millis = (duration.as_secs() as u64 * MILLIS_PER_SEC)
+ (duration.subsec_nanos() as u64 / NANOS_PER_MILLI);
let mut meas_cycles = os_to_meas_cycles
[tph_sett.os_temp.unwrap_or(OversamplingSetting::OSNone) as (usize)]
as (u32);
as (u64);
meas_cycles = meas_cycles.wrapping_add(
os_to_meas_cycles[tph_sett.os_pres.unwrap_or(OversamplingSetting::OSNone) as (usize)]
as (u32),
as (u64),
);
meas_cycles = meas_cycles.wrapping_add(
os_to_meas_cycles[tph_sett.os_hum.unwrap_or(OversamplingSetting::OSNone) as (usize)]
as (u32),
as (u64),
);
let mut tph_dur = meas_cycles.wrapping_mul(1963u32);
tph_dur = tph_dur.wrapping_add(477u32.wrapping_mul(4u32));
tph_dur = tph_dur.wrapping_add(477u32.wrapping_mul(5u32));
tph_dur = tph_dur.wrapping_add(500u32);
tph_dur = tph_dur.wrapping_div(1000u32);
tph_dur = tph_dur.wrapping_add(1u32);
self.gas_sett.heatr_dur = Some((duration as (i32) - tph_dur as (u16) as (i32)) as (u16));
let mut tph_dur = meas_cycles.wrapping_mul(1963u64);
tph_dur = tph_dur.wrapping_add(477u64.wrapping_mul(4u64));
tph_dur = tph_dur.wrapping_add(477u64.wrapping_mul(5u64));
tph_dur = tph_dur.wrapping_add(500u64);
tph_dur = tph_dur.wrapping_div(1000u64);
tph_dur = tph_dur.wrapping_add(1u64);
self.gas_sett.heatr_dur = Some(Duration::from_millis(millis - tph_dur));
}
pub fn get_profile_dur(
&self,
sensor_settings: &SensorSettings,
) -> Result<u16, <I2C as Read>::Error, <I2C as Write>::Error> {
) -> Result<Duration, <I2C as Read>::Error, <I2C as Write>::Error> {
let os_to_meas_cycles: [u8; 6] = [0u8, 1u8, 2u8, 4u8, 8u8, 16u8];
// TODO check if the following unwrap_ors do not change behaviour
let mut meas_cycles = os_to_meas_cycles[sensor_settings
@ -802,7 +809,7 @@ where
tph_dur = tph_dur.wrapping_add(500u32);
tph_dur = tph_dur.wrapping_div(1000u32);
tph_dur = tph_dur.wrapping_add(1u32);
let mut duration = tph_dur as (u16);
let mut duration = Duration::from_millis(tph_dur as u64);
if sensor_settings.gas_sett.run_gas.unwrap_or(0) != 0 {
duration = duration + sensor_settings.gas_sett.heatr_dur.expect("Heatrdur");
}
@ -903,7 +910,7 @@ where
),
(
BME680_GAS_WAIT0_ADDR,
Calc::calc_heater_dur(gas_sett.heatr_dur.unwrap_or(0)),
Calc::calc_heater_dur(gas_sett.heatr_dur.unwrap_or(Duration::from_secs(0))),
),
];
@ -914,15 +921,17 @@ where
fn get_gas_config(&mut self) -> Result<GasSett, <I2C as Read>::Error, <I2C as Write>::Error> {
// TODO move both GasSett fields to new struct
let mut gas_sett: GasSett = Default::default();
// TODO figure out if heat_temp and dur can be u8
gas_sett.heatr_temp =
Some(
I2CUtil::read_byte(&mut self.i2c, self.dev_id, BME680_ADDR_SENS_CONF_START)? as u16,
);
gas_sett.heatr_dur =
Some(
I2CUtil::read_byte(&mut self.i2c, self.dev_id, BME680_ADDR_GAS_CONF_START)? as u16,
);
let heatr_dur_ms =
I2CUtil::read_byte(&mut self.i2c, self.dev_id, BME680_ADDR_GAS_CONF_START)? as u64;
gas_sett.heatr_dur = Some(Duration::from_millis(heatr_dur_ms));
Ok(gas_sett)
}