Temperature and Humidity from AM2302/DHT22 Sensor Displayed as Chart

In this how-to, the Raspberry Pi will be configured to automatically acquire and log temperature and humidity from a AM2302/DHT22/DHT11 sensor and display the collected data like in the following picture.


About the AM2302/DHT22 Temperature and Humidity Sensor

The AM2302 and DHT22 sensors share the same characteristics. From my perspective these sensors are the same. The DHT11 on the other hand is a little cheaper but only intended for indoor use. On e-Bay you can find a pack of 5 peaces of the AM2302 for about 17 EUR with free shipping.
The sensor is already calibrated by the manufacturer. It is almost plug and play.
Unlike some temperature sensors, each of these temperature and humidity sensors requires its own data line. So connecting several sensors on a single one-wire bus is not supported because the sensor does not have an address.
The maximum cable length can be up to 30 meters / 98 feet if you use 5 V power and 1 meter / 3.3 feet if you use 3.3 V power (see Datasheet). In this how-to I will use 3.3 V because the voltage of all RPi's GPIO pins, which can be used as data pins, is 3.3 V.
The sensor contains an 8 bit micro-controller. The sensor has an average power consumption of only 0.3 mA (300 micro ampere). The low power consumption is achieved by going into sleep mode periodically. A new sensor value can only be obtained every 2 seconds. (See Datasheet)

Needed Parts
  • A Raspberry Pi that is connected to the internet.
  • A sensor of type AM2302 or DHT22. If you use a DHT11, then the wiring may differ.
  • A 4.7k Ohm resistor. If you do not have a 4.7k Ohm resistor, but a potentiometer and a voltmeter, then you can use the potentiometer as resistor and the voltmeter to set the potentiometer to 4.7k Ohm resistance (see here). Some articles state, that you can also use a 10k Ohm resistor, but I did not test this.
  • Jumper cables to connect the parts.
  • Optionally a breadboard, which may make it easier to connect the parts.

Wiring

Wire the sensor as shown in the following picture. The first sensor pin is 3.3V-5.5V, the second is bidirectional serial data, the third is not used and the fourth is ground. The resistor is used as a pull-up resistor.


Getting Temperature and Humidity

Run sudo apt-get update and sudo apt-get upgrade -y to ensure your system is up to date.
The temperature and humidity refers to a time of the day. For the data to be correct, your timezone must be set correctly. When you execute date you should see the local time. If not, then you can set the correct timezone in sudo raspi-config.
To communicate with the sensor, the Adafruit_Python_DHT library is used. It talks to the GPIO pins without using the Wiring Pi library. To install it, get the dependencies with
sudo apt-get install -y build-essential python-dev git and then download and install the library with

mkdir -p /home/pi/sources  
cd /home/pi/sources  
git clone https://github.com/adafruit/Adafruit_Python_DHT.git  
cd Adafruit_Python_DHT  
sudo python setup.py install  

Now you can already get the temperature and humidity with the command
sudo /home/pi/sources/Adafruit_Python_DHT/examples/AdafruitDHT.py 2302 4. The first argument is the sensor type, it can be 11 or 22 or 2302. The second argument is the RPi GPIO pin which is connected to the sensor data pin. Actually the sensor can be queried from any Python script with just two lines of code. You can try this by starting Python interactive with sudo python then in the interactive mode type

import Adafruit_DHT  
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.AM2302, 4)  
temperature  
humidity  

Press Ctrl-D to quit Python interactive mode.

Saving Sensor Values in CSV Files

To allow time-series analysis or visualization of the temperature and humidity, the values must be stored. The script that is used, appends a value every 60 seconds to a CSV file. This interval can be changed. However what if you would want the very latest sensor value? To achieve this, the script will write the latest value in a separate CSV file and update this value about every two seconds. The CSV file with the latest value contains only one data row with the latest value.
To make the script usable for other sensors, temperature and humidity are saved in separate files. Thus if one would add another temperature sensor to the existing temperature and humidity sensor, then one would have effectively two temperature sensors and one humidity sensor.
First create a directory where all files, which are needed to save and display the sensor data, are stored.

mkdir -p /home/pi/projects/temp-and-humidity  
mkdir -p /home/pi/projects/temp-and-humidity/sensor-values  
cd /home/pi/projects/temp-and-humidity  

Download the script with

wget http://www.home-automation-community.com/downloads/temp-and-humidity/temperature-and-humidity-to-csv-logger.py  

Before running the script, a dependency must be installed with
sudo easy_install apscheduler
Further the script requires a subdirectory that can be created with
mkdir -p /home/pi/projects/temp-and-humidity In the script, the sensor is set to 2302 and the GPIO pin is set to 4. If your values differ, then you can edit the Python script. The sensor name can also be set in the script.
Now you can start the Temperature and Humidity to CSV Logger with
sudo python temperature-and-humidity-to-csv-logger.py
After 3 or 4 minutes, you should see 4 CSV files as in the following screenshot.
It should be noted that the Python script needs 3 to 4 minutes setup time before data is recorded. After this setup time, the script uses only 1-2% of the RPi CPU to collect the sensor data.

Visualizing Sensor Values in an Interactive Chart

To display the sensor values in a chart, a HTML page with NVD3 charts for d3.js is used together with a node.js JavaScript file that contains a node.js Express web server. The web server contains two web service methods and it delivers static content from the public subfolder. The newest express version 4 is used.
Node.js is already installed on the official RPi image. You can check this with node --version which should display a version and no error. You could install node.js with the following four lines

mkdir -p /home/pi/sources  
cd /home/pi/sources  
wget http://node-arm.herokuapp.com/node_latest_armhf.deb  
sudo dpkg -i node_latest_armhf.deb  

To download the HTML page to the public subfolder type

mkdir -p /home/pi/projects/temp-and-humidity/public  
cd /home/pi/projects/temp-and-humidity/public  
wget http://www.home-automation-community.com/downloads/temp-and-humidity/index.html  

To download the node.js script type

cd /home/pi/projects/temp-and-humidity  
wget http://www.home-automation-community.com/downloads/temp-and-humidity/nodejs-webserver-with-soap-services.js  

The node.js script needs the following dependencies

npm install express  
npm install body-parser  
npm install csv-parse  
npm install glob  

To start the node.js webserver type
node nodejs-webserver-with-soap-services.js
The Chart can now be opened at http://raspberrypi:9999/index.html or http://[ip-of-your-RaspberryPi]:9999/index.html
Note that you can hide lines in the chart by clicking on the legend. So even displaying values from 20 sensors in one diagram could make sense because you can hide the lines which you do not want to analyze.

Automatically Starting the Scripts on Boot

To run the node.js script in the background, forever will be used. To install it type sudo npm -g install forever.
Then open /etc/rc.local and add the following 3 lines before the 'exit 0' line

cd /home/pi/projects/temp-and-humidity  
/usr/bin/sudo /usr/bin/python temperature-and-humidity-to-csv-logger.py &
/usr/bin/sudo /usr/local/bin/forever start nodejs-webserver-with-soap-services.js

With the next boot, the sensor data is recorded automatically and and the web server is started.