Rename + refector + CRC support

This commit is contained in:
Jonathan BAUDIN 2023-09-09 21:41:19 +02:00
parent 555911da16
commit 1186e8e888
5 changed files with 60 additions and 29 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "dht-pio" name = "dht-pio"
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"

View file

@ -26,8 +26,8 @@ For the moment, the crates have only been tested on a Raspberry Pico.
## TODO ## TODO
- [ ] Finish Readme - [ ] Finish Readme
- [ ] Add CRC read - [x] Add CRC read
- [ ] Check CRC - [x] Check CRC
- [ ] DHT11 support - [ ] DHT11 support
- [ ] Test DHT11 - [ ] Test DHT11
- [ ] Document code - [ ] Document code

View file

@ -29,8 +29,8 @@ Pour le moment le crates n'a été testé que sur un Raspberry Pico.
## TODO ## TODO
- [ ] Finir le Readme - [ ] Finir le Readme
- [ ] Ajouter la lecture du CRC - [x] Ajouter la lecture du CRC
- [ ] Vérifier le CRC - [x] Vérifier le CRC
- [ ] Support du DHT11 - [ ] Support du DHT11
- [ ] Tester DHT11 - [ ] Tester DHT11
- [ ] Documenter le code - [ ] Documenter le code

View file

@ -1,3 +1,4 @@
.define bit_to_recv 32
.program dht .program dht
; Clock must be set for 1µs per instruction ; Clock must be set for 1µs per instruction
@ -15,7 +16,9 @@
wait 0 pin 0 ; Wait for low wait 0 pin 0 ; Wait for low
wait 1 pin 0 ; wait for high wait 1 pin 0 ; wait for high
set x, 31 ; Set number bit to received (ignore CRC :( sorry ) set y, 4 ; set the number of byte to receive - 1
init_loop_data:
set x, 7 ; Set number bit to receive - 1
loop_data: loop_data:
wait 0 pin 0 ; Wait for low wait 0 pin 0 ; Wait for low
wait 1 pin 0 ; wait for high wait 1 pin 0 ; wait for high
@ -23,7 +26,10 @@
nop [29] ; wait for ~ 30 µS nop [29] ; wait for ~ 30 µS
in pins, 1 ; read the pin state and store bit value in pins, 1 ; read the pin state and store bit value
push iffull noblock ; Push data if full
jmp x--, loop_data ; Run until read all bits jmp x--, loop_data ; Run until read all bitsw
push ; send result jmp y--, init_loop_data
push ; Push the last bytes

View file

@ -11,7 +11,7 @@ pub enum DhtError {
/// Timeout during communication. /// Timeout during communication.
Timeout, Timeout,
/// CRC mismatch. /// CRC mismatch.
CrcMismatch, CrcMismatch(u32, u32),
/// FIFO Read error /// FIFO Read error
ReadError, ReadError,
} }
@ -22,14 +22,14 @@ pub struct DhtResult {
pub humidity: f32, pub humidity: f32,
} }
pub struct PicoDht<P: PIOExt, STI: StateMachineIndex> { pub struct DhtPio<P: PIOExt, STI: StateMachineIndex> {
// sm: PicoStateMachine<P, STI>, // sm: PicoStateMachine<P, STI>,
sm: StateMachine<(P, STI), Running>, sm: StateMachine<(P, STI), Running>,
rx_fifo: Rx<(P, STI)>, rx_fifo: Rx<(P, STI)>,
tx_fifo: Tx<(P, STI)>, tx_fifo: Tx<(P, STI)>,
} }
impl<P: PIOExt, STI: StateMachineIndex> PicoDht<P, STI> { impl<P: PIOExt, STI: StateMachineIndex> DhtPio<P, STI> {
pub fn new<I: AnyPin<Function = P::PinFunction>>( pub fn new<I: AnyPin<Function = P::PinFunction>>(
mut pio: rp2040_hal::pio::PIO<P>, mut pio: rp2040_hal::pio::PIO<P>,
sm: UninitStateMachine<(P, STI)>, sm: UninitStateMachine<(P, STI)>,
@ -45,6 +45,7 @@ impl<P: PIOExt, STI: StateMachineIndex> PicoDht<P, STI> {
let (mut sm, rx, tx) = rp2040_hal::pio::PIOBuilder::from_program(installed) let (mut sm, rx, tx) = rp2040_hal::pio::PIOBuilder::from_program(installed)
.set_pins(pin.id().num, 1) .set_pins(pin.id().num, 1)
.clock_divisor_fixed_point(int, frac) .clock_divisor_fixed_point(int, frac)
.push_threshold(32)
.build(sm); .build(sm);
sm.set_pindirs([(pin.id().num, rp2040_hal::pio::PinDir::Output)]); sm.set_pindirs([(pin.id().num, rp2040_hal::pio::PinDir::Output)]);
@ -58,10 +59,22 @@ impl<P: PIOExt, STI: StateMachineIndex> PicoDht<P, STI> {
/// Read data from the sensor. This blocking function (for maximum timeout of 2 seconds). /// Read data from the sensor. This blocking function (for maximum timeout of 2 seconds).
pub fn read_data(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> { pub fn read_data(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> {
let mut timeout = 2000; let mut timeout = 2000;
let mut raw: [Option<u32>; 2] = [None; 2];
self.tx_fifo.write(1); self.tx_fifo.write(1);
while timeout > 0 && self.rx_fifo.is_empty() { while timeout > 0 && raw[1].is_none() {
match self.rx_fifo.read() {
Some(d) => {
if raw[0].is_none() {
raw[0] = Some(d);
} else {
raw[1] = Some(d);
}
}
None => (),
}
delay.delay_ms(1); delay.delay_ms(1);
timeout -= 1; timeout -= 1;
} }
@ -71,20 +84,32 @@ impl<P: PIOExt, STI: StateMachineIndex> PicoDht<P, STI> {
return Err(DhtError::Timeout); return Err(DhtError::Timeout);
} }
let raw = match self.rx_fifo.read() { let data = raw[0].unwrap();
Some(d) => d, let crc = raw[1].unwrap();
None => {
self.sm.restart();
return Err(DhtError::ReadError);
}
};
let t_raw = raw & 0x0000FFFF; if Self::compute_crc(data) != crc {
let h_raw = (raw & 0xFFFF0000) >> 16; return Err(DhtError::CrcMismatch(
raw[0].unwrap_or(0),
raw[1].unwrap_or(0),
));
}
let t_raw = data & 0x0000FFFF;
let h_raw = (data & 0xFFFF0000) >> 16;
Ok(DhtResult { Ok(DhtResult {
temperature: t_raw as f32 / 10.0, temperature: t_raw as f32 / 10.0,
humidity: h_raw as f32 / 10.0, humidity: h_raw as f32 / 10.0,
}) })
} }
fn compute_crc(data: u32) -> u32 {
let mut crc: u32 = 0;
crc += data & 0x000000FF;
crc += (data & 0x0000FF00) >> 8;
crc += (data & 0x00FF0000) >> 16;
crc += (data & 0xFF000000) >> 24;
crc % 256
}
} }