Segelschiff auf dem Mittelmeer (Kopfgrafik)/grafiken/tux-md-347-260.png

Eigenbauwetterstation geht ans Netz

Autor: Michael · veröffentlicht 27.07.2016 21:00 Uhr · zuletzt geändert 31.07.2016 18:30 Uhr · Tags: linux wetter amateurfunk

Aktueller Prototyp, einsatzbereit

Bereits vor einiger Zeit habe ich über mein Projekt einer Eigenbau-Wetterstation berichtet. Einige Zeit lief ein Prototyp auf unserer Terrasse im Testbetrieb und lieferte Daten hier hin. Dabei konnten einige Kinderkrankheiten ausgemerzt werden, zuletzt lief alles recht stabil und ansehnlich. Leider ging beim Umzug das Hauptarbeitspferd, der SHT75-Sensor, kaputt, so dass das Teil einige Zeit vor sich hin schlummerte. Zwischenzeitlich ist die neue Bastelecke eingerichtet und die Sensorik repariert. Das Foto links zeigt den fertigen Prototyp, für den Testlauf noch an ein 230 Volt auf 12 Volt Hutschienennetzteil angeschlossen. Nach Fertigstellung ist diese Wetterstation auf das Dach des Institutes für Hochfrequenztechnik der RWTH Aachen an der Melatener Straße umgezogen. Dort erfolgt in Zusammenarbeit mit der Amateurfunkgruppe eine Einbindung ins Hamnet. Details zur Schaltung und den im konkreten Fall verwendeten Sensoren finden sich in den folgenden Absätzen. Kernstück ist weiterhin ein Raspberry Pi 2 mit aktueller Raspbian-Version.

Alle GPIO sind über eine Kontaktleiste auf eine Lochrasterplatine herausgeführt. Hierüber findet sowohl die Spannungsversorgung des Raspberry als auch die Verbindung mit den Sensoren statt. Die konkret verwendeten Sensoren sowie deren Abfrage und Einbindung sind im Folgenden näher beschrieben.

Lufttemperatur und -feuchtigkeit: SHT75

Unter der Bezeichnung SHT75 wird von der Firma Sensirion ein kombinierter Temperatur-/Feuchtigkeitssensor angeboten. Es gibt mehrere Sensoren in verschiedenen Bauformen und Präzisionen unter ähnlichen Bezeichnungen. Der SHT75 ist ein gut zu benutzendes Bauteil (sozusagen SMD-Sensor auf Breakout-Board) der höchsten Präzisionsklasse und benötigt wenig Zusatzaufwand. An die vier Pins werden lediglich die Versorgungsspannung (zwischen 2,4 und 5,5 Volt, hier 3,3 Volt) sowie ein I²C ähnlicher Bus angelegt. Der Datenbus wird direkt an zwei exklusive GPIO-Pins des Raspberry angeschlossen, der DATA-Pin wird über einen 10 Kiloohm-PullUp-Widerstand mit 3,3 Volt verbunden (externes Bauteil verwendet).

Für die Sensorfamilie kursieren genügend Codebeispiele im Netz herum. Dem Sensor wird über den Bus ein Initialisierungssignal mitgeteilt, dann erfolgt je ein Signal zum Beginn der Messung von Temperatur bzw. Luftfeuchtigkeit. Der Messwert kann dann jeweils vom Bus ausgelesen werden. Das Datenblatt verrät noch ein bischen Mathematik zur Weiterverarbeitung der zurückgelieferten Werte bzw. zur Bestimmung der Taupunkttemperatur. Diese drei Werte werden über ein in C geschriebenes Programm minütlich als Mittelwert dreier Messungen im 1-Sekundenabstand erhoben und in einer temporären Datei abgelegt.

Luftdruck: BMP180

Von Bosch Sensortec gibt es mit dem BMP180 einen I²C-Bus tauglichen Luftdrucksensor mit guter Präzision. Über Adafruit sind auch komplette Breakout-Boards mit integriertem Beiwerk (Pull-Up, I²C-Level-Shifter, ..) günstig erhältlich. Die Spannungsversorgung erfolgt über die 3,3 Volt Schiene, I²C ist beim Raspberry standardmäßig hardwareseitig vorhanden und muss nur durch Nachladen entsprechender Kernel-Module aktiviert werden. Zur Temperaturkompensation der Messung misst der BMP180 selbige gleich mit, so dass mit ein bischen Mathematik (vgl. Datenblatt) ein ziemlich genauer Messwert für den absoluten Luftdruck erhoben werden kann. Eine Umrechnung auf den relativen Luftdruck erfolgt mit der Barometrischen Höhenformel. Als quasi Nebenprodukt kann die Sensortemperatur auch einzeln ausgegeben werden; ich habe den Sensor mit in die Abzweigdose mit dem Raspberry Pi gepackt und den Kontakt zur Außenwelt durch mehrere 0,2 mm² große Löcher in der Dose hergestellt. Damit ist sichergestellt, dass der Luftdruck innen auch dem Luftdruck außen entspricht und gleichzeitig ist auch noch ein Gratissensor für die Innentemperatur mit dabei :-)

Die Messwerte werden durch ein Pythonskript als Mittelwert dreier Messungen im 1-Sekundenabstand ebenfalls minütlich in jeweils einer temporären Datei abgelegt.

Windgeschwindigkeit

Sicherlich einer der am komplexesten zu erhobenen Messwerte da Sensorik nicht inflationär verfügbar ist. Noch schwieriger, wenn man gewisse Ansprüche an Genauigkeit hat und nicht nur ein "Schätzeisen" bauen will. Ebenfalls bei Adafruit stieß ich auf ein interessantes Produkt; hier wird über ein Anemometer mit variabler Ausgangsspannung Windgeschwindigkeit im Bereich von 0 bis 32,4 Meter pro Sekunde (entspricht immerhin knapp 117 km/h) gemessen bei brauchbarer Auflösung und Genauigkeit. Das genauere Messprinzip (ich vermute, mittels Hall-Effekt) konnte ich zerstörungsfrei leider noch nicht 100% validieren und auch das chinesische Datenblatt half dabei nicht zielführend weiter. Die analoge Ausgangsspannung im Bereich zwischen 417 mVolt (bei Windstille) und ca. 2000 mVolt bei maximaler Windgeschwindigkeit wird über einen 16-Bit Analog-Digital-Wandler (ADS1115) quantifiziert und kann dann einfach ebenfalls über den I²C-Bus ausgelesen werden. Der von Adafruit angebotene Subtyp des Anemometers benötigt zwischen 7 und 24 Volt Betriebsspannung, so dass er direkt an den 12 Volt eingespeister Spannung hängt. Die Ruhespannung bei Windstille wurde mit dem Oszilloskop über einen 10:1 Vorteiler recht genau zu 414 Millivolt bestimmt und wird vom ADS1115 als 417 Millivolt übermittelt. Die Umrechnung jeder beliebigen weiteren gemessenen Spannung in eine diskrete Windgeschwindigkeit ist dann quasi Dreisatz und wird ebenfalls von einem Pythonskript erledigt. Aufgrund der hohen Dynamik dieser Messgröße (und um keine einzelne Windböe zu verpassen) erfolgt hier eine Abtastung und Mittelwertbildung von drei Messwerten im Abstand von 100 Millisekunden zu jeder glatt durch drei teilbaren Sekunde (also zwanzig Mal pro Minute) mit direkter Einspeisung der Windgeschwindigkeit in eine PostgreSQL-Datenbank. Um hierbei nicht mit Kommastellen (Datentyp real, verbraucht 4 Bytes) arbeiten zu müssen, wird der Wert auf eine Nachkommastelle gerundet (mehr Präzision kann man schon Messapparatur-bedingt nicht erwarten) und dann mit Zehn multipliziert ohne Nachkommastelle (Datentyp smallint, verbraucht 2 Bytes) in der Datenbank abgelegt. Über diesen Umweg spart man 50% Speicherplatz, was bei zwanzig Messwerten pro Minute immerhin schon 57,6 KiB pro Tag und im Jahr dann bei etwa 10,5 Millionen Messwerten über 20 Megabyte Ersparnis bedeutet. Nach dem Auslesen aus der Datenbank kann der Messwert durch Division durch 10 recht schnell wieder genau wiedergegeben werden.

Ozonkonzentration: MQ-131

Mit dem MQ-131 gibt es einen Sensor zur Ermittlung der Ozonkonzentration in der Umgebungsluft; er ist Teil einer ganzen Familie von Messsensoren für die unterschiedlichsten Gase und Stoffe. Technisch handelt es sich um einen elektrochemischen Sensor; es gibt eine Art Heizelement und der Widerstand zwischen zwei Elektroden ändert sich in Abhängigkeit der Gaskonzentration. In Kombination mit einem (bekannten) Festwiderstand ergibt sich also ein Spannungsteiler und in Abhängigkeit der Ausgangsspannung (über einen ADS1115 quantifiziert, siehe unten) kann dann auf den Ozonwert zurückgeschlossen werden. Leider haben wir noch keine gute Kalibriermöglichkeit aufgetan, so dass bzgl. dieses Sensors noch Experimentierbedarf besteht. Allerdings ist der Sensor bereits fertig verkabelt und kann dann später nach weiterer Erforschung noch in Betrieb genommen werden.

Niederschlagsmenge: Kipplöffel-Messgerät

Die Erhebung der Niederschlagsmenge gehört quasi auch für die allergünstigsten Consumer-Wetterstationen mit zum guten Ton, auch wenn die Aussagekraft bzw. Verwertbarkeit wohl eher überschaubar ist, insbesondere wenn man pünktlich zum Ende der Sturzregenschauer durchnässt die eigenen vier Wände wieder erreicht hat. Es gibt hier aber nichtsdestotrotz eine Vielzahl interessanter Sensorik mit abgefahrenen Messverfahren bis hin zum Gegenwert ebenso interessanter Sportwagen. Trotz bescheidener Genauigkeit habe ich mich aber für ein althergebrachtes Messinstrument entschieden, dass sich an verschiedenen Stellen immer wieder als Ersatzteil von Consumer-Wetterstationen auftreiben lässt. Es handelt sich um einen Auffangtrichter mit darunterliegendem Kipplöffel, der beim Umkippen einen Impuls über einen Magnetschalter gibt. In einem hochaufwendigen Messaufbau unter Zuhilfenahme eines Medizinproduktes in Form eines steril verpackten Polypropylen/Polyethylen-Zylinders mit Dosiereinrichtung ("Einmalspritze") konnte in einer kleinen Messreihe herausgefunden werden, dass der Kipplöffel brav nach Befüllen mit ungefähr 2 Milliliter Flüssigkeit (am Standort Herzogenrath aufgefangener Regen) umkippt und ein kurzes Signal gibt. Umgerechnet auf den Flächeninhalt des Trichters des Messgerätes ergibt sich somit eine Auflösung von rund 270 Millilitern Niederschlag pro Quadratmeter (man kann Regen also mit einer Auflösung von rund einem Viertel Liter pro Quadratmeter messen). Diese ließe sich prinzipiell durch Vergrößerung der Auffangfläche noch weiter verfeinern.

Der in den Sensor integrierte Reedkontakt ist über einen PullUp-Widerstand mit einem interruptfähigen GPIO des Raspberry verbunden. Hier gibt es einen in Python geschriebenen Wachhund, der die Anzahl der Impulse (Interrupts) kontinuierlich zählt und alle 60 Sekunden als Summe in einer temporären Datei ablegt. Die Niederschlagsberechnung selbst als Produkt aus Impulsen und 0,270 Litern pro Quadratmeter findet dann bei Abruf aus der Datenbank statt.

Gamma-Ortsdosisleistung: SBM-20 Zählröhre

Für die Messung des radioaktiven Zerfalls in der Atmosphäre habe ich eine auf der SBM-20-Röhre basierende Zähleinheit verwendet. Diese gibt es beispielsweise als fertiges Modul bei 4N Galaxy zu kaufen. Der integrierte Minilautsprecher wurde abgeklemmt, der Ausgang der Schaltung ebenfalls mit einem interruptfähigen GPIO des Raspberry verbunden. Pro detektiertem Zerfall gibt es also einen Impuls, auch diese werden über ein Pythonskript kontinuierlich über eine Minute gezählt und in temporären Dateien abgelegt. Die genaue Umrechnung in die Ortsdosisleistung geht dann aus den Unterlagen bzw. dem Datenblatt der Röhre hervor und wird jeweils über die Minutenmesswerte aus den letzten 30 Minuten gemacht um ein repräsentatives Bild zu erhalten.

Belichtungsstärke: TSL 2561

Für die Messung der einfallenden Lichtstärke bin ich auf den TSL 2561 gestoßen. Dieser Sensor ist praktischerweise ebenfalls I²C tauglich, hat zwei getrennte Dioden zur Lichterfassung an Bord und kann uns darüber unter Vernachlässigung des infraroten Lichtanteils sagen, wie hell es nun für unser menschliches Auge denn tatsächlich gerade ist. Durch die spektrengetrennte Erfassung sind darüberhinaus weitere Auswertungen denkbar. Der Sensor ist in einem separaten Gehäuse untergebracht, welches nicht mit in der Wetterhütte sitzt sondern sich schön exponiert und schattenfrei außerhalb befindet. Die Auswertung im Minutenintervall findet ebenfalls über ein Pythonskript statt, die Messwerte werden auch nach Zwischenspeicherung endgültig in der PostgreSQL-Datenbank weggespeichert.

16-Bit Analog-Digital-Wandler ADS1115

Neben den in den Absätzen oben erwähnten Anemometer und Ozon-Sensor werden weitere Spannungen über den ADS1115 gemessen. Über einen 2/3-1/3 Spannungsteiler aus möglichst toleranzarmen (hier 1%) Widerständen wird hier die genaue Versorgungsspannung (im Regelfall 12 Volt über Power over Ethernet) gemessen und dokumentiert. Am vierten Port hängt die Ausgangsspannung eines MAX471-Sensors in der Hauptzuleitung. Dieser Chip misst über einen integrierten Shunt den durchfließenden Strom im Bereich bis maximal 3000 Milliampere und gibt eine dazu proportionale Ausgangsspannung aus. Damit messe und dokumentiere ich den Gesamtstromverbrauch der Wetterstation. Diese Information ist nicht nur akademischer Natur (doch, schon :-)) sondern hilft auch bei Optimierungsüberlegungen und konkreten Maßnahmen weiter, da zukünftig auch Wetterstationen mit komplett autarker Versorgung über Akku/Photovoltaik entstehen sollen und dabei jedes eingesparte Milliwatt Energie zählt.

Weitere Innensensorik: HTU21D, pisense

Um neben der Temperatur auch die Luftfeuchtigkeit innerhalb des Gehäuses dokumentieren zu können, ist noch ein HTU21D verbaut worden. Dabei handelt es sich um einen I²C-Temperatur- und Luftfeuchtesensor mit relativ überschaubarer Genauigkeit (2% in Bezug auf relativer Luftfeuchtigkeit), dafür aber güntigem Preis und einfacher Verfügbarkeit auf Breakout-Board. Ebenfalls alle 60 Sekunden wird ein Messwert über ein Python-Skript abgefragt und in einer temporären Datei protokolliert.

Zur Überwachung des Gesundheitszustandes des Raspbian Pi (Spannungen, Temperaturen) kommt weiterhin pisense zum Einsatz. Dabei handelt es sich um Codeschnipsel, mit denen die Sensoren auf dem Pi selbst abgefragt werden können. Die Ausgabe erfolgt direkt zur Weiterverwendung mit Munin (s.u.).

Datenspeicherung und Visualisierung

Die meisten Messwerte werden zunächst mit Zeitstempel des Erhebungszeitpunktes in temporären Dateien auf einer Ramdisk zwischengespeichert. Einmal pro Minute läuft ein Upload-Skript, das prüft, ob eine Verbindung zu einer sich auf einem externen Server befindlichen PostgreSQL-Datenbank möglich ist. Im Erfolgsfall werden die Daten hierhin dauerhaft abgespeichert und die temporären Dateien gelöscht. Dies hat den Vorteil, das auch bei nicht zur Verfügung stehender Netzwerkverbindung keine Daten verloren gehen.

Periodisch alle fünf Minuten werden zudem die Messwerte durch eine auf meinem Heimserver laufende Munin-Instanz abgefragt und in RoundRobinDatenbanken abgelegt. Hieraus erfolgt dann mittels rrdgraph die Erstellung aller hier auf den Internetseiten gezeigter Grafiken. Diese werden dann ebenfalls alle fünf Minuten nach Erstellung auf den Webserver geladen. Einzig die Daten der Windgeschwindigkeitsmessung werden aufgrund des kurzen Messintervalles von aktuell drei Sekunden direkt vom Raspberry in die PostgreSQL-Datenbank geliefert.

Auf dem Webserver wird ferner jede Minute (immer zur Sekunde 15) die hier abrufbare statische Seite mit den aktuellen Messwerten und den eingebundenen Graphen erstellt und bereitgestellt. Das hat den Vorteil, dass massiv Ressourcen und Datenbankzugriffe eingespart werden da nicht jeder Seitenabruf Datenbankabfragen generiert sondern lediglich eine statische Seite durch nginx ausgeliefert werden muss. Außerdem braucht man so keine Skriptsprache als Verknüpfung zu nginx - spart potenzielle Sicherheitslücken ein :-). Die gemessene Windgeschwindigkeit wird quasi in Echtzeit an den Webseitenbesucher ausgeliefert; aufgrund der Tatsache, dass aber nur ein paar Bytes an Nutzdaten übertragen werden, hält sich die dadurch erzeugte Systemlast stark in Grenzen.

Fragen? Anregungen? Kommentare? Lass es mich wissen!