Last active
August 4, 2019 17:53
-
-
Save Kadrian/a076170d2c3599980fd9 to your computer and use it in GitHub Desktop.
Get Temperature and Humidity from DHT11 module with Raspberry Pi and RPi.GPIO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RPi.GPIO as GPIO | |
import time | |
import traceback | |
# Helper | |
def bin2dec(string_num): | |
return str(int(string_num, 2)) | |
def setup_gpio(port): | |
GPIO.setmode(GPIO.BCM) | |
GPIO.setup(port,GPIO.OUT) | |
GPIO.output(port,GPIO.HIGH) | |
time.sleep(0.025) | |
GPIO.output(port,GPIO.LOW) | |
time.sleep(0.02) | |
GPIO.setup(port, GPIO.IN, pull_up_down=GPIO.PUD_UP) | |
def get_dht11_signal_stream(port, number): | |
signal_stream = [] | |
for i in range(0, number): | |
signal_stream.append(GPIO.input(port)) | |
return signal_stream | |
def cleanup_gpio(port): | |
GPIO.cleanup(port) | |
def divide_into_buckets(signal_stream): | |
# Remove first bit + leading 1s, so we can start with our first bucket | |
signal_stream = signal_stream[1:] | |
cleaned_stream = signal_stream[signal_stream.index(0):] | |
buckets = [] | |
current_bucket = [] | |
is_one = False | |
for bit in cleaned_stream: | |
if bit == 0: | |
if is_one: | |
buckets.append(current_bucket) | |
current_bucket = [bit] | |
is_one = False | |
else: | |
current_bucket.append(bit) | |
if bit == 1: | |
current_bucket.append(bit) | |
is_one = True | |
return buckets | |
def interpret_stream(signal_stream): | |
buckets = divide_into_buckets(signal_stream) | |
output = interpret_buckets(buckets) | |
return output | |
def interpret_buckets(buckets): | |
# The DHT11 module sends signals (binary data) in buckets | |
# that represent one bit each. | |
# | |
# E.g.00000000111111111 is a 1 while 0000000111 is a 0 | |
# | |
# The length of the 1s signal determines the bit | |
# so when there are more than <bit_threshold> 1s in a bucket | |
# it's interpreted as a 1, else as a 0 | |
bit_threshold = 6 | |
humidity_bits = "" | |
temperature_bits = "" | |
crc_bits = "" | |
if len(buckets) != 40: | |
print str(len(buckets)) + " Buckets found" | |
for b in buckets: | |
print b | |
raise Exception("Bad sensor data") | |
# Find out which bucket represents which bit for which measurement | |
# 5 times 8 bits: | |
# | |
# 0 - 7 : Humidity | |
# 7 - 15 : Not used here | |
# 16 - 24 : Temperature | |
# 25 - 31 : Not used here | |
# 32 - 39 : Checksum | |
for i, bucket in enumerate(buckets): | |
num_ones = sum(bucket) | |
if i < 8: | |
humidity_bits += "1" if num_ones > bit_threshold else "0" | |
elif i >= 16 and i < 24: | |
temperature_bits += "1" if num_ones > bit_threshold else "0" | |
elif i >= 32 and i < 40: | |
crc_bits += "1" if num_ones > bit_threshold else "0" | |
return { | |
"humidity_bits": humidity_bits, | |
"temperature_bits": temperature_bits, | |
"crc_bits": crc_bits | |
} | |
if __name__ == '__main__': | |
port = 4 | |
# The number of this might vary on your sensor, 800 worked for me | |
# Basically this has to be enough to capture all the buckets | |
# from the 40 bits the sensor is sending. | |
data_count = 1000 | |
setup_gpio(port) | |
signal_stream = get_dht11_signal_stream(port, data_count) | |
cleanup_gpio(port) | |
output = interpret_stream(signal_stream) | |
humidity = bin2dec(output["humidity_bits"]) | |
temperature = bin2dec(output["temperature_bits"]) | |
if int(humidity) + int(temperature) - int(bin2dec(output["crc_bits"])) == 0: | |
print "Humidity:"+ humidity +"%" | |
print "Temperature:"+ temperature +"C" | |
else: | |
print int(humidity) | |
print int(temperature) | |
print int(bin2dec(output["crc_bits"])) | |
print "ERR_CRC" |
However, it only works half of the times due to some weird GPIO to python real time issues. So make sure you try the script a bunch of times 😄
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I took the version from here: http://www.uugear.com/portfolio/dht11-humidity-temperature-sensor-module/ "reverse-engineered" it to understand what they're doing, refactored it a little and explained it with some comments. If you're trying to connect your Raspberry Pi with a DHT11 module temperature sensor, you might find this helpful!