Einleitendes

Der folgende Beitrag geht auf die Konstruktion und Umsetzung der Firmware sowie Probleme und Lösungen ein. Beschränkt wird sich auf die auf dem Sensor an sich laufende Software.

Einleitend ist die genutzte Basis bestehend aus der Programmiersprache und den genutzten Tools zu rechtfertigen. Hier sollte erst auf MicroPython als relativ neue Sprache und ein Derivat von Python zurückgegriffen werden. Nach ersten Versuchen stellte ich aber heraus, dass die Ressourcen auf dem ESP32 nicht ausreichen würden. Die vielen Sensorabfragen, die Verarbeitung und Versendung dieser benötigt viel Arbeitsspeicher. Durch Optimierung ließe sich dieses Problem womöglich verhindern, trotzdem wurde nach dieser ersten Erkenntnis umgeschwenkt auf eine Programmierung in Manier eines Arduinos mit C++.

Hier wurde allerdings nicht die Arduino IDE verwendet, sondern PlatformIO, eine IDE als Plugin-Ergänzung zu Visual Studio Code. Diese Entscheidung trägt dazu bei, dass nur die Erweiterung und kein weiteres Programm installiert werden muss, sowie die Handhabung (abhängig von persönlichen Präferenzen) einfacher ist.

Die Codebase hier besteht nur aus zwei Dateien, einer Arduino-typen main.cpp und einer config.h Datei. Die main.cpp Datei hat alle die Initialisierung aller Sensoren und Verbindungen, das messen und verarbeiten der Sensorwerte und das veröffentlichen dieser inne. Die config.h Datei hält nur die Wifi-Zugangsdaten, Adresse eines MQTT Brokers, das entsprechende Topic und den Port, sowie die Signatur des Sensors zu Veröffentlichung (für den Fall, dass es mehrere Sensoren gibt).
Hier wäre noch die Überlegung angemessen, ob nicht eine weitere Unterteilung der Übersicht halber sinnvoll wäre, worauf, der Simplizität halber erst einmal verzichtet wurde.

Im Folgenden wird der Code in seine verschiedenen Abschnitte unterteilt und größtenteils unabhängig beschrieben. Es wurde kein Code (ausgenommen entsprechend eingebundener Bibliotheken) ausgelassen, die Ausschnitte sind der gänzliche Code des Sensors.

Import der Bibliotheken

Hier werden die verschiedenen Bibliotheken, die zum Betrieb des Sensors benötigt werden, eingebunden. Benötigt werden diese zum Beispiel zur Serialisierung und Verarbeitung des JSON-Formats (ArduinoJson.h), dem Aufbau einer Wifi-Verbindung (WiFi.h und HTTPClient.h), der Kommunikation via MQTT (PubSubClient.h), oder der Ansteuerung der verschiedenen Sensoren (Abbildung 1).

Abbildung 1: Eingebundene Bibliotheken

Deklaration von Variablen/Konstanten

Hier wird nun erst die Anzahl der später zu nehmenden Messproben festgelegt (Abbildung 2). Es folgt die Definition der Pins, an welche die genutzten Sensoren angeschlossen sind (Abbildung 3) und darauf hin einer Variable, welche die seit der letzten Messung vergangenen Millisekunden speichert. Es folgen noch Variable, die den Status des Messvorgehens verfolgt, die Speicherung der Gerätesignatur, das Anlegen eines JSON Dokuments zur Veröffentlichung, das Ansprechen des Temperatur/Luftfeuchtigkeit/Luftdruck – Sensors über I2C, das Initialisierung des Luftqualitätssensors, sowie die Instanziierung von Wifi- und MQTT-Clients (Abbildung 4).

Abbildung 2: Anzahl Proben
Abbildung 3: Belegte Pins
Abbildung 4: Sonstige Definitionen

Nun geht es an das Aufbauen einer Internetverbindung (Abbildung 5). der Initialisierung des BME280-Sensors (Abbildung 6). Darauf folgt eine setup-Methode, die alles weitere bereitstellt. Hier wird eine serielle Verbindung zum Debuggen eröffnet, Wifi begonnen, MQTT verbunden wie erst die Pins einiger Sensoren richtig eingestellt und weitere Sensoren nun endgültig initialisiert (Abbildung 7). Es folgt eine Funktion, die ein char-Array in ein JSON serialisiert und dieses auf entsprechendem Topic veröffentlicht (Abbildung 8).

Abbildung 5: Verbindungsfunktion
Abbildung 6: BME280
Abbildung 7: Setup
Abbildung 8: Publish

Wie wird nun gemessen?

Was die konkreten Messungen angehet, so wird nicht jedes mal eine einzelne Messung erhoben, sondern über einen Zeitraum eine Vielzahl von Messungen genommen, von welchen der Durchschnitt weitergegeben wird. So lassen sich kleiner Spitzen und Ungenauigkeiten der Sensoren ausgleichen.

Wird nun eine typische Funktion zur Messung eines Wertes betrachtet (Abbildung 9), so gibt es eine reading Variable, auf welche später die Messungen aufaddiert werden. Es folgt eine for-loop, welche so oft abläuft wie Messwerte genommen werden sollen – wir haben 10 Proben gewählt. Nun wird immer die aktuelle Messung auf reading addiert und sofort danach 50 Millisekunden gewartet. Wurden alle Proben genommen wird reading durch die genommene Anzahl geteilt und dann an den Buffer für den zu erstellenden Json-String angehängt (Abbildung 10).

Abbildung 9: Messfunktion
Abbildung 10: Programmablauf

Besonderheit stellen hier nur verwendete Hilfsfunktionen dar. Diese Funktionen sind wie im Fall von CO2 (Abbildung 11) benötigt, um das gemessene Signal in einen nutzbaren Wert umzuwandeln. Im Fall von CO2 wird nur eine modellierte Frequenz ausgegeben. Hier muss nun der zeitliche Abstand verschiedener Abstände im Pegel genommen werden, welche später die Konzentration darstellt.
(CO2-Sensor MH-Z19B. (2020). unsinnsbasis.de. Abgerufen am 20. August 2022, von https://unsinnsbasis.de/co2-sensor-mhz19b/)

Abbildung 11: CO2-Helper

Die main-loop ist so konzipiert, dass hier nur der eigentliche Messvorgang und das Verschicken der Ergebnisse abläuft. Beginnend werden eine Variablen festgelegt und client.loop() hält die Verbindung offen (Abbildung 12). Dann wird getestet, ob bereits gemessen wurde (Abbildung 13). Ist die nicht der Fall, so wird unter Zuhilfenahme von einer measure()-Funktion die verschiedenen Messwerte genommen. In einer weiteren Schleife wird nun getestet, ob seit der letzten Messung genügend Zeit vergangen ist. Ist dies der Fall, so wird die aktuelle Messung serialisiert und veröffentlicht (Abbildung 14).

Abbildung 12: Verbindung
Abbildung 13: Messung
Abbildung 14: Veröffentlichung

Zusätzlich gibt es noch eine config.h Datei (Abbildung 15), diese hat die Zugänge zu den genutzten Services, sowie die Signatur der Wetterstation. Diese Signatur kann angepasst werden, um im Fall des Einsatzes von mehreren Wetterstationen diese zu unterscheiden.

Abbildung 15: Konfiguration

Tags:

Comments are closed