Possible to code the Arduino to shut off an LED after 20 mins?

I am curious If I am able to write a code that will turn an LED on with a switch and automatically turn off the LED after 20 mins?

Sure. You could use the delay() function. That is the easy way, but will be a unresponsive program. That may be OK. If you want a responsive program use milllis() for timing.

Non-blocking timing tutorials:
Blink without delay().
Beginner's guide to millis().
Several things at a time.

Thank you for your quick response. I will give it a shot

Hi John Thomas,
welcome to the arduino forum

here is a software RTC based on non-blocking timing

/* This software belongs to the public domain
 * Attention: a software-RTC like this one 
 * which uses the onboard-oscillator of the microcontroller-board
 * has a deviation from exact time of up to multiple seconds per day
 * This means of you want real time with a higher precision use a
 * hardware based RTC which will be much more precise
 */

unsigned long RTC_Timer  = 0;
unsigned long MyTestTimer;

int RTC_Hour   = 0;
int RTC_Minute = 59;
int RTC_Second = 50;
int RTC_10nth_Seconds = 0;
int minutesOfDay;
int secondsOfDay;


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}


void PrintRTC_Data() {
  Serial.print("Software RTC time: ");
  Serial.print(RTC_Hour);
  Serial.print(":");
  Serial.print(RTC_Minute);
  Serial.print(":");
  Serial.print(RTC_Second);

  minutesOfDay = RTC_Hour * 60 + RTC_Minute;
  secondsOfDay = RTC_Hour * 3600 + RTC_Minute * 60 + RTC_Second;

  Serial.print(" minutesOfDay:");
  Serial.print(minutesOfDay);

  Serial.print("  secondsOfDay:");
  Serial.print(secondsOfDay);  
  Serial.println();
  
}


void SoftRTC() {
  if ( TimePeriodIsOver(RTC_Timer, 100) ) { // once every 100 milliseconds 
    RTC_10nth_Seconds ++;                   // increase 1/10th-seconds counter
    
    if (RTC_10nth_Seconds == 10) {          // if 1/10th-seconds reaches 10
      RTC_10nth_Seconds = 0;                // reset 1/10th-seconds counterto zero
      RTC_Second++;                         // increase seconds counter by 1

      if (RTC_Second == 60) {               // if seconds counter reaches 60
        RTC_Minute++;                       // increase minutes counter by 1
        RTC_Second = 0;                     // reset seconds counter to zero
      }
    }

    if (RTC_Minute == 60) {                 // if minutes counter reaches 60
      RTC_Hour++;                           // increase hour counter by 1
      RTC_Minute = 0;                       // reset minutes counter to zero
    }

    if (RTC_Hour == 24) {                   // if hours counter reaches 24 
      RTC_Hour = 0;                         // reset hours counter to zero
    }
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
}


void loop() {
  SoftRTC(); // must be called very regular and repeatedly to update the 0.1 second time-ticks
             // this means you CAN'T use delay(). 
             // Each and every single delay() must be replaced NON-blocking timing
  if ( TimePeriodIsOver(MyTestTimer, 1000) ) { // if 1000 milliseconds have passed by
    PrintRTC_Data();                           // print time
  }
}

for longer periods of time often using

minutesOfDay = hour * 60 + minutes

makes it much easier to compare times because with minutesOfDay you have to compare only one single number

The standard blink-without-delay example code IMHO is "sub-optimal"
To explain a medium complex thing like non-blocking timing requires easy to follow example-numbers. Just a link or just a code without example-numbers makes it harder to understand.

and here is a demo-code for your 20 minutes timer.
Though 20 minutes are pretty long if you wait for a code to react
so I added a 20 seconds timer too


boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod ) {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}

unsigned long MyTestTimer = 0;  // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;

unsigned long My20SecTimer = 0; // Timer-variables MUST be of type unsigned long
unsigned long My20MinTimer = 0; // Timer-variables MUST be of type unsigned long

const unsigned long myLEDOnTime20Secs = 20000;
// 60 seconds
// 1000 milliseconds per second
// 20 minutes
const unsigned long myLEDOnTime20Minutes = 60 * 1000 * 20;

unsigned long secondsCounter = 0;

void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");

 // initailise timer-variables
  MyTestTimer  = millis();
  My20SecTimer = millis();
  My20MinTimer = millis();
}

void myFunctionPrintCounter() {
  secondsCounter++;
  Serial.print("keep on waiting..:");
  Serial.println(secondsCounter);
}



void loop() {
  BlinkHeartBeatLED(OnBoard_LED, 100);

  if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
    myFunctionPrintCounter();
  }


  if ( TimePeriodIsOver(My20SecTimer, myLEDOnTime20Secs) ) {
    Serial.println("20 seconds are over");
  }

  if ( TimePeriodIsOver(My20MinTimer, myLEDOnTime20Minutes) ) {
    Serial.println("20 minutes are over");
  }

}

Be the change you want to see in the world
best regards Stefan

Gee That was a short answer :slight_smile:

You should have that somewhere and just post a link rather than pasting it every time there is a millis() question

This is also over engineered for OP’s request

const byte switchPin = 2;
const byte ledPin = 13;

void setup() {
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  while (digitalRead(switchPin) == HIGH); // wait for press
  digitalWrite(ledPin, HIGH); // turn led ON
  delay(120000ul); // await 20 minutes doing nothing
  digitalWrite(ledPin, LOW); // turn led OFF
}

void loop() {}

(Untested typed from my iPhone)

that will work once. A quick and dirty hack to make it work multiple times would be to reboot at the end of the setup()

I will think about it. But I'm not yet sure if I will post a link or keeping posting it everytime new
Be the change you want to see in the world
best regards Stefan

Or you may use a NE555 simple.

imagine we would post the full text of How to get the best out of this forum every time someone requires a bit of guidance on how to use the forum...

yeah, why waste storage for duplicating your contents many times and use up internet bandwidth both for posting and reading every time... Posting a link is an easy way to protect a bit the planet...

I would like to say thanks to @StefanL38 for shortening your signature :wink:

good argument. The best solution would be if the Arduino-IDE- development-Team would be

brave enough

to change the

Arduino-IDE-examples

But I guess they are very afraid of doing such a change. I guess they will find a lot of arguments why this change would be a bad thing.

Well if you really want to change something you will find a way. If you don't want to change something you will always find reasons against the change.

I begin to like the idea of a link-collection....
Be the change you want to see in the world
best regards Stefan

Yes this was too long (and too annoying reading it every time)

Post that in the Tutorials section, then just reply with a link.

+1 on this :slight_smile:

I don't think it qualifies for an Arduino IDE example. Blink without delay is a good start for the fundamentals

Thank you for the code for the LED, would it be possible to have the LED steady on, and not using the heartbeat code?

removing lines of code is much easier than writing.

So as a future strategy you can DE-activate parts of a program through marking the part as "comment"

There is that line that says " execute that part of the code that is called "BlinkHeartBeatLED" This is this line

putting two slashes "//" at the left marks everything that is behind as "comment" a comment can by any sensless text or whatever because it is just a comment

so here the line "BlinkHeartBeatLED(OnBoard_LED, 100);"
is DE-activated but still present in the code

void loop() {
  // BlinkHeartBeatLED(OnBoard_LED, 100);

This version has the line "BlinkHeartBeatLED(OnBoard_LED, 100);"
active no comment-characters "//"
but two other lines with comments

void loop() {
   BlinkHeartBeatLED(OnBoard_LED, 100);
  // my comment blablba blublublub
  // uztaiuieiuadojpqweoidojd 

and there is the

definition

of a part of the code

void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}

this definition has multiple lines. multiple lines can be DE-activated by a block-comment which starts with slash-astersik "/" and ends with
asterisk-slash "
/"

block-comment

/*
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}
*/

So here is a code-version with the heartbeat DE-activated

boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod ) {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}

unsigned long MyTestTimer = 0;  // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;

unsigned long My20SecTimer = 0; // Timer-variables MUST be of type unsigned long
unsigned long My20MinTimer = 0; // Timer-variables MUST be of type unsigned long

const unsigned long myLEDOnTime20Secs = 20000;
// 60 seconds
// 1000 milliseconds per second
// 20 minutes
const unsigned long myLEDOnTime20Minutes = 60 * 1000 * 20;

unsigned long secondsCounter = 0;

/*
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}
*/

void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");

 // initailise timer-variables
  MyTestTimer  = millis();
  My20SecTimer = millis();
  My20MinTimer = millis();
}

void myFunctionPrintCounter() {
  secondsCounter++;
  Serial.print("keep on waiting..:");
  Serial.println(secondsCounter);
}


void loop() {
  // BlinkHeartBeatLED(OnBoard_LED, 100);

  if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
    myFunctionPrintCounter();
  }


  if ( TimePeriodIsOver(My20SecTimer, myLEDOnTime20Secs) ) {
    Serial.println("20 seconds are over");
  }

  if ( TimePeriodIsOver(My20MinTimer, myLEDOnTime20Minutes) ) {
    Serial.println("20 minutes are over");
  }
}

You seem to be a real beginner. If you want to become independant of asking even the most basic questions like this one and

To become able of modifying code yourself there is no way around learning to code C++
Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

I will answer more questions but just specific questions.

The minimum-effort that you have to do yourself is

  • posting a modified version of the code as a code-section
  • describing in normal words the behaviour of the code you want to have
  • describing in normal words the behaviour of the code you see
  • a specific question

I see anything that is below this as freeloading from laziness

Be the change you want to see in the world
best regards Stefan

I'll volunteer for that! What's the question? TL;DR...

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