A plant keeper for the windowsill part 2 - mobile app

Hello and welcome to the second part of our plant guardian series.

Although our plant keeper is already working quite well, as a maker I find it a bit awkward to check the led “traffic light” from time to time to see if my plant needs watering. I would find it much more practical if I just had to take a quick look at the cell phone at any time and anywhere to know how the plant was doing at home.

But before anyone thinks now: This is not possible, it is far too complicated, let's take a closer look at the App Store. There is an APP already designed for our purposes, which we only have to adjust a little here, because we have to add a little code and then put the whole thing together! After that, our APP works exactly as we want it.

So, let's go! As a first step, we download the “Blynk” app from the App Store onto our mobile phone. The APP itself is free of charge and can also be operated for our application described here in the second part of the blog without any additional costs for the app.

However, the “2000 energy” units of the free version may no longer be sufficient for further expansion of the app within the blog series.

Regardless of the expansion level, there are costs for data transmission from the plant keeper to the cell phone. Please take these costs into account when building the project!

So after we have downloaded the Blynk app from the store and started it for the first time, we first have to create an account. To do this, we tap on "Create New Account"

We register with our own email address and assign a password:

Then we click on new project:

We end up in the dialogue about creating a new project. The basic data of the project must be entered here, e.g. the project name, our ESP32 development platform and the desired connection form. Various connection parameters can be given, such as Bluetooth or WLAN. However, in order to be able to receive data while on the move, the GSM connection type must be selected. Below are the settings I chose for my project:

We confirm the information with "Create" and end up in an empty project. We add our first active element to our app using the "Plus" symbol in the title bar:

We select the element "Gauge" and configure the element. First we give a NAME for the element. I chose the name “Soil Moist Plant 1”.

Then we select "V1" as the input variable, 0 as the minimum value and 100 as the maximum value. We add a% to the "LABEL" field and set "Push" as the reading rate. Any color and font size can be chosen for the design.

We confirm the settings with the arrow on the left, and then return to the main view of the APP:

We can now close the app again, because we now have to adapt our ESP code to our APP. To do this, we first install the latest version of the Blynk library in the Arduino via the library manager:

Then we paste the following code into the IDE:


#include <driver/adc.H>
#include <WiFi.H>
#include <WiFiClient.H>
#include <BlynkSimpleEsp32.H>

// Led port definition
#define LED_Red     18    // Red LED 
#define LED_Yellow    14    // Yellow LED
#define LED_Green   15    // Green LED

// LED PWM settings
#define PWMfreq 5000  // 5 kHz base frequency
#define PWMledChannelA  0
#define PWMledChannelB  1
#define PWMledChannelC  2
#define PWM resolution  8 // 8 bit resolution

#define ADCAttenuation ADC_ATTEN_DB_11  // ADC_ATTEN_DB_11 = 0-3.6V damping ADC
#define MoisureSens_Poll_Interval 60000  // Interval between two soil moisture measurements in milliseconds
#define MaxSensors 1

#define BLYNK_PRINT Serial
// # define BLYNK_DEBUG

struct MoistureSensorCalibrationData   {     int Data[MaxSensors*2] = {1650,2840};  // Calibration data for moisture sensor. Please note the project text and adjust the values ​​accordingly    };

struct MoistureSensorData   {     byte Percent[MaxSensors] = {0};       // Moisture sensor data in percent      byte Old_Percent[MaxSensors] = {0};   // Previous _ Moisture sensor data in percent (purpose: save data quantity.)   };
// Global Variables
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Enter the Blynk app according to the instructions for the Auth Token (email).

// Your WiFi access data.
char ssid[] = "WLANSSID";
char passport[] = "XXXXXXXX";  // Set Password to "" for open networks.

MoistureSensorCalibrationData MCalib;
MoistureSensorData MMeasure;
byte AttachedMoistureSensors; // Detected Active Moisture Sensors (Count) 
unsigned long Moisure_ServiceCall_Handler = 0;  // Delay Variable for Delay between Moisure Readings

void set up() {   pinMode(LED_Red,OUTPUT);   pinMode(LED_Yellow,OUTPUT);   pinMode(LED_Green,OUTPUT);   Serial.begin(115200);   // initialize serial communication at 115200 bits per second:   ledcSetup(PWMledChannelA, PWMfreq, PWM resolution);   ledcSetup(PWMledChannelB, PWMfreq, PWM resolution);   ledcSetup(PWMledChannelC, PWMfreq, PWM resolution);   ledcAttachPin(LED_Red, PWMledChannelA);   // attach the channel to the GPIO to be controlled   ledcAttachPin(LED_Yellow, PWMledChannelB);   ledcAttachPin(LED_Green, PWMledChannelC);   SetLedConfig(255,255,255);   Serial.println(F("System configuration:"));   AttachedMoistureSensors = DetectMoistureSensors();   Serial.print(AttachedMoistureSensors);   Serial.println(F("Soil moisture sensor (s)"));   Serial.print(F("Connection to WLAN"));   delay(500);   Blynk.begin(auth, ssid, passport);  // Initalize WiFi connection over Blync Library   Serial.println(F(" successful."));   SetLedConfig(0,0,0);   Run_MoistureSensors(true);
}    byte DetectMoistureSensors ()   {   #define MinSensorValue 100     byte Detected = 0;   for (int i = 0;i < MaxSensors;i++)     {     int MSensorRawValue = ReadMoistureSensor_Raw_Val(i);     if ( MSensorRawValue > MinSensorValue) { Detected++; } else {break;}     }   if (Detected < 1)     {        Serial.println(F("No soil moisture sensors detected. System stopped."));       esp_deep_sleep_start();       while(1) {}     }      return Detected;   }

bool SetLedConfig(byte Red,byte yellow,byte green)
ledcWrite(PWMledChannelA, Red); // Red LED 
ledcWrite(PWMledChannelB, yellow); // Yellow LED
ledcWrite(PWMledChannelC, green); // Green LED
return true;

int ReadMoistureSensor_Raw_Val(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 Get_Moisture_DatainPercent()
 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= ReadMoistureSensor_Raw_Val(i);   RawMoistureValue= MCalib.Data[i+1] - RawMoistureValue;   RawMoistureValue=MCalib.Data[i] + RawMoistureValue;   //Serial.println(MCalib.Data[i]);   //Serial.println(MCalib.Data[i+1]);   //Serial.println(RawMoistureValue);   MMeasure.Percent[i] = map(RawMoistureValue,MCalib.Data[i],MCalib.Data[i+1], 0, 100);   if (MMeasure.Percent[i] > 100 ) { ReadisValid = false; }   }
 return ReadisValid;

void Run_MoistureSensors (bool Init)   // HauptFunktion zum Betrieb der Bodenfeuchtesensoren
byte MinSensValue = 100;
if ((millis() - Moisure_ServiceCall_Handler >= MoisureSens_Poll_Interval) | (Init))   {    Moisure_ServiceCall_Handler = millis();    if (Get_Moisture_DatainPercent())  // Gültige aktuelle Daten Empfangen    {       for (int i = 0;i < AttachedMoistureSensors;i++)         {            if (MMeasure.Percent[i] != MMeasure.Old_Percent[i])             {               MMeasure.Old_Percent[i] = MMeasure.Percent[i];               if (MMeasure.Percent[i] < MinSensValue ) { MinSensValue = MMeasure.Percent[i]; };               Serial.print(F("Feuchtigkeitswert Sensor 1 in Prozent :"));               Serial.print(MMeasure.Percent[0]);                   Serial.println(F(" %"));                if (i == 0)  {Blynk.virtualWrite(V1,MMeasure.Percent[i]);  } // Aktualisiere Handywerte             }                    }       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  // Keine gültigen Daten empfangen    {      Serial.print(F("Bodenfeuchtigkeitssensor nicht kalibiert.Bitte kalibieren. RohDaten des Sensors 1:"));      Serial.println(ReadMoistureSensor_Raw_Val(0));      SetLedConfig(255,255,255);    }    }
}    // Main Loop
void loop() 
 Blynk.run();   // Execute Blync Basic- Functions 


Jetzt müssen wir noch unseren Code ein wenig anpassen. Zum einem muss im Code die WLAN Credentials (SSID und Passwort) an das heimische WLAN angepasst werden:

// Deine WiFi Zugangsdaten.
char ssid[] = "WLANSSID";
char pass[] = "XXXXXXXX"; // Set Password to "" for open networks.

Zum anderen haben wir bei der Anlage unseres Projektes in der AP ein Authentification Token zugesendet bekommen:

Dieses Token tragen wir im Code in der Zeile:

//Global Variables

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // Hier lt. Anleitung Auth Token dere Blynk App eintragen (E-Mail).


ein und kompilieren den Code. Anschließend laden wir Ihn aus unseren ESP hoch. Wir sollten nun auf der seriellen Schnittstelle eine ähnliche Ausgabe wie diese bekommen:

Nun kann die Blynk App auf dem Handy gestartet werden. Nach der Anmeldung und starten der neu erstellten Anwendung zeigt uns die App den aktuellen Feuchtigkeitswert des Bodenfeuchtesensors in Prozent an.


Weitere Informationen über die Blynk APP und deren Verwendung in Controllern findest du unter:

• Blynk Einführung -> https://www.blynk.cc/getting-started
• Dokumentation -> http://docs.blynk.cc/
• Sketch Generator -> https://examples.blynk.cc/
• Aktuellste Blynk Bibliothek -> https://github.com/blynkkk/blynk-library/releases/download/v0.6.1/Blynk_Release_v0.6.1.zip
• Aktuellster Blynk server -> https://github.com/blynkkk/blynk-server/releases/download/v0.41.5/server-0.41.5.jar
• Blynk Startseite -> https://www.blynk.cc

Ich wünsche viel Spaß beim Nachbauen, und bis zum nächsten Mal.


Projekte für fortgeschritteneSensorsSmart home

1 comment



Hallo, es wird hier von begrenztem Datenvolumen gesprochen!
Wo liegt hier die Begrenzung?
Am Datenvolumen des Handy´s oder am Serverdienst des Blynk-Token.
Mit welcher Datenmenge muss man rechnen, wenn alle 30 Min. bei voller Bestückung gesendet wird?

Danke schon mal
Gruß Max

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN