Room Climate Monitor

Reading of temperature and humidity data

For polling of DHT22 and BMP085, I used lady Ada’s Python libraries. Whereas reading data from BMP085 worked ‘out-of-the-box’, polling of DHT22 turned out to be unreliable. Very often, the sensor failed to respond or locked up completely. Fortunately, I found an alternative programed in C on github, which turned out to be very reliable. The problem is, that communication with the sensor requires a precise and fast timing protocol, which cannot be achieved with (slow) Python code.

To use my RasPi as an indoor room climate logger, I programed a simple shell script (see below), which invokes several programs to read sensor data each minute, injecting the values into a MySQL database. The SQL database is accessible through my home intranet. Thus, it is possible to submit queries to the database, to export data into a CSV file or connecting the database to an Excel worksheet.

You can either import a CSV file or directly connect Excel to the MySQL server.

In order to present the sensor data as plots on a webpage, they are processed with GNUPlot (for details, see my tutorial). Plots are generated for the last 24 hours, the last week or the last month as shown on the sensors page. The tutorial below includes some shell scripts and links to the required software packages. I have also prepared a tutorial for preparing whiskers or boxplots using R.

Data acquisition and storage in a MySQL database or CSV file

The software and drivers used for polling the sensors rely on python and C. It is important to run these programs with root privileges, otherwise they won’t return any values from your sensors!

First, we need to download some drivers from github. The program to poll BMP085 is a python script and can be retrieved as follows:

$ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
$ cd Adafruit-Raspberry-Pi-Python-Code
$ cd Adafruit_BMP085

Place the file Adafruit_BMP085.py into the directory containing all scripts/binaries for your project (e.g. /var/www/bin on Debian Wheezy). Now, we have to modify the example code provided in the Adafruit_BMP085 directory to obtain data as a comma separated list of values, which can be easily imported into a CSV file. You can skip this step and format the output using sed.

#!/usr/bin/python
from Adafruit_BMP085 import BMP085
# Initialise the BMP085 and use STANDARD mode (default value)
# bmp = BMP085(0x77, debug=True)
bmp = BMP085(0x77)

# To specify a different operating mode, uncomment one of the following:
# bmp = BMP085(0x77, 0)  # ULTRALOWPOWER Mode
# bmp = BMP085(0x77, 1)  # STANDARD Mode
# bmp = BMP085(0x77, 2)  # HIRES Mode
# bmp = BMP085(0x77, 3)  # ULTRAHIRES Mode

temp = bmp.readTemperature()
pressure = bmp.readPressure()
altitude = bmp.readAltitude()

print "{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f;{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f;{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4} (temp, (pressure / 100.0), altitude)

In addition, two kernel modules must be loaded at boot time. In /etc/modules enter two lines:

i2c-bcm2708 
i2c-dev

For I2C, two packages must be installed using apt-get:

$ sudo apt-get install python-smbus
$ sudo apt-get install i2c-tools

For DHT22, download the following code from github and follow the instructions of the README file to compile the program.

$ git clone https://github.com/technion/lol_dht22.git

Compilation requires the wiringPi library, which is available from here.

$ git clone git://git.drogon.net/wiringPi

Again, we want a comma separated list of values for temperature and humidity, which can be appended to the CSV file. You can skip this step if you’re going to format the program output using a regular expression with sed. Change into the lol_dht22 directory to modify dht22.c with your favorite text editor and search for the line:

printf("Humidity = {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4} Temperature = {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f *C \n", h, t );

and change this line into:

printf("{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f;{c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}.2f", t, h );

The following code should be commented. Enclose these lines in /* */:

printf("Invalid data from wiringPi library\n");
printf("Data not good, skip\n");
printf ("Raspberry Pi wiringPi DHT22 reader\nwww.lolware.net\n");
perror("Dropping privileges failed\n");

After compilation, the program should print temperature and humidity separated by a semicolon to STDOUT. If the program hangs, kill the task and remove the stale lock file in /var/run/lock.