Hooking Up a Raspberry Pi to a Temperature Sensor

Background and Intro

I recently asked for some project ideas on the Nerves slack channel to learn some more IoT and Raspberry Pi stuff. This article is the result of one of those suggestions. My eventual goal is to create an elixir/nerves based solution that reads temperature and humidity using a DHT-11 sensor and uploads them to a phoenix liveview web application, probably hosted on AWS. It would then show current and historical data from the sensor. However, I ran into a few issues with the elixir library I’m using for the DHT-11 sensor. For now, I’m going to focus this article on getting the electronics and hardware right and we’ll do the readings using python. This article will thus stand alone nicely, even if you don’t want to do the second and third parts using nerves and phoenix.

What are we doing?

  • We will put together a circuit using a raspberry pi, breadboard and a DHT-11 sensor
  • We will download the necessary linux and python libraries to get readings from the sensor
  • That’s all! Simple right?

Parts

There aren’t too many parts needed to get started. You will need:

  • A breadboard.
  • Some jumper wires.
  • A DHT-11 or DHT-22 sensor. I’m using the 11, because its cheap. The 22 has better accuracy.
  • A resistor. My DHT-11 came with 10k ohm resistor so that is what I’m using. 5k is the recommended resistence.
  • A Micro-USB cable or whatever cable to required to power your particular Pi. I use my laptop to power it so I don’t need a separate power supply, just the cable.
  • A raspberry pi. I’m using a pi 3. You might look at [CanaKit] (Optional) to provide the cables, pi, and other parts like I did.
  • An SD card that fits the pi

Getting Started

This project assumes that you are comfortable with the command line, installing libraries on the Raspberry Pi and can diagnose basic electronics. Most beginners should be able to follow along. We will be starting with the hardware, get everything setup and then move on to the software.

About the DHT-11

The DHT-11 is the heart of this project. It’s a small component that reads temperature and humidity and sends the data back to the device of our choice. You can read the datasheet from Mouser if you want. I had to ask around on the Elixir/Nerves slack channel to finally grok most of how the DHT-11 works and communicates with the Pi. If you want to skip this part and come back to it later, you can jump ahead to the actual project setup part.

As you can see, the DHT-11 has 4 pins. The third pin we can ignore, as that isn’t wired up to anything inside the DHT-11. The first pin provides power, either 3.3v or 5v. The second pin is data which can either be input or output, to and from the DHT-11. It took me a bit to wrap my brain around that. The fourth pin is ground, which you can wire to any ground connector on the Pi.

The DHT-11 has an interesting protocol for communication. We must first send a signal to tell the DHT-11 that we are ready to get a reading (temperature and humidity.) The component will switch from “low power mode” to running mode. So the Pi basically sends a message to tell the DHT-11 “Hey, we are ready to listen!” Then the component sends 40 bits of data back that include our temperature and humidity reading.

You might initially think like I did, that the device would send back a series of bits, where each high reading would be a “one” and each low reading would be a “zero”. On is one and off is zero, right? This is not the case. The way it was explained to me is that these components use something called PWM, or “Pulse Wave Modulation.” The DHT-11 DOES vary between high and low voltage, but it is the LENGTH of the high voltage that determines whether each bit is considered a one or zero. Low voltage signals are the “spaces” between each bit, almost like a delimiter. Specifically, a 70us (70 microseconds) length of high voltage represents a “one” and a 26-28us length of high voltage represents a “zero”. This is basically like Morse Code! The component will have a brief pause of zero voltage between each bit that it sends. The datasheet from Mouser confirms all this.

Once you add all these bits together with some other magic and convert them to decimal you have your reading. I’m handwaving a lot of this as its a tad more complicated. In any case, the python library will do this protocol translation for us and hopefully in future articles, I can get an elixir version to do the same.

Circuit Setup

I followed the following diagram to wire up the thermostat:

The specific power, GPIO and ground pins you use obviously don’t matter and as you’ll see below, I’m using a [CanaKit] which provides a ribbon cable to a mini-breadboard, which I then hook up to a larger breadboard making it easier to wire up. But the basics are the same:

  • We connect power (3-5.5v) from the Raspberry Pi to the 1st pin of the DHT-11
  • We also provide power to the left side of the resistor. The datasheet recommends at least 5k ohm resistor.
  • The right side of the resistor connects to pin 2 of the DHT-11, which is how the component handles input/output.
  • We then connect pin 2 to the GPIO pin of the Raspberry Pi. In my case, I’m using GPIO 26.
  • Finally, we connect pin 4 of the DHT-11 to ground on the Pi.

Remember you can use this interactive page to figure out power, GPIO or ground pins:

GPIO interactive pin diagram

Below are photos that you can use to base your project off of. You don’t necessarily need the CanaKit ribbon cable, but its nice. All that you need to know is that the breadboard its attached to has 3.3v at the top rails and 5v at the bottom rails, and then all the pins, including GPIO are in the middle and numbered on the connector.

DHT-11-Wiring 1
DHT-11-Wiring 2
DHT-11-Wiring 3
DHT-11-Wiring 4

Software

There’s not much software to install to finish off this project. We need to install Raspian or a similar operating system, install python, some development tools and the ADAFruit DHT library. You can do this directly on the pi, or you can SSH to it once the operating system is up.

I have a full article on how to install Raspian here and then SSH to it:

Read and follow the instructions there and then come back here when you’re done. Finished? Ok let’s continue…

Packages and Python

Once connected (either via keyboard or ssh) we then need to add the necessary packages with apt-get:

sudo apt-get update
sudo apt-get install build-essential python-dev python-openssl git

Finally, we need to install the AdaFruit DHT library. When I first tried to install this, I was following an older document that had out of date instructions. I suggest you check out the Github repo to check for yourself. I am also installing this for Python 2, not Python 3. So use the link above and vollow the python 3 instructions if you prefer that.

In any case, this is what I did at the time of this writing:

sudo apt-get install python-pip
sudo python -m pip install --upgrade pip setuptools wheel

Finally, install Adafruit_DHT itself:

sudo pip install Adafruit_DHT

At long last, we can create a python script in our home directory to check the readings. Fire up your favorite text editor (vi, nano etc…) and add the following code to it:

#!/usr/bin/python
import sys
import Adafruit_DHT

print 'running...'

while True:
	print 'next...'
	humidity, temperature = Adafruit_DHT.read_retry(11,26)
	print 'Temp: {0:0.1f} C  Humidity: {1:0.1f} %'.format(temperature, humidity)

Save the file as get_temp.

Remember to chmod +x get_temp to be able to execute it.

Notice the import Adafruit_DHT which is the library we just installed, doing all the work of checking voltages for us. I put print 'next...' so I would know the next time the loop runs. I did this bevcause the library itself, when we call the read_retry method, might pause for a bit and retry behind the scenes to get data from the component. Generally we can expect data about every 3 seconds. The DHT-11 doesn’t expect readings more than once every 2 seconds. However, sometimes the python library seemed to “hang” for anywhere from 5 to 20 seconds, and then start getting readings again. I’m not sure why.

When I ran the script using ./get_temp, I got the following:

pi@raspberrypi:~ $ ./get_temp
running...
next...
Temp: 25.0 C  Humidity: 38.0 %
next...
Temp: 25.0 C  Humidity: 38.0 %
next...
Temp: 26.0 C  Humidity: 35.0 %
next...
Temp: 26.0 C  Humidity: 35.0 %

And so on. Success! You now have a glorified thermometer. You can physically grab hold of the sensor gently with your fingers to watch the humidity and temperature go up or blow on it to cool it off. Just be careful not to wiggle any of the connections. You can stop it with CTRL+C and restart it if you need to.

Done!

As I said, I originally wanted to do this in Elixir, but I was having trouble with one of the libraries. If you want to see the elixir version, see the link below. I was finally able to get a working library:

Molte grazie!

A big thanks to Jon Carstens for explaining the DHT-11/22 protocol and working on a fix for his handy DHT-11 library and just generally being a huge help with this little project.