Wetterstation (Generischer Datenlogger)

Vogelhäuschen als Datenlogger

Nach so vielen tollen potenziellen Anwendungszenarien ist es an der Zeit, die Aufgabe der Überwachung und Messwertspeicherung im Sinne der Nachhaltigkeit optimal zu lösen. Datenlogging ist typisch für sehr viele Aufgaben im Internet der Dinge und des Denkens, so dass sich der Aufwand eines generischen Ardublock-Programmes lohnt. Unser zu entwickelndes Programm soll folgende Randbedingungen erfüllen:

  1. Konsequente Nutzung des deep-sleep-Befehls, nur dann sind mobile Anwendungen und Solarbetrieb möglich.
  2. Messdaten zyklisch erfassen (Sensoren abfragen) und Grenzen überwachen. Aus Gründen der Ressourceneffizienz kann diese Teilaufgabe auch mit abgeschaltetem WLAN durchgeführt werden. Zur Erinnerung: mit aktiven WLAN-Interface benötigt der Octopus einen Strom von ca. 90 mA. Ohne WLAN sind es nur 20 mA. Auch wenn es nur wenige ms Rechenzeit bedarf, so summiert sich der Unterschied im Energiebedarf über das Jahr. Die Aktivierung des WLAN-Interfaces ist über den deep-sleep Befehl möglich.
  3. Senden in die Cloud (zur Datenspeicherung oder Alarmierung) mit aktivem WLAN nur dann, wenn unbedingt nötig. Hierzu sind energieeffiziente Strategien denkbar: Z. B. sende nur wenn sich der Messwert gegenüber der letzten Übertragung um x % verändert hat, oder wenn ein Alarm-Grenzwert erreicht wird. Zusätzlich aber vielleicht auch zu festen Zeitpunkten (z.B. alle 10 Abtastzyklen auf jeden Fall senden), um zu sehen, ob der Sensorknoten noch aktiv ist.
  4. Falls gewünscht, soll der Knoten auch Kommandos aus der Cloud entgegennehmen, z.B. eine veränderte Abtastperiode (Zykluszeit) um z.B. in Zeiten starker Regenfälle, die Pegelüberwachung häufiger zu initiieren, oder um bei zuneige gehender Akkukapazität einen Notbetrieb zu ermöglichen.

Anwendung: Wetterstation detektiert Vulkanausbruch in Tonga

Eine Wetterstation im Vogelhäuschen übernimmt für uns das Monitoring der Umweltbedingungen. Manchmal beobachtet man dabei unverhofft auch einmalige Naturphänomene:  Als im Januar 2022 ein Vulkanausbruch den Inselstaat Tonga erschüttert, registriert unsere Messtation kurz darauf eine durch die Druckwelle ausgelöste Luftdruckschwankung. Vernetzte IoT-Wetterstationen auf der ganzen Welt visualisieren die um den Erdball laufende Welle, wie das externe Video hier eindrucksvoll zeigt.

 

Programmierung als Zustandsmaschine:

Der verwendete Mikrocontroller verliert beim Einsatz der deep-sleep Funktion den Zustand der Variablen im Speicher, d.h. alle in Variablen gespeicherte Informationen sind verloren und der Controller startet wie nach einem Reset. Um trotzdem sinnvolle Programme zu schreiben, erfordert es einige Tricks, z.B. die nichtfüchtige Speicherung von Informationen im Uhren-Speicher (RTC-RAM, Realtime-Clock) des ESP. Im folgenden Code verwenden wir das Programmierparadigma einer Zustandsmaschine, d.h. wir definieren einen Zustand in Form der Variablen "MessAufgabe", die wir im RTC-RAM speichern. Nach dem Aufwachen erkennt unser System dann am Inhalt dieser Variable seine nächste Aufgabe.

Auch zum Management der im RTC-RAM gespeicherten Informationen bietet die IoT-Werkstatt im Ardublock Baukasten "ESP: System" entsprechende Funktionen. Das RTC-RAM umfasst 512 Bytes, die wir in 128 Speicherplätze (Slots) für float-Variablen aufteilen und die wir bei jedem Aufruf der deep-sleep-Funktion retten, bzw. beim Aufwachen nach Reset wiederherstellen.

Selber machen: Generischer Datenlogger

Ablauf generischer Datenlogger
Hauptschleife des Datenloggers. Ziel ist nicht ein didaktisch einfacher Aufbau, sondern ein möglichst energieeffizienter Betrieb.

Das nebenstehende Bild zeigt die Struktur unseres generischen Datenloggers. Als erste Aktivität wird die Konfiguration durchgeführt. Hier erfolgen die parametrisierbaren Einstellungen, wie z.B. der aktuelle Zyklus, die Zykluszeit und die durchzuführende Aufgabe. Schlüsselgrößen sind dabei die Variablen "Zyklus" und "MessAufgabe", die im nichtflüchtigen RTC-RAM auch den notwendigen deep-sleep überdauern. Zyklus zählt die fortlaufenden Messzyklen und sorgt so ggf. für ein erzwungendes Update in der Cloud nach jeweils "FesterSendeZyklus" Zyklen. Der Inhalt der Variablen "MessAufgabe" definiert, was im aktuellen Zyklus zu tun ist:

  • MessAufgabe == 0 bedeutet:  Nur Überwachung der Grenzen, ohne WLAN.
  • MessAufgabe == 1 bedeutet:  Sende die Messdaten sofort, Aufgrund einer Alarmgrenze oder einer starken Änderung.
  • MessAufgabe == 2 bedeutet: Sende die Messdaten sofort, Aufgrund eines erzwungenen Updates nach n Zyklen.

Konkret bedeutet dies in der Schleife, dass wir:

Bei (MessAufgabe > 0) die aktuellen Messwerte erfassen (Unterprogramm "Sensoren_AktuelleMesswerte") und nach erfolgreicher Verbindung mit dem Internet (Funktion "System_WiFi") auch senden. Im dargestellten Beispiel werden die Daten wie gewohnt bei Thinkspeak abgelegt (Unterprogramm "System_Thingspeak"). Die erfolgreich gesendeten Daten speichern wir im lokalen RTC-RAM (Unterprogramm "Sensoren_SpeichereRTC"). Damit ist die aktuelle Messaufgabe erfüllt.

Bei (Messaufgabe == 0) befinden wir uns in einem normalen Überwachungszyklus ohne die Möglichkeit der WLAN-Nutzung, da das Interface beim letzten deep-sleep deaktiviert wurde. In diesem Aufgabenfall schauen wir, ob der aktuelle Zyklus ein ganzzahliges Vielfaches des in "FesterSendeZyklus" gespeicherten Wert ist. Falls ja, dann ist die nächste Aufgabe das Senden der Messwerte aufgrund der zeitlichen Bedingung (MessAufgabe = 2 im nächsten Zyklus). Andernfalls überprüfen wir die Änderung gegenüber der zuletzt in der Cloud gespeicherten Werte (Funktion "Sensoren_Änderung"). Ist die Änderung signifikant, so ist die nächse Aufgabe das Senden der Messwerte aufgrund der Dynamik (MessAufgabe = 1 um nächsten Zyklus). Ohne Änderung verbleiben wir im Überwachungsmodus ohne WLAN (MessAufgabe = 0).

Zum Abschluss erhöhen wir den Zyklenzähler und speichen den neuen Zustand unseres Systems im RTC-RAM. Leider existiert kein Befehl, um das WLAN-Interface direkt zu aktivieren. Je nach nächster Aufgabe führen wir dafür ggf. einen sehr kurzen deep-sleep durch und wachen sofort wieder mit aktiviertem WLAN auf (MessAufgabe > 0), oder wir verschlafen eine Zykluszeit und starten mit der reinen Überwachung der Messwerte (energiesparend ohne WLAN).

 

 

   

Unterprogramm Konfig
Aufgrund des deep-sleep und dem damit einhergehenden Reset muss der Datenlogger seinen Systemzustand im RTC-RAM halten. Dieser Bereich ist nichtflüchtig und behält die Inhalte dauerhaft. Bei der ersten Nutzung muss das RAM mit sinnvollen Werten initialisiert werden (System_Coldstart).
Unterprogramm Kaltstart
Hier werden die Betriebsparameter initialisiert und im RTC-RAM abgelegt. Parameter können ja nach Anwendung individuell modifiziert werden. Um die neuen Parameter auf einem bereits laufenden System (mit initialisierten RTC-RAM) zu aktivieren, muss dieses Unterprogramm einmalig ausgeführt werden (neues Ardublock-Programm mit Coldstart im Setup).
Unterprogramm WiFi
Anmeldung am Accesspoint, Netzwerk und Passwort individuell angeben.
Unterprogramm Messwerte einlesen
Umweltmesswerte einlesen.
Funktion Messwertänderung
Aktuelle Messwerte mit den zuletzt in der Cloud gespeicherten Informationen vergleichen. Nur bei starker Änderung werden die neuen Daten sofort in der Cloud aktualisiert. Hier sind auch feste Überwachungsgrenzen denkbar.
Unterprogramm Speichern im RTC
Aktuelle Messwerte nach der Übermittlung in die Cloud direkt auf dem Controller (RTC-RAM) speichern. Damit kann jederzeit lokal (ohne WLAN) überprüft werden, in wie weit sich die Messwerte verändert haben.
Unterprogramm Thingspeak
Ablegen der Messdaten in die Thingspeak-Cloud. Individuellen API-Key ergänzen.
Unterprogramm Thingspeak Kommando
Natürlich können auch Daten aus einem Thingspeak-Kanal ausgelesen werden. Hier exemplarisch im Feld8 des Kanals der Sollwert der Zykluszeit. Damit kann die Dynamik unserer Messwerterfassung von außen parametrisiert werden. Um Energie zu sparen (online-Zeit) schauen wir nur in jedem 10. Zyklus nach einer Aktualisierung. Im Thingspeak muss bei diesem Kanal das "Make-Public"-Flag gesetzt sein, andernfalls antwortet Thingspeak mit einem "-1" für Zugriff verweigert.

Selber machen: Feinstaubmessung erfordert Vorlauf mit aktiviertem Sensor

Manche Sensoren benötigen einen längeren Vorlauf um stabile Messwerte zu erhalten. Ein gutes Beispiel dafür ist der Feinstaubsensor HM3301. Über I2C mit dem Octopus verbunden läuft direkt der integrierte Ventilator des Sensors an (ca. 75 mA) - was all unsere Energieüberlegungen über den Haufen schmeißt.  Auf dem Sensor existiert ein "Set" genannter Eingang, der bei "Low"-Pegel den Motor ausschaltet. Verbinden wir den "Set" des Sensors mit GPIO 12 unseres Octopus, so können wir den Motor aktivieren bzw. deaktivieren. Unglücklicherweise schaltet der ESP alle Ausgänge in einen potentialfreien Zustand, so dass der Motor trotzdem läuft. Um das zu verhindern müssen wir einen Pull-down Widerstand (z.B. 10 kOhm) von GPIO 12 gegen GND schalten. Dieser sorgt dann im deep-sleep für einen abgeschalteten Motor und für niedrigen Standby-Strom von ca. 150 µA .

Vor der Messung muss der Pin auf High-Potential gesetzt werden, der Motor läuft an und der Sensor benötigt lt. Datenblatt 30 s bis zur stabilen Messung. Diese Logik müssen wir im Datenlogger berücksichtigen.

 

 

 

Modifizierter Datenlogger für die Feinstaubmessung
Wollen wir Messwerte für Feinstaub übertragen, so müssen wir den Sensor rechtzeitig aktivieren (Sensor_StarteFeinstaub). In unserem Fall geschieht das nur zu den äquidistanten Abtastpunkten (MessAufgabe ==2).
Unterprogramm Start der Feinstaubmessung
Mit einem High-Pegel an GPIO 12 starten wir den integrierten Ventilator im Sensor und merken uns die aktuelle Zeit (millis) plus 30 Sekunden. In der Zwischenzeit können wir uns z.B. im WLAN einloggen.
Unterprogramm Thingspeak mit Feinstaub
Zum Senden der Messinformationen müssen wir erst die 30 Sekunden Anlaufzeit des Sensors abwarten. Erst dann ist der Messwert stabil und kann übermittelt werden.
back-to-top nach oben