embedded_dht_rs/
dht22.rs

1use embedded_hal::{
2    delay::DelayNs,
3    digital::{InputPin, OutputPin, PinState},
4};
5
6use crate::{dht::Dht, SensorError, SensorReading};
7
8pub struct Dht22<P: InputPin + OutputPin, D: DelayNs> {
9    dht: Dht<P, D>,
10}
11
12impl<P: InputPin + OutputPin, D: DelayNs> Dht22<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<f32>, 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_high = self.dht.read_byte()?;
34        let humidity_low = self.dht.read_byte()?;
35        let temperature_high = self.dht.read_byte()?;
36        let temperature_low = self.dht.read_byte()?;
37        let checksum = self.dht.read_byte()?;
38
39        // Checksum
40        let sum = humidity_high
41            .wrapping_add(humidity_low)
42            .wrapping_add(temperature_high)
43            .wrapping_add(temperature_low);
44        if sum != checksum {
45            return Err(SensorError::ChecksumMismatch);
46        }
47
48        let humidity_value = ((humidity_high as u16) << 8) | (humidity_low as u16);
49        let humidity_percentage = humidity_value as f32 / 10.0;
50
51        let temperature_high_clean = temperature_high & 0x7F; // 0x7F = 0111 1111
52        let temperature_value = ((temperature_high_clean as u16) << 8) | (temperature_low as u16);
53        let mut temperature_percentage = temperature_value as f32 / 10.0;
54
55        if temperature_high & 0x80 != 0 {
56            temperature_percentage = -temperature_percentage;
57        }
58
59
60        Ok(SensorReading {
61            humidity: humidity_percentage,
62            temperature: temperature_percentage,
63        })
64    }
65}