Wenn du Schwierigkeiten hast, deine Pflanzen am Leben zu erhalten, oder ein begeisterter Statistikfan bist, der es liebt, Bodenfeuchtigkeit über Wochen und Monate zu verfolgen und zu analysieren, dann ist dieser Beitrag genau das Richtige für dich. Ich habe ein ausgefeiltes Skript entwickelt, das herkömmliche, analoge Bodenfeuchtigkeitssensoren automatisch kalibriert, deren Werte in Prozent ausgibt und die Daten mittels MQTT auch an Home Assistant usw. überträgt.
Was Du benötigst:
Hardware: * Achtung Amazon Affiliate
Einen Mikrocontroller wie ESP32 oder Arduino. Da der Code keine speziellen Bibliotheken verwendet und abgesehen von der Stromversorgung des Sensors lediglich einen Pin benötigt, ist er auf den meisten Geräten einsetzbar. Falls du jedoch eine batteriebetriebene, langfristige Überwachung deiner Pflanzen anstrebst, empfehle ich den FireBeetle 2 ESP32-E. Mit diesem Modell habe ich beeindruckende Batterielaufzeiten von mehreren Monaten erreicht. Außerdem benötigest du einen Bodenfeuchtigkeitssensor (soil moisture sensor).
Software:
Arduino IDE
Homeassistant + MQTT Broker
* Achtung Amazon Affiliate
Die Verkabelung
Verbinde das Pluskabel (+) mit einem 3V- oder 5V-Pin. Wenn du, wie ich, einen ESP32 verwendest, ist der GPIO35 eine gute Wahl. Bei einem ESP32 im D1-Format oder einem anderen Mikrocontroller wie Arduino, solltest du in den Spezifikationen deines Geräts nach einem geeigneten analogen Pin suchen, denn dieser ist notwendig, um die Daten des Sensors zu empfangen. Stelle sicher, dass du den entsprechenden GPIO-Pin auch im Code anpasst.
Inbetriebnahme
Im oberen Teil des Codes ist es notwendig, die WLAN- und MQTT-Konfigurationen festzulegen. Falls du noch keinen MQTT-Benutzer in Homeassistant hast, erstelle einfach einen neuen Admin-Benutzer in Homeassistant und trage dessen Daten in den Code ein. Beachte, dass die Berechtigungen der Homeassistant-Benutzer auch für MQTT relevant sind.
Energieeffizienz ist entscheidend
Berücksichtige, dass WLAN, Bluetooth und Sensorabfragen viel Energie verbrauchen. Diese Faktoren sind ausschlaggebend, um die Akkulaufzeit deines Geräts deutlich zu verlängern. Im Code kannst du die Variable „sleepTimeSeconds“ anpassen, um zu steuern, wie häufig die Feuchtigkeitsdaten an Homeassistant übermittelt werden. Zu Beginn, besonders während des Debuggings, kannst du niedrigere Werte wählen. Sobald alles reibungslos funktioniert, empfehle ich, die Abfragefrequenz auf einmal pro Stunde oder sogar seltener zu reduzieren. Mit dieser Einstellung kannst du bei einem 3000mAh-Akku eine Laufzeit von etwa sechs Monaten erreichen.
Automatische Kalibrierung
Die meisten Bodenfeuchtigkeitssensoren erfordern eine Kalibrierung, bei der du normalerweise die spezifischen Werte für jeden Sensor manuell ermitteln und im Skript eintragen musst. Dies kann mühsam sein, insbesondere wenn mehrere Sensoren in Betrieb genommen werden sollen, da die Werte je nach Kabellänge, gewähltem Pin und Lötstelle variieren können. Ich habe zur Vereinfachung des Prozesses eine automatische Kalibrierung implementiert. Nachdem der ESP32 mit dem Sensor programmiert wurde, hast du 20 Sekunden Zeit, um die Minimal- und Maximalwerte zu kalibrieren. Das funktioniert am besten, indem der Sensor während des Programmierens durch die Arduino IDE absolut trocken bleibt. Sobald der Programmierungsvorgang abgeschlossen ist warte 2-3 Sekunden und tauche den Sensor binnen 20 Sekunden in Wasser. Auf diese Weise lernt der ESP32 die minimalen und maximalen Werte und zeigt die Feuchtigkeitswerte fortan in Prozent an. Die Kalibrierung bleibt dauerhaft gespeichert, selbst nach einem Stromverlust des ESP32. Sollten 20 Sekunden für die Kalibrierung nicht ausreichen, kannst du die Variable „calibrationPeriod“ im Code anpassen und den Wert erhöhen. Beobachte auch die Konsolenausgabe, denn der ESP32 sollte dir die ermittelten Werte anzeigen.
Rekalibrierung
Nach der erstmaligen Kalibrierung werden die Daten permanent im nichtflüchtigen Speicher (NVS) des ESP32 gesichert. Solltest du eine erneute Kalibrierung des ESP32 wünschen, kannst du das nachstehende Skript verwenden. Dieses Skript bereinigt den nichtflüchtigen Speicher des ESP32 vollständig. Nachdem der Speicher gelöscht wurde, kannst du den ursprünglichen Code des Pflanzensensors wieder aufspielen und den Kalibrierungsprozess von Neuem beginnen.
#include <Arduino.h>
#include <Preferences.h>
Preferences preferences;
void setup() {
Serial.begin(115200);
// Initialisierung des Preferences-Speichers
preferences.begin("moisture", false);
// Überprüfen, ob die Kalibrierungsdaten bereits gelöscht wurden
bool isCleared = preferences.getBool("isCleared", false);
if (!isCleared) {
// Löschen des Speicherbereichs, wenn er noch nicht gelöscht wurde
Serial.println("Lösche Kalibrierungsdaten...");
preferences.clear();
// Setzen der Flagge, dass die Daten gelöscht wurden
preferences.putBool("isCleared", true);
// Bestätigung der Löschung
Serial.println("Kalibrierungsdaten wurden zurückgesetzt.");
} else {
Serial.println("Kalibrierungsdaten wurden bereits gelöscht.");
}
// Schließen der Preferences
preferences.end();
// Warten, um die Ausgabe im seriellen Monitor zu sehen
delay(2000);
// Neustart oder weiteren Code ausführen
Serial.println("System wird neu gestartet.");
ESP.restart();
}
void loop() {
// Der Loop-Block bleibt leer, da alle Aktionen im Setup-Block durchgeführt werden.
}
Der Code für die Bodenfeuchtigkeitsüberwachung
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Preferences.h>
const int moistureSensorPin = 35; // Pin-Nummer des Feuchtigkeitssensors
Preferences preferences; // Präferenzenspeicher für Kalibrierungswerte
int airValue; // Kalibrierungswert für trockene Umgebung
int waterValue; // Kalibrierungswert für nasse Umgebung
unsigned long startTime; // Startzeit für die Kalibrierungsphase
const unsigned long calibrationPeriod = 20000; // Kalibrierungszeit in Millisekunden (20 Sekunden)
const unsigned long sleepTimeSeconds = 20; // Schlafzeit des Sensors in Sekunden (hier auf 20 Sekunden gesetzt)
// WLAN-Informationen (ersetzen Sie die Werte durch generische oder entfernen Sie sie)
const char* ssid = "[SSID]"; // WLAN-SSID
const char* password = "[PASSWORT]"; // WLAN-Passwort
const char* mqttServer = "[MQTT_SERVER_IP]"; // MQTT-Server-Adresse
const char* mqttUser = "[MQTT_BENUTZERNAME]"; // MQTT-Benutzername
const char* mqttPassword = "[MQTT_PASSWORT]"; // MQTT-Passwort
const char* mqttTopic = "pflanzen/pflanze01"; // MQTT-Topic für die Übertragung der Sensorwerte
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200); // Starten der seriellen Kommunikation
preferences.begin("moisture", false); // Öffnen des Präferenzenspeichers für den Feuchtigkeitssensor
// Laden der gespeicherten Kalibrierungswerte
airValue = preferences.getInt("airValue", 4095);
waterValue = preferences.getInt("waterValue", 0);
bool isCalibrated = preferences.getBool("isCalibrated", false);
// Start der Kalibrierung, falls noch nicht kalibriert
if (!isCalibrated) {
Serial.println("Kalibrierung beginnt - Bitte den Sensor in unterschiedliche Feuchtigkeitszustände bringen.");
startTime = millis();
} else {
Serial.println("Kalibrierung übersprungen.");
}
setup_wifi(); // Einrichten der WiFi-Verbindung
client.setServer(mqttServer, 1883); // Konfiguration des MQTT-Clients
}
void loop() {
bool isCalibrated = preferences.getBool("isCalibrated", false);
// Verbindung zum MQTT-Server wiederherstellen, falls notwendig
if (!client.connected()) {
reconnect();
}
client.loop();
// Durchführung der Sensor-Kalibrierung
if (!isCalibrated && millis() - startTime < calibrationPeriod) {
int sensorValue = analogRead(moistureSensorPin); // Lesen des Sensorwerts
waterValue = max(waterValue, sensorValue); // Aktualisieren des Wasserwerts
airValue = min(airValue, sensorValue); // Aktualisieren des Luftwerts
Serial.println("Kalibrierung: Luftwert = " + String(airValue) + ", Wasserwert = " + String(waterValue));
} else if (millis() - startTime >= calibrationPeriod && !isCalibrated) {
// Speichern der Kalibrierungswerte
preferences.putInt("airValue", airValue);
preferences.putInt("waterValue", waterValue);
preferences.putBool("isCalibrated", true);
}
// Messung und Übermittlung der Bodenfeuchtigkeit, falls kalibriert
if (isCalibrated) {
int sensorValue = analogRead(moistureSensorPin);
int moisturePercent = waterValue == airValue ? 0 : map(sensorValue, airValue, waterValue, 100, 0);
moisturePercent = constrain(moisturePercent, 0, 100); // Sicherstellen, dass der Wert zwischen 0 und 100 liegt
Serial.println("Bodenfeuchtigkeit: " + String(moisturePercent) + "%");
char msg[50];
sprintf(msg, "%d", moisturePercent); // Formatieren der Nachricht
client.publish(mqttTopic, msg); // Senden der Bodenfeuchtigkeit an den MQTT-Server
client.loop();
delay(10); // Kurze Verzögerung, um sicherzustellen, dass die Nachricht gesendet wurde
// Einstellen des Schlafmodus für Energieeinsparung
esp_sleep_enable_timer_wakeup(sleepTimeSeconds * 1000000);
esp_deep_sleep_start();
}
}
void setup_wifi() {
delay(10);
Serial.println("Verbinde zu WiFi...");
WiFi.begin(ssid, password); // Verbindung zum WLAN
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi verbunden.");
}
void reconnect() {
// Wiederverbindung zum MQTT-Server versuchen
while (!client.connected()) {
Serial.print("Versuche, eine MQTT-Verbindung herzustellen...");
if (client.connect("ArduinoClient", mqttUser, mqttPassword)) {
Serial.println("verbunden");
} else {
Serial.print("fehlgeschlagen, rc=");
Serial.print(client.state());
Serial.println(" Versuche es in 5 Sekunden erneut");
delay(5000);
}
}
}
Home Assistant Integration
Nachdem du die MQTT-Daten korrekt im Code hinterlegt und eine MQTT Community definiert hast, musst du den Sensor in der Home Assistant Konfigurationsdatei configuration.yaml
hinzufügen. Füge den folgenden Code in die Konfigurationsdatei ein, falls du noch keine anderen Sensoren konfiguriert hast. Dabei ist es wichtig, dass du die im Code definierte MQTT Community angibst. Den Namen des Sensors kannst du nach deinen Wünschen wählen.
mqtt: # MQTT-Schnittstellenkonfiguration
sensor: # Definiert einen oder mehrere Sensoren
- name: "Pflanze 1 Bodenfeuchtigkeit" # Name des Sensors, der im System angezeigt wird
state_topic: "pflanzen/pflanze01" # MQTT-Topic, von dem der Sensor seine Daten bezieht
unit_of_measurement: '%' # Einheit der Messung für die Sensorwerte, hier Prozent
Anschließend gehst du am besten in die Entwicklerwerkzeuge, prüfst die Konfiguration und startest Home Assistant neu.
Nach dem Neustart solltest du deinen Pflanzensensor in den Entitäten finden.
Fehlerbehebung
Das Skript ist so konzipiert, dass es in der Konsole laufend Rückmeldungen über seine Aktivitäten gibt. Hier kannst du überprüfen, ob die WLAN-Verbindung erfolgreich aufgebaut wurde und ob MQTT korrekt funktioniert. Während der Kalibrierungsphase werden die Rohdaten des Sensors angezeigt, gefolgt von den berechneten Feuchtigkeitswerten. Diese Informationen sind äußerst hilfreich, um eventuelle Probleme schnell zu identifizieren. Sollte trotz korrekter Konfiguration und erfolgreicher Ausgaben in der Konsole keine Daten in Home Assistant sichtbar sein, empfiehlt es sich, einen Blick in das Log des MQTT-Brokers zu werfen.
3D Druck Gehäuse
Solltest du meine Akkus und den FireBeetle 2 ESP32-E verwenden habe ich dir dafür auch ein Case wo der ESP32 zumindest etwas vor Erde geschützt ist. Schau mal hier vorbei: https://makerworld.com/en/models/159185
Schreibe einen Kommentar