ESP8266 SoilMoisture Gardenproject

if (language == english){
scrollDown;
}

Hallo zusammen,
ich bin noch recht neu in Sachen Blynk. Ich habe das Prinzip ungefähr verstanden aber komme hier nicht mehr weiter:
Projekt Gartenbewässerung
Ich habe in Blynk zwei Knöpfe, einer für manuelles bewässern und einer für den Automatikmodus.
Im Automatikmodus soll selbständig geschaltet werden wenn der Wert ´Feuchte<=400´ist.
Wenn der Wert darunter ist, schaltet die Pumpe einmalig ein und dann nicht mehr.
Wenn der Wert darüber ist und unter 400 fällt, passiert nichts.

Kann mir jemand behilflich sein?

Vielen Dank

Code

First of all I would like to say that my english is not the best and I partly used a translator.

Project Garden Irrigation
I have two buttons in Blynk, one for manual watering and one for the automatic mode.
In the automatic mode I want to switch automatically if the value is ‘Humidity<=400’.
If the value is below that, the pump will switch on once and then not anymore.
If the value is above and falls below 400, nothing happens.

Can anyone help me?

Thanks a lot

Code

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Blynk.h>

#define pumpe 5
#define sensorPin A0

char auth[] = "TOKEN";
char ssid[] = "WLAN";
char pass[] = "CODE";
int Feuchte = 46;
int sensorWert = 400;
WidgetLED led3(V3);
WidgetLED led4(V4);

BLYNK_WRITE(V1){
    int autoBTN = param.asInt();
    Serial.print(autoBTN);
    
    if(autoBTN==1){
      led4.on();
      led3.off();
      Automatikbetrieb();
    }
    if(autoBTN==0){
      led3.on();
      led4.off();
    }
}

BLYNK_WRITE(V0){
    int manualBTN = param.asInt();
    Serial.print(manualBTN);
    
    if(manualBTN==1){
      led4.on();
      led3.off();
      Pumpenstart();
    }
    if(manualBTN==0){
      led3.on();
      led4.off();
    }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(A0, INPUT);
  pinMode(5, OUTPUT);
  pinMode(V2, OUTPUT);
  pinMode(V1, INPUT);
  WidgetLED led3(V3);
  //pinMode(V3, Feuchte);
  Serial.begin(9600);
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Blynk.begin(auth, ssid, pass);
}


void loop() {
  Blynk.run();
  WidgetLED led3(V3);
  WidgetLED led4(V4);
}

/*
 * ------Funktionsbau unterhalb--------
 * 
*/

void Automatikbetrieb(){
  sensorWert = analogRead(sensorPin);
  //sensorWert = sensorPin;
  Feuchte = map(sensorWert, 640, 220, 0, 100);
  if (sensorWert <= 500){
    digitalWrite(5, HIGH);
    delay(5000);
    digitalWrite(5, LOW);
  }
  if (sensorWert > 550){
    digitalWrite(5, LOW);
  }
}

void Sensorlesen(){
  analogRead(sensorWert);
  Serial.println(sensorWert);
  Feuchte = map(sensorWert, 640, 220, 0, 100);
  Serial.println(Feuchte);
}

void Pumpenstart(){
  digitalWrite(5, HIGH);
  delay(10000);
  digitalWrite(5, LOW);
}

Why do you have these WidgetLED definitions scattered throughout your code, and most importantly, why are they in your void loop?

What do you think these achieve?

You need to implement a Blynk timer, which periodically reads the value of your sensor and then makes a decision whether or not to turn on the pump.

The statement above doesn’t make that much sense, as I would have expected you to want to start the pump again, at some point in the future (maybe the next day) if the humidity reading is less than 400.#

However, if you want to do exactly as you said then you will need a flag, which is set to 0 at start-up (and maybe when automatic mode is selected?) and set to 1 once the pump is triggered. Your decision making process will check the flag. If it’s 1 then you wont start the pump, as it has run once already.

Pete.

The LEDs show me the status whether the pump is running or not.
The code is very confusing I know.

so i have to install a timer, which for example measures every 2h and in automatic mode switches the pump on when needed?

The purpose of the line of code:

WidgetLED led3(V3);

is to tell that compiler that you have an LED widget attached to pin V3. that from this point on in the code you are going to reference as that LED widget as led3

You only need to do this once, at the beginning of your code, then the compiler knows that references to led3 are actually intended for pin V3 and that it can accept a range of commands that relate to LED widgets, like this:

led3.on()
led3.off()
led3.setColor(#D3435C) // Red
led3.setValue(126) // half brightness

I think it might help of you read this:

Pete.

Thanks!

I´ll try to clean up my code.
But first i´ve to learn the BlynkTimer.

Thank you for helping me :slight_smile:

Woho,
it works!
So amazing :smiley:

But can u help me once again?
I have problems to “translate” the sensor value in %…
In Blynk i have one SuperChart and i want to show the % of humidity in there.

    }
    BLYNK_WRITE(V5) {
      // humidity in %
      int Feuchte = param.asInt();
    }

I´ve tried some ways but nothing works :confused:

BLYNK_WRITE(Vx) is a special Blynk callback function that is triggered automatically when the value of the Vx pin changes on the server - usually because the user has changed the state of a widget such as a switch or slider on the app, or a 3rd part system such as IFTTT has updated a value on the server.

if you are trying to send a humidity value to the app, via the Blynk server then you should be using the Blynk.virtualWrite(Vpin,Value) command.

If you want the humidity value of 400 to displayed as a RH percentage then forts of all you need to know what the maximum (100%) values and minimum (0%) values will look like in terms of numbers. For example, your sensor might return 300 for 0% and 500 for 100%, in which case 400 would represent 50% if it was a linear scale.

Pete.

thanks pete!
you’re a big help to me!

my automatic mode works quite well so far, but unfortunately it is permanently activated.
can you take a look at this?

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Blynk.h>


#define pumpe 5
#define sensorPin A0

char auth[] = "TOKEN";
char ssid[] = "WLAN";
char pass[] = "CODE";
int Feuchte = 46;
int sensorWert = 400;
BlynkTimer timer;
WidgetLED led3(V3);
WidgetLED led4(V4);


BLYNK_WRITE(V0){
    int manualBTN = param.asInt();
    Serial.print(manualBTN);
    
    if(manualBTN==1){
      led4.on();
      led3.off();
      Pumpenstart();
    }
    if(manualBTN==0){
      led3.on();
      led4.off();
      Pumpenstop();
    }
}
//-----------------------------------------------------------------SETUP
void setup() {
  // put your setup code here, to run once:
  pinMode(A0, INPUT);
  pinMode(5, OUTPUT);
  pinMode(V2, OUTPUT);
  pinMode(V1, INPUT);
  WidgetLED led3(V3);
  Serial.begin(9600);
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(2000L, Automatikbetrieb);

//-----------------------------------------------------------------LOOP
void loop() {
  Blynk.run();
  timer.run();
}

//-----------------------------------------------------------------Funktionen
void Automatikbetrieb(){
  if (V1==1){
  sensorWert = analogRead(sensorPin);
  //sensorWert = sensorPin;
  //Feuchte = map(sensorWert, 640, 220, 0, 100);
  
    if (sensorWert <= 500){
      digitalWrite(5, HIGH);
      //delay(5000);
      //digitalWrite(5, LOW);
    }
    if (sensorWert > 550){
      digitalWrite(5, LOW);
    }
  } 
  if (V1==0){
    digitalWrite(5, LOW);
  }
}

Well, it’s a mess!

First of all, you need a global variable (that’s one declared at the top of your code, where your variables like sensorWert are defined) that indicates if you are in manual or automatic mode or not.

Then, this variable needs to be synchronised with the Auto/Manual button widget in the app (V0?) when the ESP starts-up. This is done using the special BLYNK_CONNECTED callback function, which is triggered automatically whenever the device connects to the server, and the Blynk.syncVirtual(Vx) command. Like this:

BLYNK_CONNECTED
{
  Blynk.syncVirtual(Vx)
}

This will cause the BLYNK_WRITE(V0) callback to be triggered.

You then need to change the code you have in the BLYNK_WRITE(V0) callback so that it sets this new global variable to the same value as the pin. At thye monment, you have this line of code in your BLYNK_WRITE(V0):

int manualBTN = param.asInt();

Because you have int at the beginning of that line, it’s declaring manualBTN as an integer variable, but one that only exists locally within that function. It’s value can’t be seen outside of the function.
Changing this line to:

manualBTN = param.asInt();

and declaring manualBTN as an integer would make the value of manualBTN available in the rest of your code (although I’d actually call it manual_mode, as it’s more descriptive).

Your main Automatikbetrieb function then needs to test if this manualBTN / manual_mode is true or false (1 or 0) and do whatever it is you want in these two situations.

The code yoiu’ve posted ins incomplete, but does have some issues…

void Automatikbetrieb(){
  if (V1==1){

You’re referencing a variable called V1 here, which is not declared anywhere. If you’re trying to use it to represent the state of a widget attached to virtual pin V1 then you need to do what I’ve described above for pin V0.

Also, you should remove these two lines from your void setup:

  pinMode(V2, OUTPUT);
  pinMode(V1, INPUT);

pinmode definitions are only required for physical pins, not virtual pins.

When I was taught how to program, it was to start with a flow diagram which showed what the program flow would be. I think you’re lacking the overall picture of how you want the program to flow in automatic and manual modes, so youre not able to structure your code accordingly.

Pete.

2 Likes

Hey Pete,

sorry for my late answer. Was very busy…
I have changed something in my code today.
I try to take a value from BlynkApp and save it as an integer.
With the numeric input i want to set the timer in my code.
Looks like:

/*Global Integer*/
int AUTO_CTRL_TM;

/*Read V1(NumericInput) and send it to gauge too(for me to check if its overreaded)*/
BLYNK_WRITE(V1){
  int AUTO_CTRL_TM=param.asInt();
  Blynk.virtualWrite(V20, AUTO_CTRL_TM);
}

/*At last, set timer intervall for function(the function works with hardcoded timer like: int AUTO_CTRL_TM=10;)*/
timer.setInterval(AUTO_CTRL_TM * 1000, autoControlPlantation);

All fine, but it don´t work with my input box in BlynkApp. :thinking:

Remove the ‘int’ from the beginning of this line in your BLYNL_WRITE(V1) callback.

Pete.

HOAH! :smiley:

Got it!

#define BLYNK_PRINT Serial    
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define DRY_SOIL      50
BlynkTimer timer;
char auth[] = "J1JE_IK-kI609ZAvPpo77GxmM78AozZ8";
char ssid[] = "Schmid_Digi";
char pass[] = "89367Wald";
int feuchte;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);    
  Blynk.begin( auth, ssid , pass );
  pinMode(5, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  Blynk.run();
  timer.run();

}

BLYNK_WRITE(V10){
switch (param.asInt())
  {
    case 1: { // Item 1
      Serial.println("Auto-Mode");
      timer.setInterval(8000, automatik);
      break;
    }
    
    case 2: { // Item 2
      Serial.println("Manuell-Mode");
      digitalWrite(5, LOW);
      break;
    }    
  }
}

void feuchteMessen(void)
{
  int i = 0;
  feuchte = 0;
  for (i = 0; i < 10; i++)  //
  {
    feuchte += analogRead(A0); 
    delay(20);   
  }
  feuchte = feuchte / (i);
  feuchte = map(feuchte, 640, 220, 0, 100); 
}

void automatik(){
      Serial.println("Autobetrieb startet");
      feuchteMessen();
      Serial.println(feuchte);
      if(feuchte<50){
        digitalWrite(5, HIGH);
        Serial.println("Pumpe an");  
      }
      else{
        digitalWrite(5, LOW);
        Serial.println("Pumpe aus");
      }
}

I´ve made this finally with a menu in BlynkApp.
Works fine! I will test it at weekend and give u response.

Thank u so much Pete!
:partying_face:

Hey Pete,

finally i want to show u my code.
All things i want to do with this works fine :slight_smile:
Thanks for helping me!!

#define BLYNK_PRINT Serial    
#include <ESP8266WiFi.h>
#include <Blynk.h>
#include <BlynkSimpleEsp8266.h>
#define DRY_SOIL      50
BlynkTimer timer;
char auth[] = "TOKEN";
char ssid[] = "SSID";
char pass[] = "PASS";
int feuchte;
int timerNr2;
int timerNr3;
int manBTN;

//------------------------------------------------SETUP
void setup() {
  Serial.begin(115200);    
  Blynk.begin( auth, ssid , pass );
  pinMode(5, OUTPUT);
  pinMode(A0, INPUT);
  timerNr2 = timer.setInterval(2000, startFeuchte);
  timer.disable(timerNr2);
  timerNr3 = timer.setInterval(5000, startAuto);
  timer.disable(timerNr3);
}


//------------------------------------------------LOOP
void loop() {
  Blynk.run();
  timer.run();
}


//------------------------------------------------Funktionen
void startFeuchte(){
  feuchteMessen();
}
//----------------------------------------------
void startAuto(){
  automatik();
}
//----------------------------------------------
BLYNK_WRITE(V10){
switch (param.asInt())
  { 
    case 1: { // Item 1
      Serial.println("Auto-Mode");
      timer.enable(timerNr2);
      timer.enable(timerNr3);
      break;
    }
    
    case 2: { // Item 2
      Serial.println("Manuell-Mode");
      digitalWrite(5, LOW);
      timer.enable(timerNr2);
      timer.disable(timerNr3);
      break;
    }    
  }
}
//----------------------------------------------
BLYNK_WRITE(V0){
  manBTN=param.asInt();
  if(manBTN==1){
    digitalWrite(5, HIGH);
  }
  else{
    digitalWrite(5, LOW);
  }
}
//----------------------------------------------
void feuchteMessen(void)
{
  int i = 0;
  feuchte = 0;
  for (i = 0; i < 10; i++)  //
  {
    feuchte += analogRead(A0); 
    delay(20);   
  }
  feuchte = feuchte / (i);
  feuchte = map(feuchte, 640, 220, 0, 100); 
}
//----------------------------------------------
void feuchteSenden(){
  Serial.println("Feuchte: ");
  Serial.print(feuchte);
  Serial.print("%");
  Blynk.virtualWrite(V4, feuchte);
}
//----------------------------------------------
void automatik(){
      Serial.println("Autobetrieb startet");
      feuchteMessen();
      Serial.println(feuchte);
      if(feuchte<50){
        digitalWrite(5, HIGH);
        Serial.println("Pumpe an");  
      }
      else{
        digitalWrite(5, LOW);
        Serial.println("Pumpe aus");
      }
}
1 Like