LoRaWAN Bodenfeuchtesensor mit Raspberry Pi Pico

Motivation

Anlass für die Entwicklung eines Bodenfeuchtesensors war die Avocadopflanze, die meine Freundin im Sommer 2021 aufgezogen hat. Durch die Nähe zum Fenster hatte diese zwar ausreichend Licht - gleichzeitig wurde die Erde im Pflanzentopf aber auch zügig ausgetrocknet. Da wir beide keinen besonders grünen Daumen haben, musste - zumindest aus meiner Sicht - eine technische Lösung dafür her: Ein Sensor, der den Feuchtigkeitsgehalt der Erde misst und mich alarmiert, wenn der Wert unter einen gewissen Schwellwert sinkt.

Die Ziele waren schnell abgesteckt:

  • Aktive Benachrichtigungen über aktuellen Zustand des Bodens, sobald ein kritischer Wert erreicht wird
  • Versand der Benachrichtigungen via XMPP, sodass diese via Smartphone empfangen werden können
  • Mögliche Abfragen der aktuellen Bodenfeuchtigkeit via Messenger-Chat (Chatbot)
  • Hohes Maß an Energiesparsamkeit der Bodeneinheit, um einen langen Akkubetrieb zu ermöglichen

Dazu kommen natürlich noch weichere Ziele wie z.B. die Einhaltung eines Hobby-freundlichen Budgets und eine gewisse Sensorkompaktheit, um das Gerät unauffällig am Pflanzentopf anbringen zu können.

Architektur

Kommen wir zur Architektur:

Architekturzeichnung mit Systembestandteilen

Die Komponenten in der Reihenfolge des Datenflusses der Sensordaten:

LoRaWAN Sensoreinheit

Die Sensoreinheit hat nur eine Aufgabe: Feuchtigkeit messen und übermitteln. Kein Umrechnen, kein Einstufen - einfach nur übertragen. Sie befindet sich in Topfnähe und soll von einem Akku mit Strom versorgt werden. Damit der Energieverbrauch niedrig bleibt, habe ich mich für eine Kombination aus einem Raspberry Pi Pico und einem Waveshare LoRaWAN Modul SX1262 (EU-Band) entschieden. Durch LoRaWAN ist es möglich, mit geringstem Energieeinsatz sehr kleine Datenmengen (einige Bytes) in regelmäßigen Abständen auch über weite Strecken zu übertragen. In einigen Fällen sogar 2 km weit oder mehr. Mögliche Datenrate und Reichweite sind von vielen Faktoren abhängig, doch für meine Zwecke absolut ausreichend - wenn nicht sogar überdimensioniert.

Mir ging es aber vor allem um den geringen Energiebedarf. Ansonsten hätte sich für den Einsatz in der Wohnung vermutlich auch Bluetooth LE, Zigbee oder ähnliches geeignet.

Raspberry Pi Pico mit Waveshare LoRa Modul

Die Wahl der Microcontrollerplattform ist auf das Raspberry Pi Pico gefallen, weil ich das Board mit dem RP2040 ARM Cortex M0+ bereits vor einiger Zeit ins Auge gefallen ist: Es ist klein, simpel, ohne Schnickschnack, lässt sich mit handelsüblichen Tools bedienen und braucht keine Sonderlocken, merkwürdige IDEs oder sonst etwas, was mich stören würde. Zudem ist es einigermaßen energiesparsam und kompakt, sodass man es gut am Topf in einem kleinen Gehäuse unterbringen kann.

Das Waveshare LoRaWAN Modul ist speziell für das Raspberry Pi Pico entwickelt worden und lässt sich mittels Pin-Header ganz einfach aufstecken. Sogar eine kleine LoRa Antenne und ein kleiner Akku (eher als Pufferakku anzusehen) sind in der Lieferung enthalten.

Die eigentliche Feuchtigkeitsmessung geschieht durch einen kapazitiven Bodenfeuchtesensor des Typs “Capacitive Soil Moisture Sensor v2.0”. Ein Hersteller oder eine genauere Modellnummer ist mir nicht bekannt, aber eine Websuche nach dem Titel sollte zum korrekten Sensor führen.

Ich habe mich aus einem bestimmten Grund für einen kapazitiven (und keinen resistiven!) Sensor entschieden: Die grundlegend unterschiedliche Funktionsweise verringert Korrosion am Sensor, weil im Vergleich zu einem resistiven Sensor keine offenliegenden Kontaktflächen benötigt werden. Während der resistive Sensor effektiv Strom durch das Erdreich leitet und seinen elektr. Widerstand misst, nutzt der kapazitive Sensor die Erd-/Messumgebung als elektr. Kondensator und misst seine kapazitiven Eigenschaften über Signallaufzeiten. Genauso funktionieren übrigens die meisten Füllstand-/Tanksensoren in Fahrzeugen. Mehr zur Funktionsweise und den Vorteilen erfahrt ihr in diesem Video: #207 Why most Arduino Soil Moisture Sensors suck (incl. solution) - YouTube

Der Sourcecode für die Sensoreinheit ist unter der MIT Lizenz auf GitHub verfügbar: https://github.com/ThomasLeister/plantmonitor-sensor

Capacitive Soil Moisture Sensor v2.0

LoRaWAN Gateway

Damit die LoRa Daten von der Sensoreinheit weiterverarbeitet werden können, werden sie von einem LoRaWAN Gateway aufgenommen und via MQTT an das “The Things Network” (TTN) weitergelietet. Das TTN ist ein weltweites Netzwerk, das durch verschlüsselte Daten aus LoRa-Sensoren gefüttert wird. Diesem Netzwerk kann man mit seinem eigenen Gateway (oder durch ein Gateway Fremder) beitreten und kommt so über verschiedenste Online-Interfaces wieder an seine Sensordaten, z.B. via HTTP, MQTT oder andere. Ich habe mich für das beliebte MQTT Protokoll entschieden, weil es für den Zweck perfekt geeignet ist. Es erfreut sich insbesondere in der IoT-Branche wachsender Beliebtheit und dient dazu, Sensorwerte auszutauschen oder Aktoren anzusteuern.

LoRaWAN Gateways können aufgrund der patentierten Funktechnik und des wenig Consumer-orientierten Marktes sehr teuer sein. Man befindet sich schnell in der 300 € Preisklasse, wenn man sich nach professionellen Gateways umsieht.

Viele Hobbybastler greifen daher zu einfachen sog. “Single-Channel Gateways” zurück. Das sind im Grunde nur einfache LoRa “Clienteinheiten”, wie sie auch auf meinem Waveshare Modul für das Raspberry Pi Pico zum Einsatz kommen. Eine simple Kommunikation auf nur einem einzigen der vielen parallel genutzten LoRa Kanälen ist damit möglich. Allerdings entspricht so ein Betrieb nicht der LoRa Spezifikation und bringt einige Limitierungen mit sich, weshalb mittlerweile vom Betrieb eines solchen Single-Channel Gateways abgeraten wird.

Nachdem ich mich einige Tage lang wenig erfolgreich mit so einer “Frickellösung” herumgeschlagen habe, war mir der Griff in die Tasche doch lieber: Für ca 80 € kann man das TTN Indoor Gateway erstehen, das speziell für nichtprofessionelle Betreiber gedacht zu sein scheint: Es entspricht der LoRa Spezifikation und ist bereits passend für das TTN vorkonfiguriert, sodass man das Gateway nur noch im TTN Dashboard registrieren muss.

TTN - The Things Network

Wie bereits erwähnt, bietet das TTN verschiedene Schnittstellen an, um Sensordaten wieder abzurufen. Dabei können die empfangenen Daten im TTN auch gleich gefiltert oder “umsortiert” / segmentiert werden.

Da die Payload einer LoRa Nachricht nur wenige Bytes groß sein darf (abhängig von der Sendewiederholfrequenz und dem Abstand zum Gateway), bleibt nicht viel Platz für eine Segmentierung der Daten oder ein Labeling. Mit anderen Worten: Statt einen JSON String als Payload zu verschicken, schickt man nur einzelne, rohe Datenbytes. Im Fall meines Sensors: Zwei Datenbytes, um den ADC-Wert des Feuchtesensors abzubilden.

Mittels Filterscript in der TTN Cloud können die zusammengeketteten Bytes zum Beispiel getrennt, neu geordnet oder umgerechnet werden. Ergebnis ist eine JSON-Struktur, die die Daten übersichtlich und menschenlesbar abbildet.

In meinem Fall musste die Byte-Reihenfolge architekturbedingt umgekehrt werden. Das zugehörige Javascript-Snippet sieht so aus:

function decodeUplink(input) {
  return {
    data: {
      moisture_raw: input.bytes[0] | (input.bytes[1] << 8)
    },
    warnings: [],
    errors: []
  };
}

TTN Screenshot

Der Plantmonitor

Kommen wir zum Herzstück meiner Entwicklungsarbeit: Dem “Plantmonitor” Backend.

Was langweilig klingt (Namensfindung ist ein Problem!), beinhaltet den meisten selbst entwickelten Programmcode in diesem Projekt. Der Plantmonitor ist ein in Go geschriebener Daemon, der folgende Aufgaben übernimmt bzw. folgende Funktionen hat:

  • Neue Sensorwerte via MQTT aus dem Things Network empfangen
  • Sensorwerte normalisieren und mittels Kalibrierung in Prozentwerte umrechnen
  • Sensorwerte quantisieren und den Zustand der Erde anhand einer Grenzwertdefinition ermitteln (“Erde feucht”, “Erde trocken”, “Erde nass”, …)
  • Bei einem kritischen Zustand einen festgelegten Empfängerkreis via XMPP-Nachricht alarmieren
  • Erinnerungen bei länger anhaltenden, kritischen Zuständen versenden
  • Bei fehlenden Sensorupdates Alarm schlagen
  • Auf Zustandsabfragen der Nutzer via XMPP-Chat freundlich antworten :)

Nach anfänglichen Schwierigkeiten mit Fehlalarmen funktioniert der Plantmonitor nun wie gewünscht. Er ist als Open Source Projekt unter der MIT-Lizenz frei verfügbar: https://github.com/ThomasLeister/plantmonitor

Zum Plantmonitor-Backend gibt es einen gesonderten Artikel mit ausführlicheren Informationen zum Aufbau und zur Funktionsweise des Quantisierers:

Ein Quantisierer mit Hysterese für meinen LoRaWAB Bodenfeuchtesensor

XMPP-Server und Client

Weil trashserver.net sowieso schon da ist und ich mit meinem Umfeld hauptsächlich via XMPP und “Conversations” am Smartphone kommuniziere, war das XMPP-Protokoll für mich die erste Wahl bei der Überlegung, wie ich benachrichtigt werden wollte.

Für Go gibt es auch schon verschiedene XMPP-Libraries, die sich sehr einfach ansteuern lassen. Das Anbinden eines XMPP-Servers ist somit kein großer Aufwand und schnell erledigt. Ich habe mich übrigens für die Go-Library go-xmpp der Ejabberd-Entwickler “ProcessOne” entschieden: https://github.com/FluuxIO/go-xmpp

XMPP Konversations mit meiner Pflanze “Fritz”

Das XMPP-Modul meines Plantmonitor Backends ist in der Lage, abhängig von der Art der Nachricht (Warnung, Entwarnung, Info) und der Bodenfeuchtigkeit aus verschiedenen vordefinierten Nachrichten zufällig zu wählen und passende GIFs aus der Giphy-Sammlung mitzuschicken. So bringt der Bot ein bisschen Abwechslung ins Spiel. ;-)

Ausblick

Obwohl es aus meiner Sicht noch nicht ganz fertig ist, ist mein Pflanzenüberwachungssystem schon im Einsatz und verrichtet seinen Dienst. Für folgende Features / Verbesserungen ist bereits eine Umsetzung angedacht:

  • Akkubetrieb:
    Die Sensoreinheit wird aktuell noch über ein USB-Netzteil betrieben. Angedacht war eigentlich ein Akkubetrieb, doch die Energiesparmechanismen der Raspberry Pi Pico Plattform sind noch nicht vollumfänglich verstanden. Die Implementierung erweiterter Energiesparmechanismen steht auf meiner To-Do Liste. Dann ist auch ein Akkubetrieb (mit Ladestandsüberwachung) möglich.

  • Gehäuse für die Sensoreinheit:
    Derzeit liegt die Elektronik der Sensoreinheit noch offen. Ich habe vor, mir ein passendes Kunststoffgehäuse zu besorgen oder mir eines zu entwerfen und mittels 3D-Drucker ausdrucken zu lassen.

  • Unterstützung mehrerer Pflanzensensoren im Plantmonitor Backend:
    Derzeit wird nur ein Sensor / die Überwachung einer Pflanze unterstützt. Während die Software schon teilweise auf den Betrieb mehrerer Pflanzen ausgelegt ist, fehlen noch einige Änderungen, um einen Parallelbetrieb mehrerer Sensoren zu unterstützen. Ich begnüge mich vorerst mit der Unterstützung eines einzelnen Sensors, bis das Projekt weiter gereift ist. So vermeide ich unnötige Komplexität schon zu Beginn meines Projekts.