Determining the indoor air quality with your Raspberry Pi

If you are considering to measure the air quality inside your house or apartment and start reading some online resources about that topic, for sure you will find a lot of information about the famous MQ-sensors. Especially the MQ135, which is designed to determine the air quality, would be a perfect sensor for that task. But the big downside of these sensors is that they deliver an analog signal, so that an additional A/D converter or a micro controller, like e.g. the Arduino, is necessary to convert the analog signal to a digital signal that then can be used by the Raspberry Pi. For sure, this is not such a big deal, but I was looking for a more ‘consolidated’ solution.

Finally, I found an air quality sensor, manufactured by Rehau, that can be connected directly to an USB port, already containing the sensor and a micro controller in the case of a small USB stick. This sensor does not just simply measures the amount of carbon dioxide and takes it as an indicator for the air quality, like e.g. the Netatmo weather station does, it is sensing volatile organic compounds that are produced by cooking, breathing, sweating and so on. Together with the amount of carbon monoxide, the sensor calculates a value for the air quality in ppm. Values up to 1000ppm are standing for good air quality, values from 1000ppm to 1500ppm representing mediocre air quality, and if the value exceeds 1500ppm, the air quality is considered bad. You can also see the current condition of the air directly at the stick, since it is shown by using a green, a yellow and a red LED.

Important thing about this stick is, that you have to do a calibration before you are using it for measuring and recording the air quality. For that, you just have to plug the stick in, when it is surrounded by clean and fresh air, that’s basically all. Unfortunately, the stick does not keep the value from the calibration permanently. That means, every time it is powered up (or the Raspberry Pi is restarted), the calibration happens again. But there is a little trick, with which you can avoid a new calibration after a restart. The sensor comes together with a Windows software called ‘Airmonitor’. If you start this software, press and hold ‘Strg’ and then click on the logo three times, the so called ‘Expert Mode’ within the software will be activated. After that, you can go to ‘Support Tools’, ‘Edit Knobs’ and change the the value for ‘ui16StartupBits’ to ‘0’. For further reading about the Rehau Air Quality Sensor, I recommend the article here.

Fortunately,  a program for Linux already exists that can be used on the Raspberry Pi to read the values from the sensor. You can easily download the sources of the program an build an executable, by simply following the steps provided by the author of the program.

sudo apt-get install libusb-dev
sudo apt-get install build-essential
mkdir airsensor
cd airsensor
wget http://usb-sensors-linux.googlecode.com/svn/trunk/airsensor/airsensor.c
gcc -o airsensor airsensor.c -lusb

Like all the other data from my weather station, and also the system information from the Raspberry Pi, I also store the air quality values in a RRDtool database and use it for making a graph that shows the air quality values from the last 24 hours. In that graph, I also include the thresholds for good, mediocre and bad air quality, so that it is very easy to notice, in which condition the air was at a given point in time.

airquality

Additionally, I included a little smiley icon in the status bar of my weather station website, to indicate the current condition of the air in the same way, I did for showing the warning level of my lightning detector.

Happy     Air quality is good

Neutral     Air quality is mediocre

Sad     Air quality is bad

This is what the smiley indicator looks like in the status bar of the website of my weather station, together with the weather forecast, the current season, sunset and sunrise times and the current moon phase.

Benningen

I also upload the values for the air quality to ThingSpeak and use the IoT ThingSpeak Monitor Widget to monitor the air quality on my Smartphone. This little widget can also generate a notification, if the air quality exceeds a specified threshold, so that you are reminded to open the windows and get some fresh air into the room, if you want.

Telefon

This is the Python script that I use for reading the air quality, updating the icon that represents the current condition of the air, and uploading the value to ThingSpeak. If you also have an account at ThingSpeak, you can replace YOURTHINGSPEAKWRITEKEY with your own personal write key. Please note that reading the value from the sensor can take several seconds, so if you e.g. call the Python script from within a Bash script, it should be followed by a sleep of about 20 seconds.

#!/usr/bin/python

import sys
import os
import shutil
import rrdtool
import httplib, urllib
import time

writekey = 'YOURTHINGSPEAKWRITEKEY'

# Read the current airquality
process = os.popen('sudo ./airsensor -o')
str = process.read()
process.close()

if not str:
	sys.exit(1)

str = str.strip()
str = str.replace(',', '')
data = str.split(' ')

ppm = int(float(data[3]))

# Check the output and store it in the database, if it is ok
if ppm > 0:
	# Insert data into database
	update = 'N:' + data[3]
	rrdtool.update("%s/airquality.rrd" % (os.path.dirname(os.path.abspath(__file__))), update)
	if (ppm < 1000):
		shutil.copyfile('/home/pi/airsensor/Happy.png', '/var/www/html/Smiley.png')
	elif (ppm >= 1000 and ppm < 1500):
		shutil.copyfile('/home/pi/airsensor/Neutral.png', '/var/www/html/Smiley.png')
	elif (ppm >= 1500):
		shutil.copyfile('/home/pi/airsensor/Sad.png', '/var/www/html/Smiley.png')
	# Post to ThingSpeak
	try:
		params = urllib.urlencode({'field1': ppm, 'key':writekey })
		headers = {"Content-typZZe": "application/x-www-form-urlencoded","Accept": "text/plain"}
		conn = httplib.HTTPConnection("api.thingspeak.com:80")
		conn.request("POST", "/update", params, headers)
		response = conn.getresponse()
		data = response.read()
		conn.close()
	except:
		sys.exit(-1)
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.