diff --git a/sachy-shtc3/src/lib.rs b/sachy-shtc3/src/lib.rs index a0b0e44..8cb9750 100644 --- a/sachy-shtc3/src/lib.rs +++ b/sachy-shtc3/src/lib.rs @@ -35,7 +35,7 @@ //! use sachy_shtc3::ShtC3; //! //! let dev = I2cdev::new("/dev/i2c-1").unwrap(); -//! let mut sht = ShtC3::new(dev); +//! let mut sht = ShtC3::new(dev, Default::default()); //! ``` //! //! ### Device Info @@ -45,7 +45,7 @@ //! ```no_run //! use linux_embedded_hal::{Delay, I2cdev}; //! use sachy_shtc3::ShtC3; -//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); +//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), Default::default()); //! let device_id = sht.device_identifier().unwrap(); //! let raw_id = sht.raw_id_register().unwrap(); //! ``` @@ -59,12 +59,12 @@ //! use linux_embedded_hal::{Delay, I2cdev}; //! use sachy_shtc3::{ShtC3, PowerMode}; //! -//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); +//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), Default::default()); //! let mut delay = Delay; //! -//! let temperature = sht.measure_temperature(PowerMode::NormalMode, &mut delay).unwrap(); -//! let humidity = sht.measure_humidity(PowerMode::NormalMode, &mut delay).unwrap(); -//! let combined = sht.measure(PowerMode::NormalMode, &mut delay).unwrap(); +//! let temperature = sht.measure_temperature(&mut delay).unwrap(); +//! let humidity = sht.measure_humidity(&mut delay).unwrap(); +//! let combined = sht.measure(&mut delay).unwrap(); //! //! println!("Temperature: {} °C", temperature.as_degrees_celsius()); //! println!("Humidity: {} %RH", humidity.as_percent()); @@ -82,9 +82,9 @@ //! ```no_run //! use linux_embedded_hal::{Delay, I2cdev}; //! use sachy_shtc3::{ShtC3, PowerMode}; -//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); +//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::LowPower); //! let mut delay = Delay; -//! let measurement = sht.measure(PowerMode::LowPower, &mut delay).unwrap(); +//! let measurement = sht.measure(&mut delay).unwrap(); //! ``` //! //! ### Measurements (Non-Blocking) @@ -97,9 +97,9 @@ //! use linux_embedded_hal::I2cdev; //! use sachy_shtc3::{ShtC3, PowerMode}; //! -//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); +//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::NormalMode); //! -//! sht.start_measurement(PowerMode::NormalMode).unwrap(); +//! sht.start_measurement().unwrap(); //! // Wait for at least `max_measurement_duration(&sht, PowerMode::NormalMode)` µs //! let result = sht.get_measurement_result().unwrap(); //! ``` @@ -129,7 +129,7 @@ //! ```no_run //! use linux_embedded_hal::{Delay, I2cdev}; //! use sachy_shtc3::{ShtC3, PowerMode}; -//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); +//! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::NormalMode); //! let mut delay = Delay; //! sht.reset(&mut delay).unwrap(); //! ``` @@ -169,10 +169,11 @@ enum MeasurementOrder { /// note][an-low-power] by Sensirion. /// /// [an-low-power]: https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Sensirion_Humidity_Sensors_SHTC3_Low_Power_Measurement_Mode.pdf -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum PowerMode { /// Normal measurement. + #[default] NormalMode, /// Low power measurement: Less energy consumption, but repeatability and /// accuracy of measurements are negatively impacted. @@ -262,13 +263,18 @@ pub struct ShtC3 { i2c: I2C, /// The I²C device address. address: u8, + mode: PowerMode, } impl ShtC3 { /// Create a new instance of the driver for the SHTC3. #[inline] - pub const fn new(i2c: I2C) -> Self { - Self { i2c, address: 0x70 } + pub const fn new(i2c: I2C, mode: PowerMode) -> Self { + Self { + i2c, + address: 0x70, + mode, + } } /// Get the device's wakeup delay duration in microseconds @@ -289,8 +295,8 @@ impl ShtC3 { /// - Normal mode: 12.1 ms /// - Low power mode: 0.8 ms #[inline(always)] - pub const fn max_measurement_duration(&self, mode: PowerMode) -> u32 { - match mode { + pub const fn max_measurement_duration(&self) -> u32 { + match self.mode { PowerMode::NormalMode => 12100, PowerMode::LowPower => 800, } @@ -421,7 +427,7 @@ where }) .await?; - delay.delay_us(self.max_measurement_duration(mode)).await; + delay.delay_us(self.max_measurement_duration()).await; let mut buf = [0; 6]; self.read_with_crc_async(&mut buf).await?; @@ -543,21 +549,18 @@ where } /// Start a combined temperature / humidity measurement. - pub fn start_measurement(&mut self, mode: PowerMode) -> Result<(), Error> { - self.start_measure_partial(mode, MeasurementOrder::TemperatureFirst) + pub fn start_measurement(&mut self) -> Result<(), Error> { + self.start_measure_partial(self.mode, MeasurementOrder::TemperatureFirst) } /// Start a temperature measurement. - pub fn start_temperature_measurement( - &mut self, - mode: PowerMode, - ) -> Result<(), Error> { - self.start_measure_partial(mode, MeasurementOrder::TemperatureFirst) + pub fn start_temperature_measurement(&mut self) -> Result<(), Error> { + self.start_measure_partial(self.mode, MeasurementOrder::TemperatureFirst) } /// Start a humidity measurement. - pub fn start_humidity_measurement(&mut self, mode: PowerMode) -> Result<(), Error> { - self.start_measure_partial(mode, MeasurementOrder::HumidityFirst) + pub fn start_humidity_measurement(&mut self) -> Result<(), Error> { + self.start_measure_partial(self.mode, MeasurementOrder::HumidityFirst) } /// Read the result of a temperature / humidity measurement. @@ -609,8 +612,8 @@ where I2C: I2c, { /// Wait the maximum time needed for the given measurement mode - pub fn wait_for_measurement(&mut self, mode: PowerMode, delay: &mut impl BlockingDelayNs) { - delay.delay_us(self.max_measurement_duration(mode)); + pub fn wait_for_measurement(&mut self, delay: &mut impl BlockingDelayNs) { + delay.delay_us(self.max_measurement_duration()); } /// Run a temperature/humidity measurement and return the combined result. @@ -618,11 +621,10 @@ where /// This is a blocking function call. pub fn measure( &mut self, - mode: PowerMode, delay: &mut impl BlockingDelayNs, ) -> Result> { - self.start_measurement(mode)?; - self.wait_for_measurement(mode, delay); + self.start_measurement()?; + self.wait_for_measurement(delay); self.get_measurement_result() } @@ -634,11 +636,10 @@ where /// and only read the first half of the measurement response. pub fn measure_temperature( &mut self, - mode: PowerMode, delay: &mut impl BlockingDelayNs, ) -> Result> { - self.start_temperature_measurement(mode)?; - self.wait_for_measurement(mode, delay); + self.start_temperature_measurement()?; + self.wait_for_measurement(delay); self.get_temperature_measurement_result() } @@ -650,11 +651,10 @@ where /// and only read the first half of the measurement response. pub fn measure_humidity( &mut self, - mode: PowerMode, delay: &mut impl BlockingDelayNs, ) -> Result> { - self.start_humidity_measurement(mode)?; - self.wait_for_measurement(mode, delay); + self.start_humidity_measurement()?; + self.wait_for_measurement(delay); self.get_humidity_measurement_result() } } @@ -683,7 +683,7 @@ mod tests { [Transaction::write(SHT_ADDR, alloc::vec![0xef, 0xc8]) .with_error(ErrorKind::Other)]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let err = sht.send_command(Command::ReadIdRegister).unwrap_err(); assert_eq!(err, Error::I2c(ErrorKind::Other)); sht.destroy().done(); @@ -693,7 +693,7 @@ mod tests { #[test] fn validate_crc() { let mock = I2cMock::new(&[]); - let sht = ShtC3::new(mock); + let sht = ShtC3::new(mock, PowerMode::NormalMode); // Not enough data sht.validate_crc(&[]).unwrap(); @@ -730,7 +730,7 @@ mod tests { // Valid CRC let expectations = [Transaction::read(SHT_ADDR, alloc::vec![0xbe, 0xef, 0x92])]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); sht.read_with_crc(&mut buf).unwrap(); assert_eq!(buf, [0xbe, 0xef, 0x92]); sht.destroy().done(); @@ -738,7 +738,7 @@ mod tests { // Invalid CRC let expectations = [Transaction::read(SHT_ADDR, alloc::vec![0xbe, 0xef, 0x00])]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); match sht.read_with_crc(&mut buf) { Err(Error::Crc) => {} Err(_) => panic!("Invalid error: Must be Crc"), @@ -755,7 +755,7 @@ mod tests { #[test] fn new_shtc3() { let mock = I2cMock::new(&[]); - let sht = ShtC3::new(mock); + let sht = ShtC3::new(mock, PowerMode::NormalMode); assert_eq!(sht.address, 0x70); sht.destroy().done(); } @@ -775,7 +775,7 @@ mod tests { Transaction::read(SHT_ADDR, alloc::vec![msb, lsb, crc]), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let val = sht.raw_id_register().unwrap(); assert_eq!(val, (msb as u16) << 8 | (lsb as u16)); sht.destroy().done(); @@ -792,7 +792,7 @@ mod tests { Transaction::read(SHT_ADDR, alloc::vec![msb, lsb, crc]), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let ident = sht.device_identifier().unwrap(); assert_eq!(ident, 0b01000111); sht.destroy().done(); @@ -823,9 +823,9 @@ mod tests { ), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let mut delay = NoopDelay; - let measurement = sht.measure(PowerMode::NormalMode, &mut delay).unwrap(); + let measurement = sht.measure(&mut delay).unwrap(); assert_eq!(measurement.temperature.as_millidegrees_celsius(), 23_730); // 23.7°C assert_eq!(measurement.humidity.as_millipercent(), 62_968); // 62.9 %RH sht.destroy().done(); @@ -852,9 +852,9 @@ mod tests { ), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::LowPower); let mut delay = NoopDelay; - let measurement = sht.measure(PowerMode::LowPower, &mut delay).unwrap(); + let measurement = sht.measure(&mut delay).unwrap(); assert_eq!(measurement.temperature.as_millidegrees_celsius(), 23_730); // 23.7°C assert_eq!(measurement.humidity.as_millipercent(), 62_968); // 62.9 %RH sht.destroy().done(); @@ -871,10 +871,10 @@ mod tests { Transaction::read(SHT_ADDR, alloc::vec![0b0110_0100, 0b1000_1011, 0b1100_0111]), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let mut delay = NoopDelay; let temperature = sht - .measure_temperature(PowerMode::NormalMode, &mut delay) + .measure_temperature(&mut delay) .unwrap(); assert_eq!(temperature.as_millidegrees_celsius(), 23_730); // 23.7°C sht.destroy().done(); @@ -891,10 +891,10 @@ mod tests { Transaction::read(SHT_ADDR, alloc::vec![0b1010_0001, 0b0011_0011, 0b0001_1100]), ]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); let mut delay = NoopDelay; let humidity = sht - .measure_humidity(PowerMode::NormalMode, &mut delay) + .measure_humidity(&mut delay) .unwrap(); assert_eq!(humidity.as_millipercent(), 62_968); // 62.9 %RH sht.destroy().done(); @@ -907,9 +907,9 @@ mod tests { [Transaction::write(SHT_ADDR, alloc::vec![0x60, 0x9C]) .with_error(ErrorKind::Other)]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::LowPower); let err = sht - .measure(PowerMode::LowPower, &mut NoopDelay) + .measure(&mut NoopDelay) .unwrap_err(); assert_eq!(err, Error::I2c(ErrorKind::Other)); sht.destroy().done(); @@ -924,7 +924,7 @@ mod tests { fn sleep() { let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0xB0, 0x98])]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); sht.sleep().unwrap(); sht.destroy().done(); } @@ -934,7 +934,7 @@ mod tests { fn wakeup() { let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0x35, 0x17])]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); sht.wakeup(&mut NoopDelay).unwrap(); sht.destroy().done(); } @@ -944,7 +944,7 @@ mod tests { fn reset() { let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0x80, 0x5D])]; let mock = I2cMock::new(&expectations); - let mut sht = ShtC3::new(mock); + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); sht.reset(&mut NoopDelay).unwrap(); sht.destroy().done(); } @@ -955,10 +955,15 @@ mod tests { #[test] fn shortcut_function() { - let c3 = ShtC3::new(I2cMock::new(&[])); + let c3 = ShtC3::new(I2cMock::new(&[]), PowerMode::NormalMode); + + assert_eq!(c3.max_measurement_duration(), 12100); + + let i2c = c3.destroy(); + + let c3 = ShtC3::new(i2c, PowerMode::LowPower); - assert_eq!(c3.max_measurement_duration(PowerMode::NormalMode), 12100); - assert_eq!(c3.max_measurement_duration(PowerMode::LowPower), 800); + assert_eq!(c3.max_measurement_duration(), 800); c3.destroy().done(); }