dht11_spi
python3 driver that uses the SPI to receive binary data from the temp/humidity sensor. This driver uses a GPIO pin attached to a NPN transistor to send the low signal required to start the communication.
General GPIO Pin (NOT an SPI CS) used to pull the signal pin low. The DHT11/DHT22 will then send its binary data by pulling the data pin low. SPI bus reads the high and low data and determins the bits based on the time the sensor holds the voltage high. Data is converted to temperature and humidity.
NOTE: Requires SPI bus to run at a minimum of 250kHz to properly read the data. Only SPI0 on RPI4 functions properly. SPI1+ is not able to read data.
Related LearningToPi Posts | |
Git: https://github.com/LearningToPi/dht11_spi | |
PyPi: https://pypi.org/project/dht11-spi/ |
Wiring Diagram
Diagram Notes:
- The DHT11 10k Ω pullup is only necessary for DHT11 4-pin sensors, 3-pin include the pull up.
- 1k Ω and 2k Ω resistors are used for 5v to 3.3v stepdown. A stepdown converter may be used in place. (5v power is generally preferred by DHT11/22 for improved reading quality). Input connects to the SPI0 MISO port (GPIO 9 on the RPI4B).
- 470 Ω resistor is used to trigger the NPN transistor (GPIO 26 in this case).
- 2N5551 transistor is to pull the data line to ground to trigger the DHT11.
- Cabling, resistors and transistor are the same for DHT11 and DHT22 sensors.
How It Works
- DHT11/22 sensors at idle operate with the data line pulled high (5v in this case).
- Triggering the transistor by setting GPIO 26 high pulls the data line low for 20ms to trigger the DHT11/22 sensor (open ground to the data pin through the transistor)
- After setting GPIO 26 back to low, the transistor deactivates and the DHT11/22 sensor starts transmitting on the data line. The data 5v signal is leveled to 3.3v using either the 1k/2kΩ resistors (or you can use a signal leveler).
- Data sent by the DHT11/22 is read on the SPI0 bus at 250-500kHz.
- Grouping the binary data read from the SPI0 bus is translated into 0 and 1 bits based on how long the high level is received by the SPI0 bus.
NOTE: Requires SPI bus to run at a minimum of 250kHz to properly read the data. Only SPI0 on RPI4 functions properly. SPI1+ is not able to read data.
dht11_spi
– Install from PyPi
pip3 install -U dht11-spi
Usage Example – CLI
The dht11_spi library can be called from the command line using some basic command line options to query the DHT11 or DHT22 sensor and print the temperature and humidity data to the console.
(venv) $ python3 -m dht11_spi --help
usage: __main__.py [-h] [--gpio-chip GPIO_CHIP] [--dht22] [--time TIME] [--interval INTERVAL] [--spi SPI_BUS] [--spi-freq SPI_FREQ] [--rpi-lib] [--temp-f] gpio
Start a DHT11/22 test run using the dht11_spi library or the default RPi based library. Defaults to DHT11 unless --dht22 flag provided.
positional arguments:
gpio GPIO to use for signaling the DHT sensor. If using GPIO_CHIP other than 0, set the "--gpio-chip x" option.
optional arguments:
-h, --help show this help message and exit
--gpio-chip GPIO_CHIP
(default 0) GPIO chip for the GPIO provided. (0 typical for Pi4)
--dht22 (default False) Marks the sensor as a DHT22 (different calculations used)
--time TIME (default 120) Time in seconds to run the test
--interval INTERVAL (default 1 for dht11, 2 for dht22) Interval between reads. 1sec min for DHT11, 2sec min for DHT22 (per spec)
--spi SPI_BUS (default 0) SPI Bus number to use (assumes kernel driver loaded and accessible by spidev)
--spi-freq SPI_FREQ (default 500000Hz) Frequence to run on the SPI Bus. Min tested is 250000Hz
--rpi-lib (default False) Use the RPi DHT11 library instead of the dht11_spi (for comparison)
--temp-f (default False) Print temps in F rather than C
(venv) $ python3 -m dht11_spi --spi 0 26
2023-03-03 20:42:49,282 - root - INFO - DHT11_Spi (SPI0-500.0kHz): Opening
2023-03-03 20:42:49,282 - root - INFO - DHT11_Spi (SPI0-500.0kHz): Setting SPI bus speed from 125000000 to 500000
2023-03-03 20:42:49,285 - root - INFO - Starting test. Will run for 120 seconds
2023-03-03 20:42:49,386 - root - INFO - Temp: 23.04degC (73.472degF), Humidity 20.0%
2023-03-03 20:42:50,537 - root - INFO - Temp: 23.08degC (73.544degF), Humidity 19.0%
2023-03-03 20:42:51,640 - root - INFO - Temp: 23.08degC (73.544degF), Humidity 19.0%
<...output omitted...>
2023-03-03 20:44:48,315 - root - INFO - 105/105 (100.0%): Temps (min/avg/max): 23.0/24.03/24.1 deg C, Humidity (min/avg/max): 19.0/19.01/20.0 %
(venv) $ python3 -m dht11_spi --dht22 --spi 0 26
2023-03-03 20:46:17,371 - root - INFO - DHT22_Spi (SPI0-500.0kHz): Opening
2023-03-03 20:46:17,371 - root - INFO - DHT22_Spi (SPI0-500.0kHz): Setting SPI bus speed from 125000000 to 500000
2023-03-03 20:46:17,373 - root - INFO - Starting test. Will run for 120 seconds
2023-03-03 20:46:17,475 - root - INFO - Temp: 24.0degC (75.2degF), Humidity 35.7%
2023-03-03 20:46:19,624 - root - INFO - Temp: 24.4degC (75.92degF), Humidity 28.9%
<...output omitted...>
2023-03-03 20:48:17,395 - root - INFO - 57/57 (100.0%): Temps (min/avg/max): 24.0/24.52/24.6 deg C, Humidity (min/avg/max): 27.6/27.9/35.7 %
(venv) pi@rpi-kvm1:~/dev/dht11_spi $
Usage Example – Importing into Code
The dht11_spi library can be imported into your code and executed using the following example:
from ammeter_logger import AmmeterRecvSerial
# Import DHT SPI class
from dht11_spi import DHT11_Spi, DHT22_Spi
# initialize device, use (DHT11_Spi or DHT22_Spi)
# cs_chip and cs_pin from "gpioinfo". gpiod used for platform compat
dht = DHT22_Spi(spiBus=0, cs_chip=0, cs_pin=26)
reading = dht22.read() # returns instance of DhtReadings
print(reading)
# --or--
print(reading.temp_c, reading.temp_f, reading.humidity)
class DHT11_Exception(Exception)
Represents an error with the DHT11 class.
class DhtReadings
Represents a reading returend from the dht11_spi class. An object of this class will be returned when a read is called.
(property) temp_c()
Returns the temperature reading in Celcius
(property) temp_f()
Returns the temperature reading in Fahrenheit
(property) humidity()
Returns the humidity reading as a percentage (%)
class DHT11_Spi
__init__(spiBus:int, cs_pin:int, cs_chip=None, spi_hz=500000, set_spi_hz =True, logger=None, dht22=False)
Initalizes the DHT11 (or DHT22) sensor.
- spiBus (int) – SPI bus number the class should listen on.
- NOTE: For RPI4B systems, only SPI Bus 0 is operable
- cs_pin (int) – GPIO pin connected to the transistor used to trigger the DHT11/DHT22
- cs_chip (int) – GPIO chip number. Use “gpioinfo” to check for the proper chip number. If “None” uses chip 0
- NOTE: For RPI4B systems, all GPIO’s are on chip 0
- spi_hz (int) – Frequency to set the SPI bus to for reading. Tested 250,000 and 500,000. Defaults to 500,000
- set_spi_hz (bool) – Updates the SPI bus speed to the value provided from “spi_hz”
- NOTE: If you disable setting the SPI bus speed, be sure to set the speed to a supported frequency
close()
Close the SPI bus connection and the cs_pin used to trigger the DHT11/DHT22 sensor.
read() e
Performs a read on the sensor and returns an instance of the DhtReadings
class DHT22_Spi(DHT11_Spi)
__init__( *args, **kwargs)
Calls the DHT11_Spi
class with dht22
set to True