1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#![no_std]

use cortex_m::delay::Delay;
use rp2040_hal::gpio::AnyPin;
use rp2040_hal::pio::UninitStateMachine;
use rp2040_hal::pio::{PIOExt, StateMachineIndex};

mod dht;
use dht::DhtPio;

#[derive(Debug)]
pub enum DhtError {
    /// Timeout during communication.
    Timeout,
    /// CRC mismatch.
    CrcMismatch(u32, u32),
    /// FIFO Read error
    ReadError,
}

#[derive(Debug)]
pub struct DhtResult {
    pub temperature: f32,
    pub humidity: f32,
}

pub struct Dht22<P: PIOExt, STI: StateMachineIndex> {
    dht: DhtPio<P, STI>,
}

impl<P: PIOExt, STI: StateMachineIndex> Dht22<P, STI> {
    pub fn new<I: AnyPin<Function = P::PinFunction>>(
        pio: rp2040_hal::pio::PIO<P>,
        sm: UninitStateMachine<(P, STI)>,
        dht_pin: I,
    ) -> Self {
        Self {
            dht: DhtPio::new(pio, sm, dht_pin),
        }
    }

    pub fn read(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> {
        let (raw_temp, raw_hum) = self.dht.read_data(delay)?;
        let mut final_t: f32 = (raw_temp & 0x7FFF) as f32;

        if (raw_temp & 0x8000) > 0 {
            final_t *= -1.0;
        }

        Ok(DhtResult {
            temperature: final_t / 10.0,
            humidity: raw_hum as f32 / 10.0,
        })
    }
}

pub struct Dht22Type2<P: PIOExt, STI: StateMachineIndex> {
    dht: DhtPio<P, STI>,
}

impl<P: PIOExt, STI: StateMachineIndex> Dht22Type2<P, STI> {
    pub fn new<I: AnyPin<Function = P::PinFunction>>(
        pio: rp2040_hal::pio::PIO<P>,
        sm: UninitStateMachine<(P, STI)>,
        dht_pin: I,
    ) -> Self {
        Self {
            dht: DhtPio::new(pio, sm, dht_pin),
        }
    }

    pub fn read(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> {
        let (raw_temp, raw_hum) = self.dht.read_data(delay)?;

        let tmp: i16 = raw_temp as i16;

        Ok(DhtResult {
            temperature: (tmp as f32) / 10.0,
            humidity: raw_hum as f32 / 10.0,
        })
    }
}

pub struct Dht11<P: PIOExt, STI: StateMachineIndex> {
    dht: DhtPio<P, STI>,
}

impl<P: PIOExt, STI: StateMachineIndex> Dht11<P, STI> {
    pub fn new<I: AnyPin<Function = P::PinFunction>>(
        pio: rp2040_hal::pio::PIO<P>,
        sm: UninitStateMachine<(P, STI)>,
        dht_pin: I,
    ) -> Self {
        Self {
            dht: DhtPio::new(pio, sm, dht_pin),
        }
    }

    pub fn read(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> {
        let (t, h) = self.dht.read_data(delay)?;
        let mut final_t: f32 = ((t & 0x7FFF) >> 8) as f32;

        if (t & 0x8000) > 0 {
            final_t *= -1.0;
        }

        Ok(DhtResult {
            temperature: final_t,
            humidity: (h >> 8) as f32,
        })
    }
}