Need help to add delay timer function

Hello there!
I am working on a project where 2 ch relay board can be controlled by blynk app as well as physical switches with feedback.
I want to add timer circuit , when button 2 is switched on (blynk or physical switch) the appliance attached to relay 2 is ON for 2 minutes and then turned OFF for 5 minutes this cycle is continuously repeat until button 2 is switched off. please help
here is the code

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266mDNS.h> // For OTA with ESP8266
#include <WiFiUdp.h> // For OTA
#include <ArduinoOTA.h> // For OTA

BlynkTimer timer;

void checkPhysicalButton();

int relay1State = LOW;
int pushButton1State = HIGH;

int relay2State = LOW;
int pushButton2State = HIGH;

#define AUTH " " // You should get Auth Token in the Blynk App.
#define WIFI_SSID " " //Enter Wifi Name
#define WIFI_PASS " " //Enter wifi Password

#define SERVER "blynk-cloud.com " // Comment-out if use Blynk hosted cloud service
#define PORT 8442

#define RELAY_PIN_1 12 //D6
#define RELAY_PIN_2 16 //D0

#define PUSH_BUTTON_1 2 //D4
#define PUSH_BUTTON_2 14 //D5

#define VPIN_BUTTON_1 V12
#define VPIN_BUTTON_2 V13

#define OTA_HOSTNAME "Home_Automation"

BLYNK_CONNECTED() {

// Request the latest state from the server

Blynk.syncVirtual(VPIN_BUTTON_1);
Blynk.syncVirtual(VPIN_BUTTON_2);

// Alternatively, you could override server state using:
// Blynk.virtualWrite(VPIN_BUTTON_1, relay1State);
// Blynk.virtualWrite(VPIN_BUTTON_2, relay2State);
}

// When App button is pushed - switch the state

BLYNK_WRITE(VPIN_BUTTON_1) {
relay1State = param.asInt();
digitalWrite(RELAY_PIN_1, relay1State);
}

BLYNK_WRITE(VPIN_BUTTON_2) {
relay2State = param.asInt();
digitalWrite(RELAY_PIN_2, relay2State);
}

void checkPhysicalButton()
{
if (digitalRead(PUSH_BUTTON_1) == LOW) {
// pushButton1State is used to avoid sequential toggles
if (pushButton1State != LOW) {

  // Toggle Relay state
  relay1State = !relay1State;
  digitalWrite(RELAY_PIN_1, relay1State);

  // Update Button Widget
  Blynk.virtualWrite(VPIN_BUTTON_1, relay1State);
}
pushButton1State = LOW;

} else {
pushButton1State = HIGH;
}

if (digitalRead(PUSH_BUTTON_2) == LOW) {
// pushButton2State is used to avoid sequential toggles
if (pushButton2State != LOW) {

  // Toggle Relay state
  relay2State = !relay2State;
  digitalWrite(RELAY_PIN_2, relay2State);

  // Update Button Widget
  Blynk.virtualWrite(VPIN_BUTTON_2, relay2State);
}
pushButton2State = LOW;

} else {
pushButton2State = HIGH;
}

}

void setup()
{

Serial.begin(115200);
Blynk.begin(AUTH, WIFI_SSID, WIFI_PASS,"blynk-cloud.com", 8442);
ArduinoOTA.setHostname(OTA_HOSTNAME); // For OTA - Use your own device identifying name
ArduinoOTA.begin(); // For OTA

pinMode(RELAY_PIN_1, OUTPUT);
pinMode(PUSH_BUTTON_1, INPUT_PULLUP);
digitalWrite(RELAY_PIN_1, relay1State);

pinMode(RELAY_PIN_2, OUTPUT);
pinMode(PUSH_BUTTON_2, INPUT_PULLUP);
digitalWrite(RELAY_PIN_2, relay2State);

// Setup a function to be called every 100 ms
timer.setInterval(500L, checkPhysicalButton);
}

void loop()
{
Blynk.run();
ArduinoOTA.handle(); // For OTA
timer.run();
}

unsigned long timerMillis = 0;
bool ontime, offtime = false;
bool relay2State = LOW;
bool pushButton2State = HIGH;

void setup() {
  // hier pinMode etc.
}

void loop() {
  if (pushButton2State == HIGH && timerMillis == 0) {
    timerMillis = millis() + 2 * 60 * 1000;
    digitalWrite(relay2State, HIGH);
    ontime = true;
  }
  if (pushButton2State == LOW ) {
    timerMillis = 0;
    ontime = false;
    offtime = false;
    digitalWrite(relay2State, LOW);
  }
  if (timerMillis > 0 && millis() > timerMillis)
    if (ontime) {
      ontime = false;
      offtime = true;
      timerMillis = millis() + 5 * 60 * 1000;
      digitalWrite(relay2State, LOW);
    }
    else {
      ontime = true;
      offtime = false;
      timerMillis = millis() + 2 * 60 * 1000;
      digitalWrite(relay2State, HIGH);
    }
}

btw: bit-wise operations make this quicker

1 Like

Is the button a momentary switch? What about the blynk end?

Programming the behavior will be easy enough if you implement it as a state machine. I've added a diagram in which you can see what states and transitions you will have to implement.

graphviz

b2 = button 2, but it could be another trigger
dt = the time since the last transition

As for implementing a state machine there are plenty of online resources. Here is one picked at random:

1 Like

I've not proposed that he should use a delay.

@kolaha it's a state diagram. Read the article linked and learn about finite state machines.

a7

It's not. You could implement it like that, but you don't have to. It explicitly states that if dt is less than two minutes then transition to the same state.

It has nothing to do with the delay function.

Well you're wrong.

This statement clearly demonstrates that you don't know what you're talking about. Have you read the link I've posted?

That's up to you. I'm sure an attitude like that will take you far in life.

I assume you mean you don't need to read about state machines.

Your own brain is an amazing instrument, best to rely on it!

But that means you should just shut up about refrain from commenting on problems you see in a diagram you obvsly do not understand.

Someone who knows a little less than you might think you know what you talking about.

a7

Out of curiosity. What advice that I have given do you think I'm not using?

I gave hints to how he can achieve what he wants. You're the one that derailed the thread.

But nevermind. I'm out now.

Here's an approach to doing that. You could add the rest of your stuff to this as long as you promise to NOT use delay() anywhere. You will need to install LC_baseTools to get this to compile.

#include <blinker.h>
#include <mechButton.h>

#define RELAY_PIN_2     16                                  //D0
#define PUSH_BUTTON_2   14                                  //D5

#define TIME_ON         2*60*1000                           // 2 minutes
#define TIME_OFF        5*60*1000                           // 5 minutes

blinker     relaySig(RELAY_PIN_2,TIME_ON,TIME_ON+TIME_OFF); // Our signal generator.
mechButton  button2(PUSH_BUTTON_2);                         // Button 2, ground to activate.


void setup() {
   
   button2.setCallback(btn2Clicked);                        // Setup button callback.
   relaySig.setOnOff(false);
}


// When clicked the button calls this function.
void btn2Clicked(void) {

   if (!button2.trueFalse()) {                              // If grounded..
      relaySig.setOnOff(!relaySig.running());               // Read the blinker state and set it to the opposite.
   }
}


void loop() {
   
   idle();  // Runs the button and the relay.
}

Good luck!

Edit : What a dummy, I forgot to attach the actual example.

-jim lee

1 Like

Thank you so much kolaha I really appreciate it!
its perfectly working
(sorry for the delayed response)
Thank you once again for support. :slightly_smiling_face:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.