nodeMCU + Blynk and a window

Hi
I have a water/rain sensor working with a nodeMCU which commands a relay: if it is raining it gives power to a motor to close a roof window.

  1. if I’m there I’m closing it with a blynk button
  2. but if I’m note there, I want to read the sensor only once in 15 sec; if it is raining I want to give power to the relay for 40 sec to have enough time to close the window; but I don’t know how to do it
    the issue: if the sensor detects rain, I want to have the 40 sec period to close the window, but after 15 sec I’m reading again the sensor, maybe it says no rain (maybe it’s an error, it’s faulty, etc) and I don’t want to risk this, but at this moment it passed ony 15 sec and the nodeMCU cuts the power of the relay leaving the window open
    as all of you are saying not to use delay with wifi, how can I give 40 sec of power to the relay?
#define BLYNK_PRINT Serial

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

#define rainAnalog A0
#define pinRelay D4

const unsigned int Period = 4000; 
BlynkTimer timer;

char auth[] = "xxx";
char ssid[] = "yyy";
char pass[] = "zzz";

bool myRelay = false;

void sensorReadings()
{
  int rainAnalogVal = analogRead(rainAnalog); //value from 0 to 1023

  if(rainAnalogVal<800){
    Serial.println("Rain");
    digitalWrite(pinRelay, LOW);
    Serial.println("Relay is ON");
    Serial.println("start the 40sec");
    myRelay = true;
    timer.setTimeout(40000L, []() {//keeps 40 sec the relay ON
      digitalWrite(pinRelay, HIGH);
      myRelay = false;
      Serial.println("40sec ended");
    });
  }
  else{ //it is not raining but we'll test if the relay is on
    if (myRelay){ //do nothing, let pass the 40 sec
    }
    else {
      Serial.println("No Rain");
      digitalWrite(pinRelay, HIGH);
      Serial.println("Relay is OFF");
    }
  }
  Serial.println("============== new check");
}

void setup()
{
  Serial.begin(9600);
  digitalWrite(pinRelay, HIGH); //set initial state OFF for RELAY
  pinMode(pinRelay, OUTPUT);
  
  Blynk.begin(auth, ssid, pass);

  timer.setInterval(15000L, sensorReadings);
}

void loop()
{
  Blynk.run();
  timer.run();
  digitalWrite(pinRelay, LOW);
}

I though that calling myDelay (), which basically does nothing, will give me the 40 sec time, but it is continuing to run the script

Search for examples of “lambda timer”

And, if you’re worried about the timer being interrupted (which I don’t think should be a problem) then set a flag variable immediately before initialising the timer and clear the flag afterwards, and use that flag in an if condition to prevent the timer from being cancelled whilst the flag is true.

Pete.

Pete.

Also that sensor may last a little longer, not corrode as fast, if you just turn it high before reading and turn it low again at the end of the loop.

1 Like

Pete: I added the boolean var myRelay which is false when off. When starts the rain it becomes true until the 40 sec pass so it is uninterrupted even the sensor doesn’t see rain
did I used correct the lambda timer?

timer.setTimeout(40000L, []() {//keeps 40 sec the relay ON
      digitalWrite(pinRelay, HIGH);
      myRelay = false;
      Serial.println("40sec ended");
    });

Dave: I added the last line with relay set LOW; this was your suggestion?

It’s impossible to tell what you’re doing from this snippet of code, but I’d suggest that you start with just the lambda timer then add the flag variable if needed.

Pete.