adafruit_aht10/
lib.rs

1use embedded_hal::blocking::i2c::{Write, Read};
2
3pub struct AdafruitAHT10<I2C> {
4    i2c: I2C,
5}
6
7#[derive(Debug)]
8pub enum Aht10Error {
9    CommunicationError,
10    CalibrationFailed,
11    OtherError,
12}
13
14const AHT10_I2CADDR_DEFAULT: u8 = 0x38;
15const AHT10_CMD_SOFTRESET: u8 = 0xBA;
16const AHT10_CMD_CALIBRATE: u8 = 0xE1;
17const AHT10_CMD_TRIGGER: u8 = 0xAC;
18const AHT10_STATUS_BUSY: u8 = 0x80;
19const AHT10_STATUS_CALIBRATED: u8 = 0x08;
20
21impl<I2C, E> AdafruitAHT10<I2C>
22where
23    I2C: Write<Error = E> + Read<Error = E>,
24{
25    pub fn new(i2c: I2C) -> Self {
26        AdafruitAHT10 { i2c }
27    }
28
29    pub fn begin(&mut self) -> Result<(), Aht10Error> {
30        self.soft_reset()?;
31        self.calibrate()?;
32        Ok(())
33    }
34
35    fn soft_reset(&mut self) -> Result<(), Aht10Error> {
36        let cmd = [AHT10_CMD_SOFTRESET];
37        match self.i2c.write(AHT10_I2CADDR_DEFAULT, &cmd) {
38            Ok(_) => {}
39            Err(_) => return Err(Aht10Error::CommunicationError),
40        }
41        Ok(())
42    }
43
44    fn calibrate(&mut self) -> Result<(), Aht10Error> {
45        let cmd = [AHT10_CMD_CALIBRATE, 0x08, 0x00];
46        match self.i2c.write(AHT10_I2CADDR_DEFAULT, &cmd) {
47            Ok(_) => {}
48            Err(_) => return Err(Aht10Error::CommunicationError),
49        }
50        while self.get_status()? & AHT10_STATUS_BUSY != 0 {}
51        if self.get_status()? & AHT10_STATUS_CALIBRATED == 0 {
52            return Err(Aht10Error::CalibrationFailed);
53        }
54        Ok(())
55    }
56
57    fn get_status(&mut self) -> Result<u8, Aht10Error> {
58        let mut status = [0u8; 1];
59        match self.i2c.read(AHT10_I2CADDR_DEFAULT, &mut status) {
60            Ok(_) => {}
61            Err(_) => return Err(Aht10Error::CommunicationError),
62        }
63        Ok(status[0])
64    }
65
66    pub fn read_data(&mut self) -> Result<(f32, f32), Aht10Error> {
67        let cmd = [AHT10_CMD_TRIGGER, 0x33, 0x00];
68        match self.i2c.write(AHT10_I2CADDR_DEFAULT, &cmd) {
69            Ok(_) => {}
70            Err(_) => return Err(Aht10Error::CommunicationError),
71        }
72
73        while self.get_status()? & AHT10_STATUS_BUSY != 0 {}
74
75        let mut data = [0u8; 6];
76        match self.i2c.read(AHT10_I2CADDR_DEFAULT, &mut data) {
77            Ok(_) => {}
78            Err(_) => return Err(Aht10Error::CommunicationError),
79        }
80
81        let mut hata: u32 = data[1] as u32;
82        hata <<= 8;
83        hata |= data[2] as u32;
84        hata <<= 4;
85        hata |= (data[3] >> 4) as u32;
86        let humidity = (hata as f32 * 100.0) / (0x100000 as f32);
87        
88        let mut tdata: u32 = (data[3] & 0x0F) as u32;
89        tdata <<= 8;
90        tdata |= data[4] as u32;
91        tdata <<= 8;
92        tdata |= data[5] as u32;
93        let temperature = ((tdata as f32) * 200.0 / 0x100000 as f32) - 50.0;
94
95
96        Ok((humidity, temperature))
97    }
98}