Assignments, GPIO, Humidity, Python, Raspberry Pi, Sensors, Temperature

Assignment #2: Raspberry Pi + DH-T11 Tutorial

Hello an welcome back! The purpose of this week’s assignment is to produce a tutorial on how to use the DHT-11 temperature and humidity sensor with the Raspberry pi. In this tutorial I will:

  • describe the purpose of the activity,
  • introduce the components needed,
  • describe how to arrange and mount said components on a breadboard,
  • present a very small and useful python library to make use of the sensor and
  • provide a python script that reads and presents sensor data.

Additionally, I will  also discuss the SPI interface on the Raspberry Pi.



The primary purpose of this tutorial is getting the Raspberry Pi to read temperature and humidity data captured by the DHT-11 sensor. In order to to this, we will run a Python script on the Pi which will be connected to the sensor using its GPIO pins.


For this tutorial you will need:

  1. A Raspberry Pi
  2. A DHT-11 temperature and humidity sensor
  3. A breadboard
  4. 1 x 10KΩ resistor
  5. Jumper wires
  6. A breakout board and 40-pin ribbon cable


Screen Shot 2016-01-30 at 5.59.35 PM

The breakout board and 40-pin ribbon cable are not mandatory, but having them might make building the circuit a little bit easier. Also, if like me you bought the Oddwires IoT Kit 1.1, you already have a DHT-11 sensor.

The Setup

Screen Shot 2016-01-30 at 11.52.38 AM

DHT11 schematic

The DHT-11 is a very convenient, inexpensive and easy to implement sensor. As you can see from the schematic, for it to work you must connect VDD to 3.3V-5.0V, GND to ground and DATA to an input pin. Also, you must connect a 4.7KΩ-10KΩ resistor from the DATA pin to VCC.


THIS Adafruit tutorial serves as a good starting point for the understanding and setup of the components and the circuit. My setup can be observed in the following schematic and diagram, and the implementation can be observed in the subsequent picture. Notice that the DATA pin of the sensor is wired to the GPIO pin #4 (or pin #9).

Screen Shot 2016-01-30 at 11.44.48 AM

Setup diagram

Screen Shot 2016-01-30 at 11.43.51 AM

Setup schematic

Go ahead and put your setup together. You should end up with something equivalent to this:


My implementation

NOTE: notice that in my implementation of the circuit, the Vilros breakout board has a 3V3+/- wing of which I’m using the +3.3V pin, but I am wiring the DHT-11’s GND pin directly to the breakout board’s pin 9 (GND) on row 5 of the breadboard. I did this because I wasn’t sure if the -3.3V pin on the 3V3+/- wing corresponded to ground as well.

By the way, both the diagrams and the schematics I presented above (and the ones I will show below) were produced using Fritzing, a free and open-source software. Feel free to download!

DHT-11 Python Library

Being usual amongst low cost sensors, the output format of the DHT-11 is not SPI, I2C or 1-Wire compatible (some common sensor formats, more on SPI later). Instead, the data from the sensor must be polled continuously by the Raspberry pi. For this, Adafruit provides a library in the tutorial mentioned in the previous section, but I decided to use a small Python library I found on Github, written by Zoltán Szarvas (@szazo). It can be downloaded HERE. Opposed to the library provided by Adafruit, Zoltán’s library will work ONLY WITH THE DHT-11.

The library is basically a .py file containing the definition of the classes DHT11 and DHT11Result, which making use of the RPi.GPIO and the time python libraries read the binary data from the sensor.

[sourcecode language=”python” wraplines=”false” collapse=”false”]
#Source code taken from
import time
import RPi.GPIO as GPIO

class DHT11Result:
‘DHT11 sensor result returned by method’


error_code = ERR_NO_ERROR
temperature = -1
humidity = -1

def __init__(self, error_code, temperature, humidity):
self.error_code = error_code
self.temperature = temperature
self.humidity = humidity

def is_valid(self):
return self.error_code == DHT11Result.ERR_NO_ERROR

class DHT11:
‘DHT11 sensor reader class for Raspberry’

__pin = 0

def __init__(self, pin):
self.__pin = pin

def read(self):
GPIO.setup(self.__pin, GPIO.OUT)

# send initial high
self.__send_and_sleep(GPIO.HIGH, 0.05)

# pull down to low
self.__send_and_sleep(GPIO.LOW, 0.02)

# change to input using pull up
GPIO.setup(self.__pin, GPIO.IN, GPIO.PUD_UP)

# collect data into an array
data = self.__collect_input()

# parse lengths of all data pull up periods
pull_up_lengths = self.__parse_data_pull_up_lengths(data)

# if bit count mismatch, return error (4 byte data + 1 byte checksum)
if len(pull_up_lengths) != 40:
return DHT11Result(DHT11Result.ERR_MISSING_DATA, 0, 0)

# calculate bits from lengths of the pull up periods
bits = self.__calculate_bits(pull_up_lengths)

# we have the bits, calculate bytes
the_bytes = self.__bits_to_bytes(bits)

# calculate checksum and check
checksum = self.__calculate_checksum(the_bytes)
if the_bytes[4] != checksum:
return DHT11Result(DHT11Result.ERR_CRC, 0, 0)

# ok, we have valid data, return it
return DHT11Result(DHT11Result.ERR_NO_ERROR, the_bytes[2], the_bytes[0])

def __send_and_sleep(self, output, sleep):
GPIO.output(self.__pin, output)

def __collect_input(self):

# collect the data while unchanged found
unchanged_count = 0

# this is used to determine where is the end of the data
max_unchanged_count = 100

last = -1
data = []
while True:
current = GPIO.input(self.__pin)
if last != current:
unchanged_count = 0
last = current
unchanged_count += 1
if unchanged_count > max_unchanged_count:

return data

def __parse_data_pull_up_lengths(self, data):



lengths = [] # will contain the lengths of data pull up periods
current_length = 0 # will contain the length of the previous period

for i in range(len(data)):

current = data[i]
current_length += 1

if current == GPIO.LOW:
# ok, we got the initial pull down

if state == STATE_INIT_PULL_UP:
if current == GPIO.HIGH:
# ok, we got the initial pull up

if current == GPIO.LOW:
# we have the initial pull down, the next will be the data pull up

if state == STATE_DATA_PULL_UP:
if current == GPIO.HIGH:
# data pulled up, the length of this pull up will determine whether it is 0 or 1
current_length = 0

if current == GPIO.LOW:
# pulled down, we store the length of the previous pull up period

return lengths

def __calculate_bits(self, pull_up_lengths):

# find shortest and longest period
shortest_pull_up = 1000
longest_pull_up = 0

for i in range(0, len(pull_up_lengths)):

length = pull_up_lengths[i]
if length < shortest_pull_up:
shortest_pull_up = length
if length > longest_pull_up:
longest_pull_up = length

# use the halfway to determine whether the period it is long or short
halfway = shortest_pull_up + (longest_pull_up – shortest_pull_up) / 2

bits = []

for i in range(0, len(pull_up_lengths)):

bit = False
if pull_up_lengths[i] > halfway:
bit = True


return bits

def __bits_to_bytes(self, bits):

the_bytes = []
byte = 0

for i in range(0, len(bits)):

byte = byte << 1
if (bits[i]):
byte = byte | 1
byte = byte | 0

if ((i + 1) % 8 == 0):
byte = 0

return the_bytes

def __calculate_checksum(self, the_bytes):
return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255

There are two major advantages to using this library. One is that we get builtin error code handling, and the other is that we get access to the sensor data just by using the GPIO number as a function’s argument!

[sourcecode language=”python” wraplines=”false” collapse=”false”]
#Example usage of the library by @szazo

instance = dht11.DHT11(pin = 14)
result =
if result.is_valid():
print("Error: " % result.error_code)


Python Script and Execution

First of all, turn off your Raspberry Pi, and put the whole setup together using the 40-pin ribbon cable to join the GPIO pins with the T Cobbler Breakout board:

Screen Shot 2016-01-30 at 11.44.09 AM

Complete setup diagram


My complete setup


Pi running with DHT-11 setup connected

Connect your mouse, keyboard, screen, ethane cable/WiFi and power to the Pi and let it boot normally. Download the library from Github using the terminal and the git command:

$ git clone


NOTE: Having downloaded the library, make sure to place a copy the file it in the same folder as the python script in which you want to make use of it:

Screen Shot 2016-01-30 at 9.44.45 PM

The file in the same folder as my script

Once you have done that, open IDLE3 and create a new script with the following contents:

[sourcecode language=”python” wraplines=”false” collapse=”false”]

#Import RPi.GPIO to make use of the GPIO Pins
import RPi.GPIO
#Import Zoltan Szarvas’s DHT11 Python library (./
import dht11

#Initialize the GPIO in BCM Mode to access pins using their GPIO number

#Read data using GPIO pin 4
instance = dht11.DHT11(pin = 4)
result =

#Check if result is valid (provided by dht11 library)
if result.is_valid():
#print out temperature and humidity values
print("Temperature: %d C" % result.temperature)
print("Humidity: %d %%" % result.humidity)
#Error handling provided by dht11 library
#print out error code
print("Error: %d" % result.error_code)

#Cleanup the GPIO pins before ending



Save the file using whatever filename you want. In my case I used the filename


Screen Shot 2016-01-30 at 4.29.56 PM

Terminal window executing the script shown on an IDLE3 window

Then execute the script on a terminal using sudo to get admin privileges, and wait to see the output produced by the script:


$ sudo python3




Screen Shot 2016-01-30 at 11.19.14 PM

Script output showing temperature and humidity measurements

Eureka! If everything went well, you will see the output strings on the terminal window showing you the current temperature and humidity data sensed by the DHT-11, like in the above image.

If you see an error message like this:

Screen Shot 2016-01-30 at 11.16.09 PM

Script output showing an ERROR

you might have a connection error with the circuit. This means the Pi is unable to receive signals from the DHT-11. I suggest you check your setup carefully using the diagrams and schematics presented in the previous sections.

NOTE: all the code I present here can also be found on THIS repository of my Github account.


The Raspberry Pi’s SPI Interface


SPI stands for Serial Peripheral Interface. It is a short-distance serial bus communication standard developed by Motorola primarily used in embedded systems. Since then, SPI has become one of the most commonly accepted and used serial communications standards. Some of the particularities about SPI are that it is a synchronous serial bus, implementing  full-duplex protocol using a ‘master/slave‘ paradigm. This means that all communications are governed by a master system clock, and these communications can go both ways: from master to slave, or from slave to master. The following diagram illustrates the architecture:


If we detail the previous diagram, we can tell that each SPI component has a system clock I/O, a Master Output/Slave Input I/O, a Master Input/Slave Output I/O and a Slave Select I/O. Wether any of these signals is an Input or an Output is determined by the type of component. A master component will have SLCK, MOSI and SSn as Outputs and MISO as Input; a slave component will have an opposite configuration. It is also evident that more than one slave components can be connected to a master component, but for each one an extra Slave Select pin is needed in addition to SCLK, MOSI and MISO.

Another caveat of working with SPI is that you need to ‘send a byte to receive a byte‘. This is true because a master component communicates with a slave component through commands. In a oversimplified way, first it will send the request command to the slave, and the slave will respond with acknowledgement. Then the master will send the slave the address of the data block, and the slave will look up the data and respond with acknowledgement again. Finally the master sends the transfer command to the slave, and the it responds with the data. So as you see,communications take place synchronously. Also, depending on the slave component, specifications for command bytes, times and communications protocol might change, but all SPI components will hold to presented I/O signal scheme.

Raspberry Pi 2 Model B SPI Capabilities

If you detail the Pi’s pin diagram, you will see that GPIO11, GPIO09 and GPIO10 (pins 23, 19 and 21) correspond to SPI_CLK, SPI_MOSI and SPI_MISO respectively:

GPIO_Pi2In this case, our Slave Select I/Os would be GPIO08, GPIO07 (pins 24 and 26) named SPI_CE0_N and SPI_CE1_N respectively. I believe you could also use any of the other unused GPIOs as SS I/Os, but you might have to program them yourself, as GPIO07 and GPIO08 are the only SS pint that are part of the Pi’s builtin SPI bus.

As we can see, the Raspberry Pi is readily equipped  with SPI capabilities because it implements the necessary I/Os for the Interface. So, instead of using a temperature sensor like the DHT-11 (which is not very precise), we could use a SPI compatible high precision digital temperature sensor like the Adafruit BME280 (but that’s just a whole different story).

Alright! I hope you enjoyed this post and might have learned a thing or two. See you next week!



Disclaimer: English is not my first language, though I do handle it well. Please excuse any typos and grammatical errors you might find. If you’re kind enough to point them out, I’ll make sure to correct them. 



  1. Seen a similar idea elsewhere but using a 1-wire device rather than the DHT-11, the 1-wire setup would seem to have the advantage that you can have multiple sensors on one GPIO pin which seems to me to be better – any comment?

    • Comment by post author

      Jorge A. Duarte G.

      Hello and thanks for your comment! Well, I think that a 1-wire setup might have the advantage if you need to have the sensor wired farther apart from the Raspberry Pi, or use multiple sensors to average a reading. It would be more simple and advantageous to use only one GPIO pin for this, but note that even though communications between master and slave would be bidirectional, they would also be ‘half-duplex’. You might find a bit more information on that here:

  2. Daryl

    How would I convert printout Temperature from Celsius to Fahrenheit in this code?

    • Comment by post author

      Jorge A. Duarte G.

      Hello Daryl,

      thank you for reading my post, and I hope these blog has been helpful.

      In order to print out Fahrenheit units, you must convert the output in Celsius by using the formula:

      Tf = Tc*(9/5) + 32.

      This means you have to edit portion of the script which returns the temperature, into something like this:

      if result.is_valid():
      #print out temperature and humidity values
      print(“Temperature: %d F” % (result.temperature * (9/5) + 32) )
      print(“Humidity: %d %%” % result.humidity)

      I hope this helps.


      – Jorge

Leave a Reply