Automatically turn off output after set time

I have an Arduino UNO with an ethernet shield running a very simple blink program. It has 8 buttons that control relays. I want the relays to automatically turn off after a set amount of time from when they got turned on. what is the best way to do this? if it uses millis it needs to handle rollover perfectly and I don’t know how to do that.

It’s fairly easy to avoid millis rollover issues if you write your comparison test correctly, and there are plenty of examples how to do that, and explanations of why they work, on the internet.

However, for this type of thing using millis isn’t usually the best approach, as you need a routine to constantly do your millis comparisons, and with 8 relays that gets messy.

The simplest approach is to use a lambda timeout timer like this…

  digitalWrite(relay1, LOW);       // Turn relay1 On
  timer.setTimeout(5000L, []() 
  {  // Wait 5 seconds then...
     digitalWrite(relay1, HIGH);   // Turn relay1 Off again
  });  // END of Lambda Function

You’ll need to declare a timer object as part of your initialisation code near the top of your sketch…

// Initialise the timer object
BlynkTimer timer;

and service the timer object in your void loop…;


Hey, Pete.

I have a similar problem.

I need to switch on two relays simultaneously and after about 30 minutes they should switch off automatically.

I have already tried the “Delay” and “millis” functions. The “milli” function was fine when I tested it on Tinkercad, for example, but when I try the Blynk virtual button, it doesn’t work.

I have now tried your suggestion, with the addition of this code, but the relay started to turn on and on again every 5 seconds after I turned off.

The “Timer” and “Eventor” functions are not suitable for this project. The buttons are activated at different unexpected times.

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
char auth[] = "XXXXXXXX";
char ssid[] = "XXXXXX";
char pass[] = "XXXXX";
#define EspSerial Serial3
#define ESP8266_BAUD 115200

ESP8266 wifi(&EspSerial);
BlynkTimer timer;


   if (param.asInt()==1) {
    digitalWrite(R_S_BOMBA_NAO_POTAVEL, HIGH);
    timer.setTimeout(5000L, []() 
  {  // Wait 5 seconds then...
    digitalWrite(R_S_BOMBA_NAO_POTAVEL, LOW);
    digitalWrite(R_S_VALVULA_GARAGEM_FRENTE, LOW);   // Turn relay1 Off again
  });  // END of Lambda Function
    digitalWrite(R_S_BOMBA_NAO_POTAVEL, LOW);

void setup()
  Blynk.begin(auth, wifi, ssid, pass);


void loop()
    if ( Serial3.available() )   {  Serial.write( );  }
    if ( Serial.available() )       {  Serial3.write( );  };

That’s probably because the BLYNK_WRITE function isn’t a loop, so no millis comparison would be repeated.

Is there any reason why you’ve not declared the

Are you sure your relays are active HIGH?


Relays work normally even without declaring “pin, output” if I don’t add “delay or milli”.

I can turn on and off in the Blynk app, triggering the virtual pin, but I can’t turn it off after a while automatically.

That’s a different description of the error to the one you gave earlier, and it doesn’t answer my question about whether the relay is active HIGH or LOW.


When I did the first test with the virtual pin, I forgot to declare the pins “R_S_BOMBA_NAO_POTAVEL and R_S_VALVULA_GARAGEM_FRENTE” as “output”, but they worked correctly (HIGH and LOW).

When I remembered it, I realized it was working properly to turn it on and off, so I didn’t write the code. I thought it was not necessary using the blynk app.

Is that why they didn’t work properly?

I have no idea, I don’t really understand your comment, and you won’t answer my questions about whether your relays are active HIGH or low.

Is this topic solved now?