Function to run only once

Hello !!

I am sure this is nothing to do with Blynk ! But i am sure that someone here can help me out. So please bare with me this time !!

I am trying to modify this Blynk project :point_down:

And here every thing works just cool. But here in my application i need 2 relays, one relay to turn on for 2 sec and another for 2 seconds to turn the device off. This is the basic working needed.

BLYNK_WRITE(V4)//Monday-Friday
{  
  if (mondayfriday==1) {         
    sprintf(Date, "%02d/%02d/%04d",  day(), month(), year());
    sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
  
    TimeInputParam t(param);
  
    terminal.print("M-F Checked schedule at: ");
    terminal.println(Time);
    terminal.flush();
    int dayadjustment = -1;  
    if(weekday() == 1){
      dayadjustment =  6; // needed for Sunday, Time library is day 1 and Blynk is day 7
    }
    if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
    terminal.println("Monday-Friday ACTIVE today");
    terminal.flush();
    if (t.hasStartTime()) // Process start time
    {
      terminal.println(String("Start: ") + t.getStartHour() + ":" + t.getStartMinute());
      terminal.flush();
    }
    if (t.hasStopTime()) // Process stop time
    {
      terminal.println(String("Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
      terminal.flush();
    }
    // Display timezone details, for information purposes only 
    terminal.println(String("Time zone: ") + t.getTZ()); // Timezone is already added to start/stop time 
  //  terminal.println(String("Time zone offset: ") + t.getTZ_Offset()); // Get timezone offset (in seconds)
    terminal.flush();
  
     for (int i = 1; i <= 7; i++) {  // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
        if (t.isWeekdaySelected(i)) {
        terminal.println(String("Day ") + i + " is selected");
        terminal.flush();
        }
      } 
    nowseconds = ((hour() * 3600) + (minute() * 60) + second());
    startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    //Serial.println(startsecondswd);  // used for debugging
    if(nowseconds >= startsecondswd){    
      terminal.print("Monday-Friday STARTED at");
      terminal.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
      terminal.flush();
      if(nowseconds <= startsecondswd + 90){    // 90s on 60s timer ensures 1 trigger command is sent
        digitalWrite(TestLED1, HIGH); // set LED ON
        Blynk.virtualWrite(V2, 1);
        // code here to switch the relay ON
      }      
    }
    else{
      terminal.println("Monday-Friday Device NOT STARTED today");
      terminal.flush();
   
    }
    stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
    //Serial.println(stopsecondswd);  // used for debugging
    if(nowseconds >= stopsecondswd){
      digitalWrite(TestLED1, LOW); // set LED OFF
      Blynk.virtualWrite(V2, 0);
      terminal.print("Monday-Friday STOPPED at");
      terminal.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
      terminal.flush();
        if(nowseconds <= stopsecondswd + 90){   // 90s on 60s timer ensures 1 trigger command is sent
        digitalWrite(TestLED1, LOW); // set LED OFF
        Blynk.virtualWrite(V2, 0);
        // code here to switch the relay OFF
      }              
    }
    else{
      if(nowseconds >= startsecondswd){  
        digitalWrite(TestLED1, HIGH); // set LED ON    test
        Blynk.virtualWrite(V2, 1);
        terminal.println("Monday-Friday is ON");
        terminal.flush();
      
      }          
    }
  }
  else{
    terminal.println("Monday-Friday INACTIVE today");
    terminal.flush();
    // nothing to do today, check again in 30 SECONDS time    
  }
  terminal.println();
}
}

In this part of the code we can set the relay high or low. But this will updated every 10 sec and it will trigger the relay once more !! I dont want the relay to trigger but the rest should work.

I tried using while(1) {} but this will cease the whole code and put the device into offline mode… I am damm sure this is wrong. But i wanted to try if that works…

Can someone please tell me how to achive this ??

Thank you in advance…

Typically this can be achieved with a simple flag and flag check.

int flag = 0;  // set your flag in the pre-setup

void yourThingFunction() {  // or use a BLYNK_WRITE() function
 if (flag == 0) { // Only run your thing if never ran before
 flag = 1;  // prevent your thing from running again by setting flag
 // do your thing here
 }
}

Thank you for the quick reply.
By doing what you said now, will it run again if the

is called again or will i have to restart the module ?

It will only run again if you change the flag back to 0 somewhere in the code or when the device is restarted.

i just tried the code you gave. For the first time i worked like it should. The relay clicked for 2 sec and turned back off. And when i again Ran the :point_down:

this time the relays did not turn on, but the program was running fine.

How to get the relays to work every time the above BLYNK_WRITE is called…

its a request
Can you please give me an idea how to reset the flag, once the

gets done ??

flag = 0; at the end of the function… or wherever it needs to go for your application.

yes tried it. But it runs only once, the next time its not running as it is is not setting the flag to 0.

I haven’t ran through the logic of your code, so I don’t know exactly where it needs to go. You need to figure out where to put that line as needed.

Follow your code line by line and think about what steps are taken and where the logical place to “reset” the flag would be, then test. If it works, great, if not, go through it again… trial and error gets the brain working :wink:

Ooooopsssss my bad … i put in flag == 0; instead of flag = 0; …

I corrected this. But it again cycles through the flag = 0 and again turns back the relay on :sweat_smile:

Basically ended up where i started up, but in a better way… Need to find a way to stop the flag from loop…

This whole thing loops every 10 sec when called and loops every 30 sec if idle :point_down:

LYNK_WRITE(V4)//Monday-Friday
{  
  if (mondayfriday==1) {         
    sprintf(Date, "%02d/%02d/%04d",  day(), month(), year());
    sprintf(Time, "%02d:%02d:%02d", hour(), minute(), second());
  
    TimeInputParam t(param);
  
    terminal.print("M-F Checked schedule at: ");
    terminal.println(Time);
    terminal.flush();
    int dayadjustment = -1;  
    if(weekday() == 1){
      dayadjustment =  6; // needed for Sunday, Time library is day 1 and Blynk is day 7
    }
    if(t.isWeekdaySelected(weekday() + dayadjustment)){ //Time library starts week on Sunday, Blynk on Monday
    terminal.println("Monday-Friday ACTIVE today");
    terminal.flush();
    if (t.hasStartTime()) // Process start time
    {
      terminal.println(String("Start: ") + t.getStartHour() + ":" + t.getStartMinute());
      terminal.flush();
    }
    if (t.hasStopTime()) // Process stop time
    {
      terminal.println(String("Stop : ") + t.getStopHour() + ":" + t.getStopMinute());
      terminal.flush();
    }
    // Display timezone details, for information purposes only 
    terminal.println(String("Time zone: ") + t.getTZ()); // Timezone is already added to start/stop time 
  //  terminal.println(String("Time zone offset: ") + t.getTZ_Offset()); // Get timezone offset (in seconds)
    terminal.flush();
  
     for (int i = 1; i <= 7; i++) {  // Process weekdays (1. Mon, 2. Tue, 3. Wed, ...)
        if (t.isWeekdaySelected(i)) {
        terminal.println(String("Day ") + i + " is selected");
        terminal.flush();
        }
      } 
    nowseconds = ((hour() * 3600) + (minute() * 60) + second());
    startsecondswd = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    //Serial.println(startsecondswd);  // used for debugging
    if(nowseconds >= startsecondswd){    
      terminal.print("Monday-Friday STARTED at");
      terminal.println(String(" ") + t.getStartHour() + ":" + t.getStartMinute());
      terminal.flush();
      if(nowseconds <= startsecondswd + 90){    // 90s on 60s timer ensures 1 trigger command is sent
        digitalWrite(TestLED1, HIGH); // set LED ON
        Blynk.virtualWrite(V2, 1);
        relayON();
        flag2 = 0;
        // code here to switch the relay ON
      }      
    }
    else{
      terminal.println("Monday-Friday Device NOT STARTED today");
      terminal.flush();
   
    }
    stopsecondswd = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);
    //Serial.println(stopsecondswd);  // used for debugging
    if(nowseconds >= stopsecondswd){
      digitalWrite(TestLED1, LOW); // set LED OFF
      Blynk.virtualWrite(V2, 0);
      terminal.print("Monday-Friday STOPPED at");
      terminal.println(String(" ") + t.getStopHour() + ":" + t.getStopMinute());
      terminal.flush();
      
        if(nowseconds <= stopsecondswd + 90){   // 90s on 60s timer ensures 1 trigger command is sent
        digitalWrite(TestLED1, LOW); // set LED OFF
        Blynk.virtualWrite(V2, 0);
        relayOFF();
        flag1 = 0;
        // code here to switch the relay OFF
      }              
    }
    else{
      if(nowseconds >= startsecondswd){  
        digitalWrite(TestLED1, HIGH); // set LED ON    test
        Blynk.virtualWrite(V2, 1);
        terminal.println("Monday-Friday is ON");
        terminal.flush();
       }          
    }
  }
  else{
    terminal.println("Monday-Friday INACTIVE today");
    terminal.flush();
    // nothing to do today, check again in 30 SECONDS time    
  }
  terminal.println();
  
}
}

So i am not able to put in the flag = 0; here. Because it sets the flag to 0 and when the loop starts again the relay will turn on.
I am not understanding where to place the flag = 0; :tired_face:

If you don’t want it to trip the relay again… then don’t reset the flag.

Or determine the logic that dictates if and when you want to trip the relay again and reset the flag there.

1 Like

The problem is we do not know what you are trying to do.

Ok let me explain.

There is a pump and that has 2 switches. One switch to turn on and other to turn it off !!

Now what am trying to do is, instead of the switches am replacing it with a relay. Basically doing the same stuff as the switch but adding the ability to be controlled by a NODEMCU. And injecting it with :ok_hand:t2:BLYNK !!

Now i want to mimic the press of the button with the relay ! Like turning on the relay for 2sec and turning back off . This will trigger the pump . And when we do the same with the other relay the pump turns off .

This is the functionality i am looking for. This is not a BLYNK related problem at all !!! But I am looking for a way out of this here . Pardon me for this.

As @Gunner said placing a flag and setting it 0 will help and yes it worked. But every time the loop occurs where ever we place the flag, it runs through it sets it zero and again triggers the relay like it was a new command .

I have set 2 function to trigger the 2 different relay’s for 2sec with 2 different flags for each.As Gunner’s states in the earlier post . And yes it works for the turn off relay . But not the turn on relay . It just loops back setting the the flag 0 and triggers the relay back.

Can you please tell me where to place the flag so that this doesn’t occur?

ok very easy code

relaybutton is the vpin that is used on the app

void relayoff() {
  digitalWrite(RELAY_PIN, LOW);             // turn off pin this causes the relay to turn off
  Blynk.virtualWrite(relaybutton, 0);      // display relay off
  flag = 0;
}

void relayon() {
    if (!flag) {
      flag = 1;
      digitalWrite(RELAY_PIN, HIGH);              // send power to relay
      timer.setTimeout(5000L, relayoff);        // turn off after 5 seconds  << change this to whatever delay you want
    }
    Blynk.virtualWrite(relaybutton, 1);          // update the app
}

the flag needs to be a global var

Sorry I forgot to mention. I am modifying an existing Blynk project.

Can you please have a look at this code once please.

This is the part of the code tnat am trying to modiy. There is no dedicated button to turn the relays on.

Once the schedule occurs the relays must work as i said earlier.
Yes i have a void relayon () as global .

You need to properly format code so I can read it

Oops sorry… i am on my phone. And it’s difficult to use here. Sorry for the mess. Now its been edited.

I don’t see it.

Also you can just call the function from the code with the same result.