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:
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.
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:
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).
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.
Sie verlassen die offizielle Website der Hochschule Trier