#dht #hal #sensors #dht11 #dht22 #driver #digital

no-std dht-hal-drv

HAL based driver for digital humidity and temperature sensors DHT11, DHT21, DHT22

4 releases

0.2.2 Dec 6, 2021
0.2.1 Jan 15, 2020
0.2.0 Oct 16, 2019
0.1.0 Oct 11, 2019

#1599 in Embedded development

Custom license

17KB
124 lines

HAL based driver for DHT sensors

crates.io Released API docs

Digital humidity and temperature sensors (DHT) from Adafruit are widely used especially in different kind of DIY projects.

This driver supports next sensors revisions: DHT11, DHT21, DHT22.

I have tested it on Raspberry Pi 3 and STM32 Blue Pill board. All platform specific implementations are available in examples directory.

Licensing

This product is licenses under almost MIT license but with plumbus exception.


lib.rs:

HAL based driver for Digital Humidity and Temperature sensors (DHT)

Because of some limitations in HAL API and limitations in some HW implementations using this sensor is some kind of tricky.

DHT use one pin for communication that should work in open drain (open connect) mode. For hardware that does not have such pin implementations you should emulate its behaviour.

You can get readings by:

  • using single function to read all data
  • using splitted functions for initialization and reading while converting pin to different modes between calls

Should notice that DHT initialization process has some caveats. There have to be near 1 sec delay before next reading. At his time pull-up resistor in DHT circuit would pull up data pin and this would prepare DHT for next reading cycle.

Delay implementation issues should be taken into account. On some platforms sleep at some amount of microseconds means "sleep at least N us". For example on RPi with std::thread::sleep nothing would work. For such case should use dht_split_read without delay or another sleep implementations like spin_sleep.

Examples

Using open drain pin

let delay; // Something that implements DelayUs trait
let open_drain_pin; // Open drain pin, should be in open mode by default
// Need to create closure with HW specific delay logic that DHT driver is not aware of
let mut delay_us = |d| delay.delay_us(d);

// ... Some code of your APP ... //
let result = dht_read(DhtType::DHT11, &mut open_drain_pin, &mut delay_us);
// ... Other code of your APP ... //

Using dht_split_* functions

Such approach is useful if you your device does not have open drain pin and you need to emulate it or you have slow CPU and do not want to use delays while reading.

use dht_hal_drv::{dht_split_init, dht_split_read, DhtError, DhtType, DhtValue};

// ... Some code of your APP ... //

let delay; // Something that implements DelayUs trait
let pin_in; // Pin configured as input floating

// Should create closure with
// custom HW specific delay logic that DHT driver is not aware of
let mut delay_us = |d| delay.delay_us(d);

// pin to output mode
let mut pin_out = pin_in.into_push_pull_output();

// Initialize DHT data transfer
// Before reading begins MCU must send signal to DHT which would initiate data transfer from DHT.
dht_split_init(&mut pin_out, &mut delay_us);

// You can check dht_split_init response for errors if you want

// WARNING there should be no additional logic between dht_split_init and dht_split_read

// Should convert pin back to input floating
let mut pin_in = pin_out.into_floating_input(cr);

// Now let's read some data
// Here you can pass empty delay_us closure to skip using delays on slow CPU
let readings = dht_split_read(DhtType::DHT11, &mut pin_in, &mut delay_us);

// ... Other code of your APP ... //

Working examples for particular HW platforms could be found in source repository.

Inspiration sources

Dependencies

~71KB