Skip to content

Instantly share code, notes, and snippets.

@Kadrian
Last active August 4, 2019 17:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kadrian/a076170d2c3599980fd9 to your computer and use it in GitHub Desktop.
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
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"
@Kadrian
Copy link
Author

Kadrian commented Jun 7, 2015

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!

@Kadrian
Copy link
Author

Kadrian commented Jun 7, 2015

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