Problem with timers

Hi,
I have a simple program with relay, it shoud work 30 seconds, then 30 seconds off and repeat again and again untill the button at application is pressed.
But it doesn’t work like it should, please advice.

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>


// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "";   // илентификатор устройства


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = ""; // Имя Wi-Fi сети
char pass[] = ""; // Пароль Wi-Fi сети
//
BlynkTimer VentilationOnTimer;
BlynkTimer VentilationOffTimer;

int value;

BLYNK_WRITE(V15)  // получение значение кнопки timer
{
value =param.asInt();
pinMode(1, OUTPUT); 
while (value == 1){
VentilationOnTimer.setInterval(60000, ventilationOn);   
VentilationOffTimer.setInterval(30000, ventilationOff); 
}
}
void setup()
{
  #define BLYNK_PRINT Serial
//  Serial.begin(115200);
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
  
}
  

void ventilationOff()
{
  digitalWrite(1, HIGH);  
}

void ventilationOn()
{
  digitalWrite(1, LOW);  
}

void loop()
{
  Blynk.run();
  VentilationOnTimer.run();
 VentilationOffTimer.run();
}


You can’t use a while command like this, as it’s blocking other code execution, so the void loop doesn’t run.

The proper way to do it is to enable a timeout timer and when that timer expires enable another timeout timer.
Or, use a a single timer and a flag.

Pete.

@DoMoney As mentioned by @PeteKnight, instead of using two seperate interval timers, try one (usually the 2nd embedded one) as a timeout timer. Then read other posts in my topic for info on enabling/disabling/deleting timers. (only need to do so on the initial interval timer… don’t forget you might need to add in a sacrificial timer to make that work)

1 Like

Hi. I’ve used your code to flash esp led, if the button V15 is pressed, it’s working, but when V15 isn’t pressed it still continue to flash. Please advice.

#define BLYNK_DEBUG        // Optional, this enables more detailed prints
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "";   // илентификатор устройства


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XiaomiHome"; // Имя Wi-Fi сети
char pass[] = ""; // Пароль Wi-Fi сети

  int value;
  BLYNK_WRITE(V15)  // получение значение кнопки timer
  {
    value = param.asInt();
    pinMode(1, OUTPUT);
  
      if (value == 1) {
      timer.setInterval(20000L, []() {  // Start 1st Timed Lambda Function - Turn ON LED every 2 seconds (repeating)
        timer.setTimeout(10000L, []() {  // Start 2nd Timed Lambda Function - Turn OFF LED 1 second later (once per loop)
          digitalWrite(1, HIGH); // Turn ESP On-Board LED OFF
        });  // END 2nd Timer Function
        digitalWrite(1, LOW); // Turn ESP On-Board LED ON
      });  // END 1st Timer Function
    }
  }


void setup()
{
#define BLYNK_PRINT Serial
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);

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

}

Your BLYNK_WRITE(V15) callback contains a if (value == 1) statement, but no complimentary if (value == 0) statement.

I’d expect you to be deleting/disabling the timers in this value == 0 scenario.

Pete.

1 Like

You will need to do some creative thinking. As with most programming problems there is often many way to accomplish the same task.

You have nothing telling the code to stop when V15 is not pressed. One way would be to add an else statement that deletes or disables the timer that runs on an interval.

Or you can make the first timer run only once per loop as well, and have it trigger the loop again to see if V15 is still 1.

Also, the on-board LED is active LOW, and (someone correct me if I am wrong here), the timers execute AFTER the time has passed. So there will be a delay before the light turns ON

Here is an example of the second option.

#define BLYNK_DEBUG        // Optional, this enables more detailed prints
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "";   // илентификатор устройства


// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XiaomiHome"; // Имя Wi-Fi сети
char pass[] = ""; // Пароль Wi-Fi сети
int value;
  BLYNK_WRITE(V15)  // получение значение кнопки timer
  {
    value = param.asInt();

      if (value == 1) {
      timer.setTimeout(1000L, []() {  // Start 1st Timed Lambda Function - Turn ON LED AFTER 1 seconds (once per loop)
        digitalWrite(2, LOW); // Turn ESP On-Board LED ON
        Serial.println("FIRST timer - LED ON"); 
        timer.setTimeout(1000L, []() {  // Start 2nd Timed Lambda Function - Turn OFF LED AFTER 1 more second (once per loop)
          digitalWrite(2, HIGH); // Turn ESP Off-Board LED OFF
          Blynk.syncVirtual(V15); // Run V15 Function Again
          Serial.println("SECOND timer - LED OFF");
        });  // END 2nd Timer Function
         
      });  // END 1st Timer Function
    }
  }

void setup()
{

  Serial.begin(9600);
  pinMode(2, OUTPUT); // move this to your setup()
  digitalWrite(2, HIGH); // Turn ESP Off-Board LED OFF
  Blynk.begin(auth, ssid, pass);

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

}
1 Like