This is an improvement on a previous implementation, and many others that use fixed thresholds for decoding.
In certain circumstances the new implementation significantly reduces error rate when reading from the sensor (e.g., in one recorded scenario from 40% to <1%), for the reasons described below.
In the previous implementation, the data
(5 bytes: 2 each for humidity/temperature and 1 for a checksum)
is decoded by classifying signal pulses sent by the DHT22 as 1
or 0
depending if the duration held by the state is
longer than 16 microseconds or not.
Sometimes, this classification is inaccurate and we get bad data, which is typically invalidated by the checksum. To see why, here is realistic example of recorded state durations in microseconds (1 byte only):
Signal A: ( 3, 2, 3, 8, 8, 9, 8, 3)
Signal B: ( 9, 9, 9,32,33,33,32, 8)
Signal C: (25,26,26,74,73,74,75,23)
True decoded data: ( 0, 0, 0, 1, 1, 1, 1, 0)
It is clear to see that the encoded data is present in all signals, but with a fixed threshold of 16 microseconds only signal B will be decoded correctly. I'm not sure exactly why in some circumstances the state durations are longer/shorter. I've observed consistently shorter durations when running this in a docker container.
The newer the decoding technique uses k-means (k=2) to cluster the signal into upper and lower
clusters and classify any states assigned to the upper cluster as a 1
. This results in all
signals A, B and C being decoded correctly.
Other changes:
- Fix undefined behaviour when reading too many bits in the read loop
Install wiringPi to be able to interface with Raspberry Pi GPIO pins
git clone https://github.com/WiringPi/WiringPi.git WiringPi
cd WiringPi
./build
Look at the pin numbers
gpio readall
Map the Physical
pin, on your Raspberry Pi that the DHT22 data line is connected to, to the BCM
pin.
Compile using g++
g++ dht22.cpp dht22lib.cpp -lwiringPi -o dht22.exe
To view the debug table showing the results of the robust decoder, use the
-DDEBUG
compile option.g++ dht22.cpp dht22lib.cpp -lwiringPi -DDEBUG -o dht22.exe
Run, giving the pin number as an argument (in this example I use pin 13)
./dht22.exe 13