1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
use crate::{
error::Result,
mode::{Sht31Measure, Sht31Reader},
Accuracy, Reading, SHT31,
};
use embedded_hal::i2c::I2c;
/// Periodic reading where reading returns the last available data
#[derive(Default, Copy, Clone, Debug)]
pub struct Periodic {
mps: MPS,
art: bool,
}
/// Stands for measurements per second
#[allow(dead_code)]
#[derive(Default, Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum MPS {
Half = 0x20,
#[default]
Normal = 0x21,
Double = 0x22,
X4 = 0x23,
X10 = 0x27,
}
impl Periodic {
#[allow(dead_code)]
pub fn new() -> Self {
Self {
mps: MPS::Normal,
art: false,
}
}
/// Sets the measurements per second for the periodic readings,
/// NOTE: The higher the frequency the less accurate the readings will be
pub fn set_mps(&mut self, mps: MPS) {
self.mps = mps;
}
/// Sets the measurements per second for the periodic readings,
/// NOTE: The higher the frequency the less accurate the readings will be
pub fn with_mps(mut self, mps: MPS) -> Self {
self.set_mps(mps);
self
}
/// Enables accelerated response time, evaluates data at a frequency of 4 Hz
pub fn with_art(mut self) -> Self {
self.art = true;
self
}
}
impl<I2C> Sht31Reader for SHT31<Periodic, I2C>
where
I2C: I2c,
{
fn read(&mut self) -> Result<Reading> {
let mut buffer = [0; 6];
self.i2c_read(&[0xE0, 0x00], &mut buffer)?;
self.process_data(buffer)
}
}
impl<I2C> Sht31Measure for SHT31<Periodic, I2C>
where
I2C: I2c,
{
/// Initialized the periodic measuring mode,
/// a break command must be run in order to change
/// the measuring style
fn measure(&mut self) -> Result<()> {
let (msb, lsb) = if self.mode.art {
(0x2B, 0x32)
} else {
let lsb = match self.mode.mps {
MPS::Half => match self.accuracy {
Accuracy::High => 0x32,
Accuracy::Medium => 0x24,
Accuracy::Low => 0x2F,
},
MPS::Normal => match self.accuracy {
Accuracy::High => 0x30,
Accuracy::Medium => 0x26,
Accuracy::Low => 0x2D,
},
MPS::Double => match self.accuracy {
Accuracy::High => 0x36,
Accuracy::Medium => 0x20,
Accuracy::Low => 0x2B,
},
MPS::X4 => match self.accuracy {
Accuracy::High => 0x34,
Accuracy::Medium => 0x22,
Accuracy::Low => 0x29,
},
MPS::X10 => match self.accuracy {
Accuracy::High => 0x37,
Accuracy::Medium => 0x21,
Accuracy::Low => 0x2A,
},
};
(self.mode.mps as u8, lsb)
};
self.i2c_write(&[msb, lsb])
}
}