Ein Pflanzenwächter für die Fensterbank

Heute möchte ich euch ein neues interessantes mehrteiliges Projekt mit dem vielseitigen und leistungsfähigen ESP 32 vorstellen. Wir bauen uns einen Pflanzenwächter für unsere heimischen Pflanzen. Dieser soll während wir unsere Aufmerksamkeit unseren spannenden Elektronikprojekten widmen, den Wassergehalt der Pflanzenerde überwachen und uns darüber informieren, wenn die Bodenfeuchte sinkt. Dazu hat unser Pflanzenwächter eine LED-Ampel, die bei feuchter Erde grün leuchtet und bei trockener Erde über gelb rot wird. Bevor wir jedoch mit dem Projekt beginnen, müssen wir uns jedoch noch, vor dem eigentlichen Start des Projektes einige Gedanken machen. Dies betrifft insbesondere den Einsatz des Pflanzenwächters. Da unser Pflanzenwächter die Feuchtigkeit der Erde über eine kapazitive Nahfeldmessung bestimmt, ist es notwendig, dass die Feuchtigkeit in unmittelbarer Nähe des Sensors gespeichert wird. Während i.d.R. normale (Blumen-)Pflanzenerde aus dem Baumarkt oder dem Supermarkt diese Bedingung erfüllt, ist dies bei u.a. Hydrokultursubstraten oder Orchideensubstrat nicht der Fall! Daher:

Dieses Projekt ist für Hydrokulturpflanzen oder Luftwurzlerpflanzen (wie z.B. Orchideen) nicht geeignet!

Außerdem haben Pflanzen ganz unterschiedliche Anforderungen an Ihre Bewässerung. Während mache Pflanzen eine dauerhafte Grundfeuchte (meistens keine Staunässe) bevorzugen, sind mache dagegen eher trockenliebend und möchten nur selten gegossen werden. Da die individuellen Anforderungen der Pflanze unser Pflanzenwächter nicht kennen kann, liegt die Interpretation der nötigen Aktionen (gießen oder nicht gießen) auf die (Ampel-) Anzeige des Pflanzenwächters ausschließlich in der Hand des botanisch kundigen Anwenders 😊. 

Der Pflanzenwächter ist daher kein Ersatz für eine verantwortungsvolle- und pflanzengerechte Pflege deiner Pflanzen!

Im weiteren Verlaufe des Projektes und mit größer werden dem Umfang werden wir weitere Sensoren anbinden und natürlich auch Komfortfunktionen hinzufügen. Lasst euch überraschen!
Aber fangen wir mit der Basis an. Schauen wir uns die Bauteile an, die wir für unseren Pflanzenwächter für den Anfang brauchen:

  • 1 x LED Farbe Grün (560nm); 5 mm
  • 1x LED Farbe Gelb (605nm); 5 mm
  • 1x LED Farbe Rot (633nm); 5 mm
  • 6x130kΩ Widerstand Toleranz ±1%;
  • 6x 47kΩ Widerstand Toleranz ±1
  • 3x 150Ω Widerstand Toleranz ±1%;
  • 1x Kapazitiver Feuchtesensor
  • 1x ESP32-38Pin Variante Generic; Typ NodeMCU-32S; Beinchen 38;
  • 1x YwRobot Breadboard Spannungsversorgung

Wir verdrahten die Komponenten wie folgt:

Schaltung

 

Die 150 Ohm Widerstände werden als Vorwiderstände für die LEDs genutzt. Der 130 KOhm bildet zusammen mit dem 47 KOhm Widerstand ein Spannungsteiler für den Analogausgang des Feuchtigkeitssensors.

Wir laden folgenden Code auf unseren ESP 32 hoch:

 

#include <driver/adc.h>

// Portedefinierung Led's
#define LED_Rot     5     // Rote LED 
#define LED_Gelb    14    // Gelbe LED
#define LED_Gruen   15    // Gruene LED

// LED PWM Einstellungen
#define PWMfreq 5000  // 5 Khz basisfrequenz
#define PWMledChannelA  0
#define PWMledChannelB  1
#define PWMledChannelC  2
#define PWMresolution  8 // 8 Bit Resolution
#define ADCAttenuation ADC_ATTEN_DB_11  //ADC_ATTEN_DB_11 = 0-3,6V  Dämpung ADC Einstzellung
#define MaxSensors 1


struct MoistureSensorCalibrationData
{
  int Data[MaxSensors * 2] = {0, 0}; // Calibration Data für Feuchtigkeitssensor. Bitte Projekt Text beachten und Werte ensprechend anpassen
};

struct MoistureSensorData
{
  byte Percent[MaxSensors] = {0};  // Feuchtigkeitssensordaten in Prozent
};

//Global Variables
MoistureSensorCalibrationData MCalib;
MoistureSensorData MMeasure;
byte AttachedMoistureSensors; // Detected Active Moisture Sensors (Count)

void setup() {
  // initialize serial communication at 9600 bits per second:
  pinMode(LED_Rot, OUTPUT);
  pinMode(LED_Gelb, OUTPUT);
  pinMode(LED_Gruen, OUTPUT);
  Serial.begin(115200);
  ledcSetup(PWMledChannelA, PWMfreq, PWMresolution);
  ledcSetup(PWMledChannelB, PWMfreq, PWMresolution);
  ledcSetup(PWMledChannelC, PWMfreq, PWMresolution);
  ledcAttachPin(LED_Rot, PWMledChannelA);   // attach the channel to the GPIO to be controlled
  ledcAttachPin(LED_Gelb, PWMledChannelB);
  ledcAttachPin(LED_Gruen, PWMledChannelC);
  SetLedConfig(20, 20, 20);
  AttachedMoistureSensors = DetectMoistureSensors();
  Serial.println(F("Systemkonfiguration:"));
  Serial.print(AttachedMoistureSensors);
  Serial.println(F(" Bodenfeuchtigkeitsensor(en)"));
}

byte DetectMoistureSensors ()
{
#define MinSensorValue 100
  byte Detected = 0;
  for (int i = 0; i < MaxSensors; i++)
  {
    int MSensorRawValue = ReadMoistureSensorVal(i);
    if ( MSensorRawValue > MinSensorValue) {
      Detected++;
    } else {
      break;
    }
  }
  if (Detected < 1)
  {
    Serial.println(F("Keine Bodenfeuchtigkeitssesoren erkannt. System angehalten."));
    esp_deep_sleep_start();
    while (1) {}
  }
  return Detected;
}

bool SetLedConfig(byte Red, byte yellow, byte green)
{
  ledcWrite(PWMledChannelA, Red); // Rote LED
  ledcWrite(PWMledChannelB, yellow); // Gelbe LED
  ledcWrite(PWMledChannelC, green); // Gruene LED
  return true;
}

int ReadMoistureSensorVal(byte Sensor)
{
  int ReturnValue, i;
  long sum = 0;
#define NUM_READS 6
  adc1_config_width(ADC_WIDTH_BIT_12);   //Range 0-4095
  switch (Sensor)
  {
    case 0:
      {
        adc1_config_channel_atten(ADC1_CHANNEL_0, ADCAttenuation);
        for (i = 0; i < NUM_READS; i++) { // Averaging algorithm
          sum += adc1_get_raw( ADC1_CHANNEL_0 ); //Read analog
        }
        ReturnValue = sum / NUM_READS;
        break;
      }
  }
  return ReturnValue;
}

bool GetMoistureData()
{
  bool ReadisValid = true;
  for (int i = 0; i < AttachedMoistureSensors; i++)
  {
    if ((MCalib.Data[i] == 0) || (MCalib.Data[i + 1] == 0)) // MinADC Value maxADC ADC Value
    {
      ReadisValid = false;
      return ReadisValid;
    }
    int RawMoistureValue = ReadMoistureSensorVal(i);
    RawMoistureValue = MCalib.Data[i + 1] - RawMoistureValue;
    RawMoistureValue = MCalib.Data[i] + RawMoistureValue;
    MMeasure.Percent[i] = map(RawMoistureValue, MCalib.Data[i], MCalib.Data[i + 1], 0, 100);
    if (MMeasure.Percent[i] > 100 ) {
      ReadisValid = false;
    }
  }
  return ReadisValid;
}

// Main Loop
void loop()
{
  if (GetMoistureData())
  {
    Serial.print(F("Feuchtigkeitswert Sensor 1 in Prozent :"));
    Serial.print(MMeasure.Percent[0]);
    Serial.println(F(" %"));
    if (MMeasure.Percent[0] > 50)
    {
      SetLedConfig(0, 0, 20);
    }
    else if (MMeasure.Percent[0] > 10)
    {
      SetLedConfig(0, 255, 0);
    }
    else
    {
      SetLedConfig(255, 0, 0);
    }
  }
  else
  {
    Serial.print(F("Bodenfeuchtigkeitssensor nicht kalibriert.Bitte kalibrieren. RohDaten des Sensors 1:"));
    Serial.println(ReadMoistureSensorVal(0));
    SetLedConfig(20, 20, 20);
  }
  delay(1000);        // delay between reads for stability
}

 

 

Als letzten Schritt müssen wir nun die Kalibrierung unseres Feuchtigkeitssensors durchführen. Die Kalibrierung des Sensors legt fest, was als trockene Erde (Wassergehalt 0%) und was nasse Erde (Wassergehalt 100%) erkannt wird. Dazu strecken wir den Feuchtigkeitssensor als erstes in absolut trockene Erde und lassen uns die Sensor-Rohdaten auf der seriellen Schnittselle ausgeben:

Wert 1: (Trocken)

Bodenfeuchtesensor nicht kalibriert

Wir notieren uns den Wert (2276) und bewässern nun die Erde solange, bis sie komplett! durchnässt ist und kein Wasser mehr ausnehmen kann. Wir notieren uns den Wert 2: (Nasse Erde) (1648)

Wert bei Nässe

 

Wir addieren zu dem ersten Wert 2276, 10 dazu und ziehen von 1648, 10 ab. Es ergeben sich daraus die Werte 2286 und 1638

Wir tragen die Werte in unseren Code ein:

struct MoistureSensorCalibrationData

{
int Data[MaxSensors*2] = {1638,2286};
};

Und laden den Code erneut hoch.

Wir erhalten folgende Ausgabe:

Ausgabe Bodenfeuchte

 

Gleichzeitig zeigt unsere Led „Ampel“ grün an. Dabei bedeuten die Farben:

Grün: Feuchtigkeit hoch.

Gelb: Feuchtigkeit mittelmäßig. 

Rot: Trocken.

Viel Spaß beim Nachbauen und bis zum nächsten Teil der Serie.

Letzter Artikel Instant-Messenger für ESPs und Arduinos - Teil 1
Neuer Artikel Zugangsbeschränkung zu Geräten per Contactless Card mit der NodeMCU und dem RC522 Modul Teil 5 – Sicherheit.

Kommentar

R.R - August 4, 2019

ESP 32 Pflanzenwächter Code mit Fehlermeldungen!
Jetzt habe ich es geschafft, den ESP mit gedrückter Boot Taste etwas vorzugeben. Nun will ich den Planzenwächter Teil I anwenden und habe gleich nach dem Überprüfen die Fehlermeldungen : Stray 302, Stray 240 in der letzten Zeile.
Hat jemand einen Tipp, wie man den Codefehler schnell rauskriegt? Vielleicht gibt es jemanden, der diesen Fehler gar kennt?
Ich hoffe nicht, dass ich der einzigste bin, dem sowas passiert. So im Rückblick ginbt es immer wieder so komische Fehler. Geht es der Gemeinde ähnlich?
Euch allen einen Guten Wochenanfang

R.R - August 4, 2019

ESP 32 Pflanzenwächter Code mit Fehlermeldungen!
Jetzt habe ich es geschafft, den ESP mit gedrückter Boot Taste etwas vorzugeben. Nun will ich den Planzenwächter Teil I anwenden und habe gleich nach dem Überprüfen die Fehlermeldungen : Stray 302, Stray 240 in der letzten Zeile.
Hat jemand einen Tipp, wie man den Codefehler schnell rauskriegt? Vielleicht gibt es jemanden, der diesen Fehler gar kennt?
Ich hoffe nicht, dass ich der einzigste bin, dem sowas passiert. So im Rückblick ginbt es immer wieder so komische Fehler. Geht es der Gemeinde ähnlich?
Euch allen einen Guten Wochenanfang

Tobias - Juli 15, 2019

Hallo Jörg,

Die Idee mit der Ansteuerung für eine automatische Bewässerung währe zwar eine konsequente Erweiterung , würde jedoch den Rahmen des Projektes hier sprengen. Falls du weitergehende Tipps dazu bekommen möchtest, schreibe bitte an AZ-Delivery mit bitte um Weiterleitung an mich. Dann gehe ich gerne zu diesem Thema noch auf Details ein.

Jörg - Juli 5, 2019

Hi Tobias,
dein Hinweis auf ein gewisses Grundwissen der Programmierung ist schon nicht falsch.
Zumindest weiß ich in der Zwischenzeit auch wie das mit der Belegung der Pins in der Programmierung zu erkennen ist. Wenigstens ein kleiner Lichtblick für mich…..
Denn in meinem Alter will ich nicht mehr großartig anfangen irgend welche Programmiersprachen zu lernen, das Grundlegende des Code verstehe ich soweit ich weiß um was es sich dabei handeln soll….
Jetzt aber gleich noch eine ganz einfache Frage:
Ich habe ein ähnliches Projekt aber das läuft auf einer separaten Hardware und nennt sich: Gies-O-Mat mit AVR
Vom Prinzip her das gleiche Grundprinzip, kapazitive Feuchtigkeitssensoren zur Ermittlung der Erdfeuchte. Nur kann dieses Projekt nun auch noch Relais ansteuern und somit die Pflanzen selbständig gießen…….
Denkst du dass du das vielleicht auch noch implementieren könntest, dann wäre das ganze Projekt ja absolut unschlagbar ?!?!?

Tobias - Juli 1, 2019

Hallo Jörg,

Erst einmal vielen Dank für die Beantwortung der Fragen bzgl. des Treibers. Du liegst natürlich direkt richtig. Der Treiber wird automatisch eingebunden. Bezüglich des Schaltbildes würde ich dich bitten, etwas Geduld zu haben. Ich werde dieses bei Gelegenheit dann auf meiner GIT-Hub Seite auf https://github.com/kuchto auf der ich die Projekte ebenfalls einstelle, veröffentlichen. Dieses Projekt setzt aber Erfahrung in der Technik an sich als auch in der Programmierung voraus.

Knut Dorendorff - Juli 1, 2019

Hallo Jörg. Vielen Dank für die Hinweise. Ich habe zwar noch nicht die einzelnen Teile zusammen gesteckt, aber zunächst hatte ich auch mit der Ansicht Probleme. Allerdings muss du berücksichtigen, dass auf dieser Seite nur ein Sensor angeschlossen ist, aber die Vorbereitung für weitere 5 Sensoren schon verbaut sind, aber noch nicht genutzt werden. Siehe am unteren Bild die Widerstände. Wenn Du in den dritten Teil gehst sollte es sich erklären.
Schauen wir mal .
Gruß Knut

Jörg - Juni 28, 2019

Hallo Knut,
das Problem mit dem Treiber hat sich, denk ich mal von selbst erledigt.
Sobald man nämlich das Board ESP32xxxxx verwendet, wird auch automatisch der richtige Treiber bereit gestellt.
Zumindest habe ich das bisher bei der Überprüfung beim Kompilieren festgestellt.
Falls das nicht stimmen sollte:
Bitte nicht gleich alle mit dem Vorschlaghammer auf mich einschlagen ;-))))
Und in einem anderem Thread habe ich lesen können dass dieser Sketch nicht mit dem Lolin V3 kompatibel ist, somit hat sich diese Frage auch schon von selbst aufgelöst.
Das Einzige:
Ich kann die Schaltung nach wie vor nicht richtig erkennen….
Gibt es hierfür einen schöneren Steckplan oder gar Schaltplan?

Jörg

Knut Dorendorff - Juni 28, 2019

Halli Hallo,
eine tolle Sache. Wie komme ich an Library Driver/adc.h ?

Gruss Knut.

Knut Dorendorff - Juni 28, 2019

Große Klasse. Allerdings habe ich auch das Problem wie Jörg, dass die Library Driver/adc.h nicht gefunden wird. Wo bekomme ich die als Zip?

Gruß Knut

Jörg - Juni 26, 2019

Hallo, eine sehr schöne Schaltung welche ich gerne auch nachbauen möchte.
Leider bin ich nicht gerade der Programmierprofi und habe auch mit der Beschaltung an sich ein kleines Problem. Ein paar Fragen hierzu:
1.: Gibt es eine Art Schaltplan für diese Schaltung, ich kann das Bild sehr schlecht erkennen ?
2.: Kann man diese Schaltung auch mit einem Lolin NodeMcu V3 nachbauen ?
3.: Wo finde ich den Treiber <driver/adc.h> ?

Jörg

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe