Skip to main content

dht20/
lib.rs

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        // request reading
44        self.write_data(&[0xAC, 0x33, 0])?;
45        self.delay.delay_ms(80);
46        // read data
47        let data = self.read_data()?;
48        // convert values
49        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; // ==> / 1048576.0 * 100%;
54
55        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; //  ==> / 1048576.0 * 200 - 50;
61        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}