de|en

Barometer mit dem Raspberry Pi und dem I2C Luftdrucksensor BMP085

Martin Kompf

Raspberry Pi als Barometer

Ein wichtiger Bestandteil einer Wetterstation ist die Messung des Luftdrucks mittels eines Barometers. Der integrierte digitale Luftdrucksensor BMP085 lässt sich aufgrund des vorhandenen I²C Bus mit minimalem Aufwand an den Raspberry Pi anschließen.

Luftdruck und Barometer

Durchzug eines Tiefduckgebietes
Durchzug eines Tiefdruckgebietes. An der fallenden Luftdruckflanke (oben) steigt die gemessene Regenmenge deutlich (unten).

Unser Wetter wird deutlich vom Luftdruck und den damit verbundenen Strömungen beeinflusst. Hoher Luftdruck steht meist für sonniges und trockenes Wetter, während ein Tiefdruckgebiet Regen und Sturm mit sich bringt. Starke Veränderungen des Luftdrucks innerhalb kurzer Zeit signalisieren einen bevorstehenden Wetterumschwung. Die Messung und Aufzeichnung des Luftdrucks ist daher eine sinnvolle und lohnenswerte Tätigkeit für den Hobbymeteorologen.

Ein Barometer misst den durch das Gewicht der Atmosphäre an einem bestimmten Ort aufgebauten Luftdruck. Außer vom Wetter ist er dadurch auch von der Höhe des Ortes abhängig. Um für meteorologische Zwecke vergleichbare Luftdruckwerte zu bekommen, rechnet man den gemessenen Luftdruck immer auf Meereshöhe (Normal-Null) um.

Die international verwendete Maßeinheit für den Luftdruck ist das Pascal (Pa). Um zu gut handhabbaren Zahlenwerten zu kommen, gibt man den Luftdruck meistens in Hektopascal (hPa) an. Der Zahlenwert ist dann auch identisch mit der früher oft verwendeten Einheit Millibar.

Der normale mittlere Luftdruck auf Meereshöhe beträgt 1013 hPa. Die mit meiner Wetterstation gemessenen Extremwerte im letzten Jahr lagen bei 1036 hPa (Hochdruck) und 988 hPa (Tiefdruck).

Luftdrucksensor BMP085

Vor einigen Jahren war der Aufbau eines elektronischen Barometers für den Anschluss an einen Computer noch relativ aufwendig. Eine praktikable Lösung bestand aus der Kombination eines analogen Luftdrucksensors (z.B. MPX4115A) mit einem Operationsverstärker und einem Digital-Analogwandler. Mittlerweile sind Schaltkreise wie der BMP085 von Bosch oder sein Nachfolger BMP180 erhältlich, die alle diese Komponenten in ein Gehäuse integrieren. Die Übertragung der Messwerte erfolgt über einen I²C-Bus. Da der Raspberry Pi ebenfalls einen I²C-Bus an seinem GPIO Konnektor bereitstellt, ist der Anschluss eines BMP085 oder BMP180 schaltungstechnisch mit minimalem Aufwand möglich.

Eine Hürde gibt es jedoch noch zu bewältigen: Die Schaltkreise gibt es nur im LCC oder LGA Gehäuse, die mit Hobbywerkzeugen kaum zu verarbeiten sind. Glücklicherweise haben sowohl Adafruit als auch Sparkfun Breakout-Boards im Angebot, welche die Anschlüsse des IC auf eine Steckerleiste im 2,5 mm Raster aufbrechen. Die nachfolgenden Ausführungen beziehen sich auf den BMP085, jedoch sollte der Nachbau mit dem BMP180 ohne große Änderungen möglich sein.

Testaufbau mit Breadboard

Testaufbau BMP085
Mit Breadboard, Pi T-Cobbler umd BMP085 Breakout realisierter Prototyp.

Ein sinnvoller erster Schritt zum Kennenlernen neuer Hard- und Software besteht im Aufbau eines Prototyps. Hierzu eignet sich hervorragend ein universelles Breadboard, das man mittels des Pi T-Cobblers von Adafruit mit dem Raspberry Pi verbindet. Auch das BMP085 Breakout passt mit auf das Breadboard. Dann verbindet man jeweils die Anschlüsse Masse (GND, -), Betriebsspannung (3V3, +) sowie Takt (SCL, CL) und Daten (SDA, DA) von Cobbler und BMP085 (Bild links). Wichtig ist, dass die Betriebsspannung 3,3 Volt beträgt und nicht etwa 5 Volt! Nun ist noch der Stecker des Pi T-Cobblers in die GPIO Steckerleiste des Raspberry Pi zu stecken. Hierbei ist die richtige Polarität zu beachten: Die weiß markierte Ader des Flachbandkabels gehört an Pin 1, welches auf der Seite des SD-Karteneinschubs liegt (Bild unten).

Testaufbau Barometer

Softwarevorbereitung

Die Kommunikation zwischen Raspberry Pi und Luftdrucksensor erfolgt über den I²C-Bus. Die dazu notwendigen Kernelmodule sind Bestandteil von Raspbian "wheezy", man muss sie allerdings noch aktivieren. Dazu fügt man ihre Namen in die Datei /etc/modules ein:

i2c-bcm2708
i2c-dev

In /etc/modprobe.d/raspi-blacklist.conf sind die blacklist Einträge zu entfernen oder auszukommentieren:

#blacklist spi-bcm2708
#blacklist i2c-bcm2708

Neuere Versionen des Raspbian Betriebssystems ab Kernel 3.18 (Februar 2015) erfordern zusätzlich die Aktivierung des Devicetree Overlay für I²C. Am einfachsten erfolgt dies per

sudo raspi-config

Im Menü wählt man dann Advanced Options - I2C aus und bestätigt den Auswahldialog mit Yes.

Da das Messprogramm später unter Python laufen soll, installiert man jetzt auch gleich die erforderlichen Python-Module und Tools für die Arbeit mit dem I²C-Bus:

sudo apt-get install python-smbus i2c-tools

Damit die Luftdruckmessung später nicht ständig mit Superuser-Rechten laufen muss, sollte der entsprechende Benutzer (zum Beispiel der Standardbenutzer pi) Mitglied der Gruppe i2c sein:

sudo adduser pi i2c

Jetzt bootet man den Raspberry Pi mit angeschlossenem Luftdrucksensor neu. Dabei lädt der Kernel die I²C-Module. Nach dem Einloggen als Benutzer pi lässt sich mittels i2cdetect überprüfen, ob die Hard- und Software soweit funktionieren. Die Ausgabe zeigt, dass eine Kommunikation mit der I²C-Adresse 77 möglich ist. Diese Adresse ist dem BMP085 und BMP180 fest zugewiesen:

i2cdetect -y 1

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- 77

Das Messprogramm

Der BMP085 liefert unkompensierte rohe Werte für Temperatur und Luftdruck. Der Hersteller hat die für die Berechnung der kompensierten richtigen Werte notwendigen Kalibrierungsinformationen bereits in einen 176 bit E²PROM gespeichert - nur die Berechnung muss man noch selbst durchführen. Dies ist allerdings nicht ganz einfach, das Datenblatt liefert detaillierte Informationen dazu.

Wer sich diese Arbeit sparen möchte, kann eine von Adafruit bereitgestellte Open Source Software benutzen. Sie ist in Python programmiert, das als Bestandteil des Betriebssystems Raspbian standardmäßig auf dem Raspberry Pi installiert ist. Da es sich um eine Scriptsprache handelt, kann man relativ komfortabel mit der Software experimentieren und sie für eigene Zwecke anpassen.

Adafruit hat die Software in einem Git-Repository auf Github publiziert. Dieses dupliziert man per

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

in sein lokales Verzeichnis. Nun sollte das mitgelieferte Beispielprogramm schon erste Ergebnisse liefern:

cd Adafruit-Raspberry-Pi-Python-Code/Adafruit_BMP085
./Adafruit_BMP085_example.py 

Temperature: 21.90 C
Pressure:    1018.14 hPa
Altitude:    -40.80

Das Programm gibt die Temperatur und den am Aufstellungsort gemessenen absoluten Luftdruck aus. Die Höhenangabe stimmt nur dann, wenn man vorher im Script den aktuellen Luftdruck auf Normal-Null eingetragen hat. Das ist aber nicht der angestrebte Anwendungsfall für eine Wetterstation. Hier ist die Ausgangssituation umgekehrt: Die Höhe der Wetterstation über dem Meeresspiegel ist bekannt und man will daraus und dem gemessenen absoluten Luftdruck den auf Meereshöhe bezogenen Luftdruck bestimmen. Denn nur dieser ist mit anderen Wetterstationen vergleichbar und damit für meteorologische Zwecke geeignet.

Mittels einer kleinen Änderung lässt sich das Script Adafruit_BMP085_example.py für unseren Anwendungsfall umbauen:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from Adafruit_BMP085 import BMP085

bmp = BMP085(0x77)
temp = bmp.readTemperature()

# Read the current barometric pressure level
pressure = bmp.readPressure()

# Set the altitude of your current location in meter
altitude = 95
psea = pressure / pow(1.0 - altitude/44330.0, 5.255)

print "Temperature:           %8.2f °C" % temp
print "Pressure:              %8.2f hPa" % (pressure / 100.0)
print "Pressure at sea level: %8.2f hPa" % (psea / 100.0)

Die Berechnung des Luftdruck auf Meereshöhe erfolgt mittels einer vereinfachten barometrischen Höhenformel. Die Variable altitude enthält die dafür erforderliche Höhe der Wetterstation über Normal-Null. Sie müssen diese an Ihren Aufstellungsort anpassen, den ungefähren Wert dafür kann man auf der Webseite GeoPosition bestimmen. Durch Vergleich der Messergebnisse mit einer meteorologischen Station lässt sich die Höhe auch exakt ermitteln - dazu später mehr.

Aufzeichnung mit RRDtool

Das geänderte Script gibt nun die gemessenen und berechneten Werte auf der Konsole aus:

./Adafruit_BMP085_example.py 

Temperature:           22.30 °C
Pressure:              1018.06 hPa
Pressure at sea level: 1029.24 hPa

Für die Visualisierung und Auswertung des Luftdruckverlaufs ist der händische Aufruf des Scripts ungeeignet. Dazu ist eine langfristige Aufzeichnung der Messwerte in einer Datenbank und eine komfortable Möglichkeit zur Erstellung von Grafiken notwendig. Damit die zu speichernden Datenmengen nicht ausufern, bietet sich eine Round-Robin-Datenbank an. Bei entsprechender Konfiguration hält sie zeitlich hoch aufgelöste Messwerte nur eine bestimmte Anzahl von Tagen vor. Danach erfolgt eine automatische Verdichtung der Daten, sodass nur noch der Tagesmittelwert in der Datenbank steht. Nach einer längeren Zeit kann man dann auch diese Werte überschreiben. Damit hält sich der Speicherbedarf der Datenbank in vorbestimmbaren Grenzen.

Eine Implementierung dieses Prinzips ist RRDtool, das sich unter Zuhilfenahme des Packagemanagers auf dem Raspberry Pi ganz einfach installieren lässt:

sudo apt-get install rrdtool python-rrdtool

Am Beginn der Arbeit mit RRDtool steht die Definition der Datenbank. Das folgende Beispiel legt eine einfache Datenbank an, die Temperatur temp und Luftdruck auf Meeresniveau psea speichert. Sie soll pro Viertelstunde (900 Sekunden) jeweils ein Messwert-Tupel aufnehmen. Nach zehn Tagen (= 960 Werte) erfolgt eine Reduzierung auf jeweils einen Durchschnitts-, Minimal-, und Maximalwert pro Tag. Die Aufbewahrungszeit der Tageswerte beträgt zehn Jahre (= 3600 Werte):

rrdtool create pressure.rrd --step 900 \
DS:temp:GAUGE:1200:-40:80 \
DS:psea:GAUGE:1200:950:1050 \
RRA:AVERAGE:0.5:1:960 \
RRA:MIN:0.5:96:3600 \
RRA:MAX:0.5:96:3600 \
RRA:AVERAGE:0.5:96:3600

Nun ergänzt man noch das Script am Ende um das Schreiben der Messwerte in die Datenbank, die im gleichen Verzeichnis wie das Script liegen muss:

# ... wie oben

import os, rrdtool

# insert data into round-robin-database
data = "N:%.2f:%.2f" % (temp, psea/100.0)
rrdtool.update(
  "%s/pressure.rrd" % (os.path.dirname(os.path.abspath(__file__))),
  data)

Ob das Script nun tatsächlich Daten in die Datenbank schreibt, lässt sich mittels rrdtool lastupdate pressure.rrd überprüfen. Dieses Kommando gibt den Zeitstempel und die Werte des letzten Datenbankupdates aus. Damit man sich in Zukunft nicht immer am Raspberry Pi einloggen und die Kommandozeile bemühen muss, ist es sinnvoll, den Scriptaufruf an den Zeitplandienst cron zu delegieren.

Daten gesammelt?

Nach einiger Zeit kontinuierlicher Datenerfassung lohnt es sich, einen Blick auf die Grafikfähigkeiten von RRDtool zu werfen. Das folgende Kommando erzeugt die Grafikdatei pressure.png mit dem Luftdruckverlauf der letzten Woche:

rrdtool graph pressure.png \
  -s 'now - 1 week' -e 'now' \
  -A -Y -X 0 \
  DEF:psea=pressure.rrd:psea:AVERAGE \
  LINE2:psea#0000FF:

Mehr zum Thema Grafik mit RRDtool bis hin zum Aufbau einer Webapplikation zur Präsentation der Daten finden Sie in den Artikeln Wetterdatenerfassung mit dem USB-WDE1 und Temperaturmessung mit dem Raspberry Pi.

Natürlich kann man sich auch die Daten auch als Zahlenwerte ausgeben lassen:

rrdtool fetch pressure.rrd AVERAGE -s 'now - 1 week'

1389978000: 3.8599258026e+01 1.0035865546e+03
1389978900: 3.8799765815e+01 1.0036133266e+03
1389979800: 3.8766727854e+01 1.0036799544e+03
...

Die zweite und dritte Spalte enthalten die gemessenen Temperatur- und Luftdruckwerte. In der ersten Spalte steht das Datum als Unix-Zeitstempel, das sind die Anzahl der seit dem 1.1.1970 0:00 Uhr UTC vergangenen Sekunden. Um es in ein lesbares Datum zu konvertieren, ist zum Beispiel der folgende Einzeiler geeignet:

rrdtool fetch pressure.rrd AVERAGE -s 'now - 1 week' | awk -F: '{print "@"$1}' | date +"%d.%m.%Y %H:%M.%S" -f -

Kalibrierung

Kalibrierung des Barometers
Kalibrierung des Barometers durch Vergleich der eigenen Messwerte (y-Achse) mit der nahegelegenen Wetterstation Frankfurt/Main (x-Achse).

Die derart gewonnenen Messwerte eignen sich für eine Überprüfung und Kalibrierung des selbstgebauten Barometers. Dazu importiert man sie in eine Tabellenkalkulation, wie LibreOffice Calc oder ähnlichem. Dann sucht man sich im Internet die Luftdruckmesswerte einer in der Nähe gelegenen professionellen Wetterstation heraus und kopiert diese ebenfalls in die Tabellenverarbeitung. Ein guter Anlaufpunkt ist zum Beispiel Wetter24.de, für meine in Rüsselsheim stehende Wetterstation verwende ich zum Vergleich die Daten aus Frankfurt/Main.

Bei richtiger Zuordnung der beiden Datenreihen anhand der Zeitstempel erzeugt die Tabellenkalkulation aus ihnen ein X-Y-Diagramm (Bild rechts). Die Y-Achse repräsentiert die gemessenen Werte, die X-Achse die Vergleichswerte. Idealerweise liegen dann alle Punkte auf einer Linie y=x (im Diagramm rot eingezeichnet). Kleine Abweichungen im Rahmen der Messgenauigkeit sind erlaubt. Liegen die Punkte dagegen alle ober- oder unterhalb der Ideallinie, dann ist wahrscheinlich die Höhe der Station falsch im Script eingetragen. Nach einer entsprechenden Korrektur des Wertes altitude wiederholt man die Kalibrierung nach einer Woche. Stimmt dann alles, hat man auf diese Art und Weise nebenbei eine exakte Höhenbestimmung für seine Wetterstation vorgenommen.

Solider Aufbau für Dauerbetrieb

Lochrasterplatte mit BMP085
Der BMP085 auf einer Lochrasterplatte mit Steckverbinder für den GPIO-Port des Raspberry Pi

Der fliegende Aufbau mit Breadboard und Pi-Cobbler erscheint für einen Dauerbetrieb nicht besonders gut geeignet. Besser ist es, die BMP085 Breakout-Platine auf eine Universal-Lochrasterplatte zu löten. Auf diese kommen dann noch zwei 13-polige Buchsenleisten, welche die Verbindung zum GPIO-Port des Raspberry Pi herstellen. Die Lochrasterplatte wird dann huckepack face-down direkt auf den GPIO-Port gesteckt (siehe Bilder links und am Artikelanfang).

Auf der Lochrasterplatte ist noch genügend Platz, um den Pull-Up Widerstand und eine abgewinkelten Buchsenleiste für einen 1-wire Temperatursensor DS1820 aufzulöten. Das alles bringt man ohne weiteres mit im TEK-BERRY Gehäuse des Raspberry Pi unter. An den USB-Anschluss kommt dann noch der USB-Wetterdaten-Empfänger USB-WDE1 - und fertig ist die Hobby-Wetterstation!