Sensordaten mit Arduino und LoRa an ioBroker übermitteln
In diesem Artikel werden wir Sensordaten über eine längere Strecke via LoRa und Arduino in ioBroker übertragen.
Die LoRa-Funktechnik ermöglicht die Übertragung von Informationen über große Distanzen mit einem geringen Stromverbrauch. Die Technik eignet sich daher auch bestens im Smart-Home Umfeld, um z.B. Sensoren im Garten in das Smart-Haus integrieren zu können. Bestehende Funktechniken wie WLAN haben hier meistens eine zu geringe Reichweite und zudem noch einen deutlich höheren Stromverbrauch. Im Artikel werden wir nun mittels einem ESP32 LoRa Board einen kleinen Sender mit Temperatur- und Luftfeuchtigkeitsensor aufbauen, welcher die ermittelten Informationen via LoRa ein ein baugleiches Board überträgt und diese dann per MQTT und WLAN an ioBroker übermittelt. Den Empfänger werden wir direkt im Haus platzieren wodurch wie die Informationen einfach in ioBroker übertragen können.
Verwendete Materialien und Produkte
Hier liste ich zunächst die verwendeten Materialien und Produkte auf, welche für den Nachbau des LoRa-Senders und Empfängers erforderlich sind:
Architektur
In folgendem Schaubild wird die Architektur des Test-Aufbaus dargestellt:
Im Test-Aufbau wird das erste Heltect ESP32 LoRa Board mit einem BME280 Sensor ausgestattet. Diese ESP32 Komponente wird bei uns im Garten installiert und soll an diesem Standort die Temperatur sowie die Luftfeuchtigkeit messen und per LoRa an den zweiten ESP32 übertragen.
Das zweite Heltect ESP32 LoRa Board wird bei uns im Wohnhaus platziert und zusätzlich mit dem WiFi verbunden. Der ESP32 wird später dann die empfangenen LoRa-Nachrichten per WiFi-Verbindung und MQTT an ioBroker übermitteln. Als Nachrichtenformat wird eine JSON-Zeichenkette verwendet, da diese relativ einfach zu erstellen ist. Zudem kann das Format später einfach um zusätzliche Eigenschaften erweitert werden. Ein weiterer Vorteil des JSON-Format ist das einfache und komfortable Parsen in JavaScript in ioBroker. Die JSON-Zeichenkette als Nachrichtenaustausch wird folgendes Format haben:
{"name":"SensorOutdoor1", "temp":4.5, "hum":58}
Als Name wird ein eindeutiger Name des Sensors verwendet. Wenn später weitere Sensoren hinzukommen, können so die einzelnen Sensoren differenziert werden. Über die Eigenschaften Temp und Hum werden die Temperatur sowie Luftfeuchtigkeit übermittelt.
Installation von Bibliotheken
Nun beginnen wir mit den Vorbereitungen der Entwicklungsumgebung. Für das Flashen des ESP32 Boards benötigen wir zunächst die entsprechende Board-Software für das Heltec ESP32 Board. Über die Suchfunktion im Boardverwalter (aufrufbar unter Werkzeuge – Board – Boardverwalter) suchen wir nach dem Hersteller „heltec“ und installieren die im Screenshot gezeigte Board-Software.
Im nächsten Schritt benötigen wir noch für den BME280-Sensor die entsprechenden Bibliotheken. Folgende Bibliotheken müssen wir hierzu installieren:
- Adafruit BME280 Library (Version 2.0.0 oder neuer)
- Adafruit Unifed Sensor (Version 1.1.1 oder neuer)
Aufbau des Senders
In diesem Kapital bauen wir nun zunächst den Sender auf. Am Sender wird der BME280-Sensor wie folgt angeschlossen:
ESP32 | BME280 |
3,3V | VIN |
GND | GND |
4 | SDA |
15 | SCL |
Ich habe die Anschlüsse mit einfachen Steckverbindungen vom Breadboard vorgenommen. Später werden wir hierfür noch eine kleine Platine mit Halterung für einen Akku vorsehen.
Im nächsten Schritt kannst Du den folgenden Arduino-Sketch für den Sender herunterladen und als neuen Sketch in der Arduino IDE einfügen.
Sketch LoRa-Sender (1196 Downloads )Als ich nun das erste mal den Sender compiliert und gestartet habe, wollte ich zunächst die ermittelten Sensorwerte des BME280-Sensors kontrollieren. Im seriellen Monitor wurden mir aber leider entweder 100, 0, oder NaN angezeigt. Auch mit alternativen Libaries oder einer Adresse des Sensors wurden keine brauchbaren Messwerte angezeigt. Nach langer Recherche bin ich dann auf einen Artikel gestoßen, in dem auch ein BME280 am Heltec ESP32-Board betrieben wurde, und ebenfalls keine Messwerte ermittelt werden konnten. Der Author des Artikels veröffentlichte freundlicherweise seine Lösung des Problems, welche ich hier in meinem Artikel übernehme:
https://www.instructables.com/id/The-Super-Long-Distance-WiFi-of-the-ESP32-LoRa-Wit/
Der Grund für die fehlerhaften Messwerte ist die Pin-Belegung des Heltec-Boards. Die Pins SDA und SCL sind im Port-Mapping auf 21 und 22 gelegt. Die Adafruit Bibliothek unterstützt dies aber aber nicht. Wir müssen daher die Belegung, wie unten gezeigt, anpassen:
C:\Users\<Username>\AppData\Local\Arduino15\packages\Heltec-esp32\hardware\esp32\0.0.4\variants\wifi_lora_32_V2\
pins_arduino.h
Folgende Anpassungen müssen durchgeführt werden:
Der Sketch ist relativ einfach gehalten. In der Setup-Methode wird zunächst die serielle Verbindung initialisiert sowie die statische Begin-Methode der HelTec Board-Software aufgerufen. Über diese Methode wird das Board entsprechend initialisiert. Im Anschluss wird der BME280-Sensor initialisiert und dann die Loop-Methode aufgerufen.
In der Loop-Methode werden die Sensor-Informationen ermittelt und daraus ein JSON-Zeichenfolge gebildet. Ich habe hier auf eine zusätzliche Bibliothek verzichtet und die Zeichenfolge einfach per String aufgebaut. Über die LoRa Methoden wird dann ein LoRa-Paket erstellt und gesendet. Abschließend warten wir 10 Sekunden und durchlaufen dann erneut die Loop-Methode. Für den praktischen Einsatz müssen hier später noch Anpassungen wie der DeepSleep-Mode erfolgen.
Aufbau des Empfängers
Im nächsten Schritt können wir den Empfänger aufbauen. Hierfür laden wir uns zunächst den folgenden Sketch runter und fügen ihn in der Arduino IDE ein.
Sketch LoRa-Empfänger (1131 Downloads )Im Sketch des Empfängers müssen wir zunächst die WLAN-Konfiguration anpassen. Hierbei muss die SSID sowie das Kennwort der WLAN-Verbindung im Code hinterlegt werden. Zudem müssen wir die IP-Adresse des MQTT-Brokers angeben. In meinem Fall verwende ich hier die IP-Adresse der ioBroker Instanz.
Im Sketch wird in der Setup-Methode zunächst wieder das HelTec-Board initialisiert und dann die Verbindung zum WLAN sowie zum MQTT-Server aufgebaut. Abschließend warten wir innerhalb der Loop-Methode auf die eingehenden Sensorinformationen und publizieren diese dann am MQTT-Broker über den Topic LoRaServer/SensorCmd. Die weitere Verarbeitung von unterschiedlichen Sensoren erfolgt direkt in ioBroker. Ich muss somit an der Arduino-Software keine weiteren Anpassungen vornehmen.
ioBroker Vorbereitungen
Im nächsten Schritt wechseln wir nun ioBroker. Nach dem wir beide ESP32-Boards mit Strom versorgt haben und die ersten LoRa-Nachrichten versendet werden, sollten wir in den MQTT-Datenpunkten einen neuen Ordner LoRoServer finden. Manchmal dauert dies ein wenig und auch die Objekt-Struktur muss über die Aktualisierungsschaltfläche neu geladen werden.
Nach ca. 1 Minute wurde mir dann die folgende JSON-Zeichenkette im Datenpunkt angezeigt 🙂
Wir haben nun also die Temperatur sowie die Luftfeuchtigkeitswerte des Sensors SensorOutdoor1 erfolgreich an ioBroker übermittelt.
{"name":"SensorOutdoor1", "temp":22.08, "hum":87.32}
Im nächsten Schritt wechseln wir nun in den Bereich Skripte und erstellen uns ein neues JavaScript, welches die Sensordaten verarbeitet und dafür entsprechende Datenpunkte erstellt.
Das komplette Script kannst Du hier runterladen:
ioBroker LoRa Script (789 Downloads )
Im Script wird ein Trigger auf den SensorCmd Datenpunkt des MQTT-Adapters erstellt. Nach einer Veränderung des Datenpunktes wird der Trigger ausgeführt, welcher dann die Funktion ParseCommand() startet. Die Funktion parst nun die übergebenen JSON-Zeichenfolge und ermittelt so den Namen des Sensors sowie die einzelnen Sensorwerte. Anschließend wird mit dem createState() Command ein entsprechender Datenpunkt angelegt sowie mit setState() der Datenpunkt mit dem Wert gesetzt. Die Vorgehensweise ist hier nicht ganz richtig, da direkt nach dem createState() kein setState() erfolgen kann (Timing-Problem). Dies tritt aber nur bei der ersten Ausführung auf, und war daher für mich so kein Problem. Richtigerweise müsste man hier die createState() Aufrufe nur einmalig vornehmen.
Nach der Aktivierung des Scripts und dem ersten Versenden und Empfangen der LoRa-Nachrichten sollten wir nun in den Objekten einen neuen Eintrag für die LoRa-Sensoren erhalten. Im Script habe ich den Verwahrungsort der Daten unter JavaScript.0.LoRa gewählt.
Fazit und Ausblick
Mich faszinieren die Möglichkeiten der LoRa-Funktechnik immer mehr. Gerade der Einsatz im Smart-Home ermöglicht nun viel bessere Anbindungen von entfernten Sensoren. So könnten wir z.B. in Zukunft auch unsere Streuobstwiese am Stadtrand besser überwachen und einen Feuchtigkeitssensor an jungen Bäumen installieren. Auch die einfache Integration in ioBroker und die damit verbundenen weiteren Möglichkeiten der Auswertung, Visualisierung und Automatisierung machen hier Lust auf weitere LoRa-Projekte. Als nächste Erweiterung werde ich auf jeden Fall das JSON-Paket um eine DeviceClass erweitern, mit dem ich später in ioBroker die Daten einfacher verarbeiten kann. Folgende DeviceClasses sind in Planung:
- TempHumiditySensor (name, temp, hum)
- CommonSensor (name, value)
- PositionSensor (name, latitude, longitude)
Mit dieser Klassifizierung kann ich nun problemlos unterschiedliche Sensortypen betreiben und auf der Seite von ioBroker entsprechend die Werte weiterverarbeiten. Die Anpassungen dazu sind minimal, da hier nur am Arduino Sender eine Erweiterung vorgenommen werden muss. Zudem muss dann in ioBroker die Parsing-Aufgabe je nach Sensortype in unterschiedliche Funktionen ausgelagert werden.
Ich werde hier definitiv noch weitere Projekte umsetzen 🙂
Interessanter Artikel; du beschreibst den Sender-Aufbau als stromsparende Lösung. Hast du zufällig auch Messungen durchgeführt? Würde mich echt interessieren.
Danke
Hallo Matthias,
danke für Deinen tollen Artikel. Bin gerade ein paar Tage unterwegs und werde Dein Tutorial wahrscheinlich am WE mal ausprobieren.
Sicher treten noch zwei/drei Fragen auf.
Bis später Gruß Mark
Hallo Matthias,
habe es endlich mal geschafft Dein Tutorial auszuprobieren.
Der Sender funktioniert ohne Probleme.
Will ich den Empfänger kompilieren kommt die Fehlermeldung: images.h: no such file or directory.
Wo bekomme ich die images.h her bzw. wie erstelle und wo speichere ich diese.
LG
hi habe auch das Problem mit der Images.h …
wie hast du das genau gelöst?
Hallo Matthias,
obiges Problem mit der images.h habe ich gelöst bekomme. Habe einfach ein Heltecbeispielscript genommen und Deinen Code hineinkopiert.
In den JS-Objekten wurden zwar der Sensorpunkt angelegt, aber keine Werte-Punkte angezeigt. Hat sicher was mit der createState()/setState()-Problematik zu tun. Nach einem Neustart des Pi war dann alles so wie es sein sollte.
Eine nicht ganz unwichtige Frage tut sich mir nun auf. Die Lora-Frequenz ist ja frei, und so kann ja eigentlich „Jeder“ die gesendeten Werte mitlesen oder gar andere Werte senden. Was bei Temperaturmeldungen eventuell noch zu verschmerzen wäre, solange das keine Grundlage für Reaktionen ist (z.Bsp. Gewächshaus prüfen/lüften/heizen/sichern). Bei Magnetkontakten oder Wasserstandsmeldern schon etwas problematischer. Wie können die gesendeten Daten abgesichert/verschlüsselt werden.
Danke für Dein Tutorial und viele Grüße
Hi Matthias,
sehr guter Artikel. Ich habe bis jetzt noch niemanden gesehen der Lora in IoBroker intergriert hat. Zumindest nicht dokumentiert. Was ich schade finde, dass dies nur eien P2P Variante zwischen zwei ESPs ist. Ein Gateway und mehrere Senosren dran das wäre für mich die ultimative Lösung.
Danke für die gute Dokumentation des Aufbaus!
Zum Kommentar von Matthias setze ich noch eines drauf: schän wäre auch eine bidirektionale Übertragung; d.h. mann kann nicht nur die Sensoren auslesen, sondern ihnen auch Werte (z.B. Schwellwerte) übermitteln.
Hi Matthias,
Interessanter Artikel. Machst du noch mehr mit LoRa mittlerweile oder ist es nur bei diesem Test geblieben?
Gruß
Christian
Moin Christian,
aktuell fehlt mir ein wenig die Zeit – hier kommt aber definitiv noch mehr 🙂
LG Matthias
Danke für die gute Beschreibung!
Wozu dient der ESP32 auf der ioBroker Seite?
Könnte man nicht auch direkt mit einem LORA Modul am Raspberry kommunizieren und lokal auf MQTT umsetzen?
lG Gerhard
Hallo,
ich habe mir zum testen des Stromverbrauchs, einen Heltec asr6501mit einem BME280 verbunden.
Der sendet alle 60sec ein Datenpaket(Temperatur,Luftfeuchte,Luftdruck und Batteriespannung) ins TTN Netz. Betreibe den Heltec mit einer 4,5 Volt Flachbatterie…nach 174311 Messungen ist noch 4,314 Volt auf der Batterie.
Also sehr sehr Stromsparend:-)
Hallo Hans,
ja, das Heltec-Modul ist sehr stromsparend. Cooles Projekt, würde mich hier über mehr Details freuen. Wo hast Du den Sensor installiert?
LG Matthias
Hallo Matthias,
Der sender läuft, aber beim Empfänger bekomme ich den Fehler: invalid conversion from ‚const char*‘ to ‚const uint8_t* {aka const unsigned char*}‘ [-fpermissive]“
Bezogen auf die Zeile: „Heltec.display->drawXbm(0,5,logo_width,logo_height,logo_bits);“
Woran kann da liegen?
LG
Fritz
Hallo Fritz,
versuche mal die HelTec Bibliothek upzudaten, ich meine da gab es ein Issue auf Github, schau mal hier:
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/issues/59
LG Matthias
Ich nutze den heltec 0.0.5 board treiber und die heltec 1.1.0 Bibliothek.
Gelöst.
Ich musste die Zeile:
display.drawXbm(0,5,logo_width,logo_height,logo_bits);
durch
display.drawXbm(0,5,logo_width,logo_height,(uint8_t*)logo_bits);
ersetzen.
Hallo Matthias,
ist es auch möglich darüber zwei IOBroker instanzen zu koppeln? Darüber könnte ich ein LTE Router und reichlich Strom für den Schrebergarten sparen…
IOBroker – MQTT – ESP32 Lora —– ESP32 Lora – MQTT – IOBroker
Gruß Mark
Servus,
bei mir werden immer folgende 2 Include befehle angemäckert ich weiß aber nicht welche Bibliotheken mir fehlen Weiß die zufällig wer?
#include „images.h“
#include
Danke
Gruß Marcel
das 2. include sollte #include heißen und ist soweit ich rausgefunden habe folgende Bibliothek. zumindestens gehts mit der…..
https://github.com/knolleary/pubsubclient