Vorhandene Situation
Das Quellwasser auf der Alpe wird in einem Wasserreservoir gespeichert, welches in einem nicht leicht zugänglichen Gelände liegt. Dies bedeutet, wenn man den aktuellen Wasserstand wissen möchte, muss man jedes Mal den Weg zum Reservoir erklimmen und dieses öffnen, um nachzusehen. Weiters ist die Wasserabdeckung nicht über das ganze Jahr gegeben und es ist schwer zu analysieren, ob sich ein zweites Reservoir rentieren würde.
Aufgabe:
Der Wasserstand im Reservoir soll mithilfe eines autonomen Systems ermittelt, an einen Server übertragen und ausgewertet werden. Dadurch könnten die Daten bequem von Zuhause aus abgefragt werden. Beim Reservoir selbst sind keine bestehende Stromversorgung und Datenanbindung vorhanden. Durch die rauen Wetterbedingungen in den Alpen muss das System dauerhaft vor den Einflüssen von außen geschützt werden. Optional, wenn es die Zeit zulässt, kann noch eine Anzeige mit den wichtigsten Daten auf der Alpe installiert werden.
Konzept
Der Aufbau unterteilt sich in eine Haupt- und eine Sensorstation. In der Hauptstation befindet sich die LoraWAN Sendeplatine, sowie die Energieversorgung mit Batterie sowie Photovoltaikzelle und der Hauptarduino. Sie ist isoliert und enthält ein Heizpad damit auch bei winterlichen Temperaturen die Batterie vor dem Laden auf Betriebstemperatur gebracht werden kann.
In der Sensorstation befindet sich ein weiterer Arduino, der den Ultraschallsensor und den Durchflusssensor auswertet.
Für dieses aufgeteilte Konzept haben wir uns aufgrund von zwei Argumenten entschieden. Zum einen die lange Leitungslänge, die direktes Auswerten von Signalen aufgrund des Spannungsabfalls schwierig macht. Zum anderen der knappe Speicher auf dem Hauptarduino, der vor allem durch die LoraWAN Library stark belegt ist. So wäre die Auswertung der Sensorrohdaten auf dem Hauptarduino nur eingeschränkt möglich.
Lösung
Hauptstation
- Energieversorgung mit Photovoltaik und LiFePo4 Akku
- Energiemanagement
- LoRaWAN Sendemodul
- Temperatursensor
Sensorstation
- Ultraschallabstandsensor für Füllstandmessung
- Steuerung und Auswertung des Durchflusssensors
Sensorik
Für die Messung des Wasserstandes wurde ein Ultraschallsensor der Firma Maxbotix ausgewählt. Dieser ist wasserdicht und verfügt über eine Auflösung von einem Millimeter mit bis zu 7m Reichweite. Des Weiteren hat er ein sehr geringen Abstrahlwinkel von 11°, was nötig ist, um keine Reflektionen von der Wand des Reservoirs zu erhalten, die die Messung verfälschen können.
Zusätzlich zu der Aufgabenstellung wurden in den beiden Gehäusen zwei kombinierte Temperatur- und Luftfeuchtesensoren verbaut. Mit diesen Sensoren kann der „Gesundheitszustand“ der Gehäuse festgestellt werden. Dabei wurden 1-wire Sensoren verwendet. Bei der Hauptstation wurde zusätzlich ein externer 1-wire Temperatursensor verbaut, um die Umgebungstemperatur zu messen.
Um den Überlauf des Reservoirs zu messen wurde ein eigener Sensor entwickelt. Dieser basiert auf dem kapazitiven Messprinzip. Je mehr Wasser zwischen den beiden Kondensatorplatten hindurchfließt, umso niedriger wird die Kapazität der Anordnung. Die Kapazität der Anordnung wird durch einen astabilen Multivibrator mit 555 Timer-IC ausgewertet. Diese Schaltung verändert ihre Schwingfrequenz je nach angeschlossener Kapazität. Diese Frequenz kann über einen Frequenzzähler auf dem Arduino ausgewertet und auf den Abfluss umgerechnet werden. Die Idee zum Durchflusssensor haben wir von diesem Video: https://youtu.be/ATY3bhiUqg4
Datenübertragung und Programmierung
TheThingsNetwork
TheThingsNetwork verwaltet das von uns genutzte LoraWAN Netzwerk. Von unserem Gerät gesendete Daten sind auf den Servern von TheThingsNetwork abrufbar. Auf der Website müssen alle Geräte registriert und einer Anwendung zugeordnet werden. TTN übernimmt auch die Umwandlung von einer Serie von Bytes, wie sie von unserem Gerät verschickt werden, in das JSON Format, welches für die weitere Verarbeitung genutzt wird.
Visualisierung via Senseforce
Senseforce ist ein im Campus V ansässiges Unternehmen, das Datenanalysetools zur Verfügung steht. Wenn an den MQTT Broker Daten gesendet werden, werden diese automatisch in die Datenbank übernommen. Im Webinterface von Senseforce können die Daten dann einfach gefiltert und mit Diagrammen visualisiert werden.
MQTT
MQTT ist ein Standard, um Daten von IoT Geräten zu übertragen. Es gibt einen Broker (Serveranwendung) an den die Daten gesendet werden. Um die Daten verschiedener Anwendungen zu trennen sind sie in Themen (topics) organisiert. Von dem Broker können dann alle Daten eines Themas abgerufen werden. Die Daten werden im JSON Format verschickt.
Die MQTT Messages müssen vom MQTT Broker von TTN abgerufen und dann an den MQTT Broker von Senseforce weitergesendet werden. Da wir auf beide Broker keinen Zugriff außerhalb des Abrufens bzw. Sendens von Daten haben, können wir keine direkte Verbindung zwischen ihnen herstellen. Deshalb kommt eine MQTT Bridge zum Einsatz, die Messages vom TTN Broker abruft, kurz zwischenspeichert und dann zum Senseforce Broker hochlädt. Das erfordert einen dauerhaft verfügbaren Webserver und erhöht dadurch den Betriebsaufwand. Eine gute dauerhafte Lösung haben wir hier noch nicht.
Unterer Arduino (Sensorarduino)
Die Aufgabe des Sensor-Arduinos ist es den Ultraschall- und den Durchflusssensor auszulesen. Um Sendezeit zu sparen sollen die Daten mit möglichst wenigen Bytes übertragen werden. Um Speicherplatz am Sendearduino zu sparen sollen die Bytes direkt aus der seriellen Verbindung weitergesendet werden, ohne dafür noch Berechnungen durchführen zu müssen.
Die gesamte untere Box ist in der Regel spannungsfrei und wird nur eingeschaltet, wenn Messwerte benötigt oder andere Befehle gegeben werden. Der Sensordarduino wartet dann auf einen Befehl.
Ermittlung des Wasserstands
Der Ultraschallsensor gibt einen Puls aus, dessen Länge sich abhängig vom gemessenen Abstand linear verändert. Dabei entspricht Pulslänge Abstand. Da die Genauigkeit des Sensors bei 5mm liegt und wir ohnehin entschieden haben, dass eine Genauigkeit von ausreicht, wird mit einem Integer in Zentimetern weitergerechnet. Mit der bei Inbetriebnahme im Speicher hinterlegten Höhe des Sensors über dem Boden des Tanks wird aus dem Abstand die Füllhöhe errechnet. Dieser Wert darf maximal 255cm betragen, da bei der Übertragung nur ein Byte vorgesehen ist. Der Tank ist aber nur 2m tief, sodass eine Überschreitung dieser Grenze bei korrekten Messungen nicht möglich ist.
Ermittlung des Durchflusses
Zur Bestimmung des Durchflusses muss die Frequenz der Schaltung des Durchflusssensors, die von der Kapazität des Plattenkondensators abhängt, gemessen werden. Dazu wird die Bibliothek FreqCount verwendet. Diese zählt die Peaks in einem bestimmten Zeitfenster und errechnet daraus die Frequenz. Da die Messwerte mit dieser Methode stark schwanken, wird ein Mittelwert aus drei Messungen gebildet. Anhand der empirisch ermittelten Formel wird daraus ein Durchfluss ermittelt.
Temperatur und Luftfeuchtigkeit
Die Messung von Temperatur und Luftfeuchtigkeit ist an allen relevanten Stellen der Programme vorbereitet, aber noch nicht implementiert. Eine Umsetzung mit DHT11 und DHT22 Sensoren scheiterte an Timingproblemen, da die von uns eingesetzten Arduinos eine Taktfrequenz von haben, die Library für die Sensoren aber für ausgelegt ist. Da dieses Feature mit niedriger Priorität erst kurz vor Ende des Projekts umgesetzt werden sollte, fehlte die Zeit, um andere Sensoren zu bestellen und zu implementieren.
EEPROM
Um das Programm für jeden Tank einsetzen zu können sind einige Werte für die Berechnungen als Variablen hinterlegt. Über die serielle Debug-Schnittstelle können sie geändert werden, ohne das Programm neu aufspielen zu müssen. Da für das Energiemanagement vorgesehen ist, den Arduino zwischendurch vollständig abzuschalten, können die Variablen nicht im normalen Variablenspeicher gespeichert werden. Stattdessen kommt der im Arduino vorhandene „electrically erasable programmable read-only memory“ (EEPROM) zum Einsatz. Die einzelnen Bytes können mit einer Library wie bei einem Array ausgelesen werden. Auch der Sommer- bzw. Wintermodus wird im EEPROM eingestellt. EEPROM Speicher eignet sich allerdings nicht, um ihn oft zu beschreiben. Da der Tank nicht oft gewechselt wird und auch nur zweimal jährlich ein Wechsel zwischen Sommer- und Wintermodus ansteht, ist aber nicht zu erwarten, dass der Speicher frühzeitig unbrauchbar wird.
Oberer Arduino (Sendearduino)
Die wesentlichen Aufgaben des oberen Arduinos sind die Datenverbindung über LoraWAN und das Energiemanagement. Auch einige Sensoren sind verbaut, diese machen aber nur einen Bruchteil des Codes aus.
Datenverarbeitung und Übertragung
Die wichtigste Aufgabe ist das Betreiben des LoraWAN Funkchips. Einen Großteil der Arbeit erledigt die LMIC Bibliothek automatisch. Wichtig ist, die Funktion os_runloop_once() regelmäßig auszuführen, da darin wichtige Aufgaben für das Aufrechterhalten einer Verbindung erledigt werden Ein Timer startet in einem regelmäßigen Abstand den Übertragungsprozess. Dazu werden zunächst die Daten vom Sensorarduino angefragt. Diese Daten werden dann in ein Array übertragen und die Überwachungswerte (Temperatur, Luftfeuchtigkeit, Batterie) hinzugefügt. Dann wird der Sendevorgang in Auftrag gegeben. Alles weitere regelt die LMIC Bibliothek.
Folgendes Byte-Array wird über LoraWAN übertragen:
0 | 1 | 2 | 3 | 4 |
Ultraschall | Überfluss | Luftfeuchtigkeit Innen unten | Temperatur Innen unten | Modus |
5 | 6 | 7 | 8 | 9 |
Batterie-spannung | Temperatur Außen | Luftfeuchtigkeit Innen oben | Temperatur Innen oben | LDR |
Energiemanagement
Das Energiemanagement wurde noch nicht implementiert, die einzelnen Funktionen aber bereits geplant. Es sind dabei zwei Aufgaben zu bewältigen:
Minimierung des Energieverbrauchs
Die Zeitspanne zwischen zwei Übertragungen beträgt mindestens 5 Minuten. Dazwischen beschränken sich die Aufgaben des Arduinos auf das Energiemanagement. Durch Versetzen in einen Schlafmodus für wenige Sekunden kann der Energieverbrauch drastisch gesenkt werden. Beim Aufwachen kann dann das Energiemanagement und gegebenenfalls auch eine neue Übertragung vorgenommen werden. Danach wird das Gerät wieder in den Schlafmodus versetzt. Die Sensorbox wird, solange keine Daten für eine Übertragung benötigt werden, ganz abgeschaltet. Durch Auslesen der Batterie kann ein Energieengpass frühzeitig erkannt werden. Unter einer bestimmten Spannung wird die Sendefrequenz schrittweise reduziert.
Optimierung der Batterieladung und Verhindern einer Überladung
Um die Lebensdauer der Batterie zu schonen ist es sinnvoll, die Solarzelle abzuschalten, wenn die Batterie vollgeladen ist. Dazu wird die Batteriespannung gemessen und über einem bestimmten Grenzwert ein MOSFET durchgeschalten, um die Solarzelle kurzzuschließen. Im Winter kann es außerdem vorkommen, dass die Temperatur der Batterie so niedrig ist, dass ein Ladevorgang ineffizient und für die Batterie schädlich wäre. Über einen lichtabhängigen Widerstand wird festgestellt, ob die Sonne scheint und die Solarzelle Energie bereitstellt. Über den Temperatursensor im Inneren wird festgestellt, ob ein Heizen der Batterie notwendig ist. Wenn beide Bedingungen erfüllt sind wird eine Heizmatte neben der Batterie angeschaltet bis eine Mindesttemperatur erreicht ist.
Speicherplatz
Die LMIC Bibliothek verbraucht sehr viel Speicherplatz, insbesondere für Variablen. Bei der Programmierung war daher besonders auf den Speicherverbrauch zu achten. An einzelnen Stellen konnte der Beispielcode, auf dem unser Programm aufbaut, noch effizienter gestaltet werden. Durch die Verwendung des zweiten Arduinos konnte Speicherplatz gespart werden, indem die Daten über die serielle Verbindung bereits vollständig verarbeitet ankommen und nur noch über das LoraWAN Netzwerk weitergeleitet werden müssen.
Kommunikation zwischen den Arduinos
Die Kommunikation zwischen den beiden Arduinos läuft über eine einfache serielle Verbindung mit zwei Leitungen (VCC und GND sind ohnehin verbunden). Da auf der Platine des Sende-Arduinos die eingebaute serielle Schnittstelle bereits für Debugzwecke vorgesehen ist wird mit der SoftwareSerial Library eine weitere Schnittstelle simuliert. Am Sensorboard wird die serielle Schnittstelle verwendet.
Die Kommunikation beginnt immer mit einem Befehl des Sendearduinos and den Sensor, der darauf gegebenenfalls antwortet. Es gibt 3 Befehle, die theoretisch mit 2 Bits übertragen werden könnten. Eine Umsetzung mit 8 Bits ist allerdings einfacher, da so der Byte oder Char Datentyp verwendet werden können. Die Werte der Befehle sind anhand der Anfangsbuchstaben der Befehle gewählt und haben keine technische Bedeutung.
0x52 – Request – Abfragen von Sensorwerten
Es wird folgende Reihe von Bytes übertragen:
Ultraschall | Überfluss | Luftfeuchtigkeit | Temperatur | Modus |
0x57- Winter mode – Winter Modus einstellen
0x53- Summer mode – Sommermodus einstellen
Zusammenfassung
Im Projekt wurden eine Hauptstation und eine Sensorstation gebaut, sowie programmiert. Die Hauptstation beheimatet die Energieversorgung mit Solarpanel und LiFePo4-Akkumulator und dem Energiemanagement. Des Weiteren sind dort ein Arduino und ein LoRaWAN-Funkmodul, die das Senden der Daten übernehmen. Zudem ist außerhalb der Hauptstation ein Temperatursensor befestigt, um die Außentemperatur zu erfassen.
In der Sensorstation befindet sich ein weiterer Arduino, der die Messwerte von zwei Sensoren erfasst, umrechnet und via serielle Schnittstelle an den Hauptarduino weiterleitet. Die Sensoren sind zum einen der Ultraschall-Abstandssensor, der den Wasserstand misst, und zum anderen der Durchflusssensor, der den Überlauf des Reservoirs erfasst.
Aktuell noch nicht umgesetzt, wird allerdings noch nachgereicht, ist die Visualisierung der erfassten Messwerte auf der Online-Plattform Senseforce. Der Auftraggeber wird zudem bei einer knappen Wasserlage per E-Mail benachrichtigt, damit er weitere Maßnahmen einleiten kann.
Zugang Senseforce
Unter diesem Link könnt ihr unsere Visualisierung der Sensordaten einsehen.
mit der Email FhvVisitor@gmail.com und dem Passwort SmartCity2k
Fragen oder Anregungen
Falls ihr Fragen oder auch Anregungen habt, erreicht ihr uns unter folgenden Email-Adressen:
tim.strutzberg@students.fhv.at
robert.theobold@students.fhv.at
georg.wehinger@students.fhv.at