embedded_dht_rs/
dht11.rs

1use embedded_hal::{
2    delay::DelayNs,
3    digital::{InputPin, OutputPin, PinState},
4};
5
6use crate::{dht::Dht, SensorError, SensorReading};
7
8pub struct Dht11<P: InputPin + OutputPin, D: DelayNs> {
9    dht: Dht<P, D>,
10}
11
12impl<P: InputPin + OutputPin, D: DelayNs> Dht11<P, D> {
13    pub fn new(pin: P, delay: D) -> Self {
14        Self {
15            dht: Dht::new(pin, delay),
16        }
17    }
18
19    pub fn read(&mut self) -> Result<SensorReading<u8>, SensorError> {
20        // Start communication: pull pin low for 18ms, then release.
21        let _ = self.dht.pin.set_low();
22        self.dht.delay.delay_ms(18);
23        let _ = self.dht.pin.set_high();
24
25        // Wait for sensor to respond.
26        self.dht.delay.delay_us(48);
27
28        // Sync with sensor: wait for high then low signals.
29        let _ = self.dht.wait_until_state(PinState::High);
30        let _ = self.dht.wait_until_state(PinState::Low);
31
32        // Start reading 40 bits
33        let humidity_integer = self.dht.read_byte()?;
34        let humidity_decimal = self.dht.read_byte()?;
35        let temperature_integer = self.dht.read_byte()?;
36        let temperature_decimal = self.dht.read_byte()?;
37        let checksum = self.dht.read_byte()?;
38
39        // Checksum
40        let sum = humidity_integer
41            .wrapping_add(humidity_decimal)
42            .wrapping_add(temperature_integer)
43            .wrapping_add(temperature_decimal);
44        if sum != checksum {
45            return Err(SensorError::ChecksumMismatch);
46        }
47
48        Ok(SensorReading {
49            humidity: humidity_integer,
50            temperature: temperature_integer,
51        })
52    }
53}