1#![no_std]
2
3use core::fmt;
4
5use embedded_hal::blocking::delay::DelayMs;
6use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
7use log::info;
8
9pub struct Dht20<I2C, D> {
10 i2c: I2C,
11 address: u8,
12 delay: D,
13}
14
15#[derive(Debug, Clone)]
16pub struct Reading {
17 pub temp: f32,
18 pub hum: f32,
19}
20
21#[derive(Debug)]
22pub enum Error<E: fmt::Debug> {
23 I2cError(E),
24 ReadToFast,
25}
26
27impl<I2C, E, D> Dht20<I2C, D>
28where
29 I2C: Read<Error = E> + Write<Error = E> + WriteRead<Error = E>,
30 E: fmt::Debug,
31 D: DelayMs<u16>,
32{
33 pub fn new(i2c: I2C, address: u8, delay: D) -> Self {
34 Self {
35 i2c,
36 address,
37 delay,
38 }
39 }
40
41 pub fn read(&mut self) -> Result<Reading, E> {
42 self.reset()?;
43 self.write_data(&[0xAC, 0x33, 0])?;
45 self.delay.delay_ms(80);
46 let data = self.read_data()?;
48 let mut raw = (data[1] as u32) << 8;
50 raw += data[2] as u32;
51 raw <<= 4;
52 raw += (data[3] >> 4) as u32;
53 let hum = raw as f32 * 9.5367431640625e-5; let mut raw = (data[3] & 0x0F) as u32;
56 raw <<= 8;
57 raw += data[4] as u32;
58 raw <<= 8;
59 raw += data[5] as u32;
60 let temp = raw as f32 * 1.9073486328125e-4 - 50.0; Ok(Reading { temp, hum })
62 }
63
64 fn reset(&mut self) -> Result<(), E> {
65 let status = self.read_status()?;
66 if status & 0x18 != 0x18 {
67 info!("resetting");
68 self.write_data(&[0x1B, 0, 0])?;
69 self.write_data(&[0x1C, 0, 0])?;
70 self.write_data(&[0x1E, 0, 0])?;
71 }
72 Ok(())
73 }
74
75 fn read_data(&mut self) -> Result<[u8; 8], E> {
76 let mut buffer = [0; 8];
77 self.i2c.read(self.address, &mut buffer)?;
78 Ok(buffer)
79 }
80
81 fn read_status(&mut self) -> Result<u8, E> {
82 let mut buffer = [0; 1];
83 self.i2c.read(self.address, &mut buffer)?;
84 Ok(buffer[0])
85 }
86
87 fn write_data(&mut self, data: &[u8]) -> Result<(), E> {
88 self.i2c.write(self.address, data)
89 }
90}