Loop action problem

Hello!

I’m using Wemos D1 R2 and latest Blynk library and app. I am also using Arduino IDE 1.6.13. I am trying to read a button from the app, which works fine, but i want to read it continuously. Through the serial monitor i can see that the board changes modes as it should. However, even if sensors read values when we get through the first “if” states, the values do not continue to show up in serial monitor. I believe that’s happening because it is not working as a loop. Also, the relays are not working(they start as open as they should, but their state never changes), as i believe program freezes at some point.

Sorry if i have confused you, but here comes the code:


//Start of program
#include <dht11.h>
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <Blynk.h>
#include <BlynkSimpleEsp8266.h>
#include <NewPing.h> 
#include <SimpleTimer.h>


#define TRIGGER_PIN2 D4 // Arduino pin tied to trigger pin on the ultrasonic sensor 2.
#define ECHO_PIN2 D3     // Arduino pin tied to echo pin on the ultrasonic sensor 2.
#define MAX_DISTANCE2  23// Height of the Water Tank 2 (in centimeters). 
#define DHT11_PIN D5


char auth[] = "****************";
char ssid[] = "8888";
char pass[] = "888888";

int Relay1 = D1;
int Relay2 = D2;
int val2 = 0;
int tankwater1 = 0; //water in tank 1 in liters
int tankwater2 = 0; //water in tank 2 in liters
int fieldsize1 = 0; //size of field1 in m^2
int fieldsize2 = 0; //size of field2 in m^2
int sensor_pin =D6;
SimpleTimer timer;
NewPing sonar2(TRIGGER_PIN2, ECHO_PIN2, MAX_DISTANCE2); // NewPing setup of pins and maximum distance.

void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  Blynk.begin(auth, ssid, pass);
  pinMode(Relay1, OUTPUT); //Setup Relay pin as output pin
  pinMode(Relay2, OUTPUT); //Setup Relay pin as output pin
  //pinMode(led_pin, OUTPUT);
  pinMode(sensor_pin, INPUT);
  digitalWrite(Relay1, LOW);
  digitalWrite(Relay2, LOW);
  
  
}

void loop()
{
 Blynk.run();
 timer.run();
}

BLYNK_READ(V5)
{
Blynk.virtualWrite(8,val2);// virtualpin 8 distance
}

 BLYNK_WRITE(V1) {
  int pinValue = param.asInt(); 
  val2 = sonar2.convert_cm(sonar2.ping_median());
  if (pinValue==0)
  {
    Serial.println("Irrigation mode is active");
    Serial.println("Water level is at:");
    Serial.println(23-val2);
    
    if(digitalRead(sensor_pin) == HIGH)
    {

       if (val2 <= 15) //Water level reaches the Top of the Tank2
          {   
          digitalWrite(Relay2, HIGH); //Pump2 off
          delay(500);
          }

        else if (val2 > 15) // Water is empty on the Tank2
          {
    
          digitalWrite(Relay2, LOW); // Pump2 ON
          delay(500);
          //delay(86400000); one day delay. not suitable for experiment
          }
     else if(digitalRead(sensor_pin) == LOW)
          {
            digitalWrite(Relay1, LOW);
          }}}
  
  
  
  else {
    Serial.println("Fertilize mode is active. This does nothing now");
    //val3 = sonar2.convert_cm(sonar2.ping_median());
    //tankwater2 = (10-val3)*fieldsize2; //calculation of water in tank2
  }
}
//End of program

So the part you want to happen regularly should be inside the loop() {...} method.

Something like this:

int mode = 0; //0 = irrigation, 1 = fertilisation

BLYNK_WRITE(v1) {
  int pinValue = param.asInt(); 
  mode = pinValue; //store the mode, we need it inside loop()
}

void loop() 
{
  Blynk.run();
  timer.run();
  
  if(mode == 0)  {
    [...] //all the stuff you have already
  else {
   Serial.println("Fertilize mode is active. This does nothing now");
  }

}

@Gaff no, that is asking for problems in the long run. Loop() should only contain timer.run and Blynk.run. The way it is on the posted code is just fine.

The only thing I’m missing in the code is a function to be executed on a timely basis. E.g. like in the PushData example of Blynk. Move all the code you want to execute regularly (like say every 1s) to it’s own void functionSomething() and have that on a timer.

Maybe something like this, no guarantees it will work like you want it:

boolean tankFull = true;  // start as if tank is full so pump doesn't start running on boot/restart

BLYNK_WRITE(V1) {
  int pinValue = param.asInt();  
  if (pinValue==0)
  {
     val2 = sonar2.convert_cm(sonar2.ping_median());
    Serial.println("Irrigation mode is active");
    Serial.println("Water level is at:");
    Serial.println(23-val2);
    NewTimer = timer.setInterval(1000L, repeatMe); //REPEAT THIS FUNCTION EVERY 1 SECOND
    }
      
  else {
    Serial.println("Fertilize mode is active. This does nothing now");
    timer.disable(NewTimer); //STOP THE TIMER REPEATING repeatMe FUNCTION
    digitalWrite(Relay2, HIGH); //make sure Pump2 is off; otherwise pump may continue to run if V1 goes high while pump is on
    //val3 = sonar2.convert_cm(sonar2.ping_median());
    //tankwater2 = (10-val3)*fieldsize2; //calculation of water in tank2
  }

  void repeatMe() 
{
   val2 = sonar2.convert_cm(sonar2.ping_median()); //get water level
   Blynk.virtualWrite(8,val2); // write water level to virtual pin 8
   if(digitalRead(sensor_pin) == HIGH)
    {
       if (val2 <= 15) //Water level has reached the Top of the Tank2
          {   
          if (tankFull != true)
            {
          digitalWrite(Relay2, HIGH); //Pump2 off
            }
          
          tankFull = true;
          }
          else
          {
            tankFull = false;
            digitalWrite(Relay2, LOW); // Pump2 ON
          }
    
     }   
    else if(digitalRead(sensor_pin) == LOW)
          {
            digitalWrite(Relay1, LOW);
            digitalWrite(Relay2, HIGH); //Pump2 off; otherwise pump will continue to run if sensor_pin goes low while pump is on
          }  
        
            
}

Remove this

BLYNK_READ(V5)
{
Blynk.virtualWrite(8,val2);// virtualpin 8 distance
}

And Change

digitalWrite(Relay2, LOW);

to

digitalWrite(Relay2, HIGH);// no pump upon startup