Replace heat_dur u32 with Duration
This commit is contained in:
parent
a8a7426888
commit
d1fe4a972a
3 changed files with 58 additions and 47 deletions
|
@ -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(())
|
||||
}
|
||||
|
|
31
src/calc.rs
31
src/calc.rs
|
@ -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);
|
||||
|
|
47
src/lib.rs
47
src/lib.rs
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue