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}