Turn pin HIGH for 1 minute without delay()

What would be the simplest way to set some pins HIGH and hold them HIGH for one minute, not using delay?

logitech: What would be the simplest way to set some pins HIGH and hold them HIGH for one minute, not using delay?

Use the TimerOne library or setup an ISR. Run the ISR at, say, 100 times per second.

Do something like this OUTSIDE the ISR:

uint32_t timeout = 100 * 60;
uint8_t flag = 1;
digitalWrite (myPin, HIGH);

Then put something like this in the ISR function:

if (timeout && flag) {
    timeout--;
} else {
    digitalWrite (myPin, LOW);
    flag = 0; // prevent any more digitalwrite low
}

Your pin will go low after 60 seconds, and other code will be able to run in the mean time.

Or use blink without delay. Every pass thru loop, see if a minute has elapsed since you started checking the time and set the pins high; when it has, clear the pins. Something like this:

void loop(){
currentTime = millis();
if ( (digitalRead(startButton) == LOW) || (timeRunnning == 1)){ // pin with internal pullup, button 
if (timeRunning == 0){
startTime =millis();
timeRunning = 1; // flag to show timer is started
// set output pins HIGH
}
elapsedTime = currentTime - startTime;
if (elapsedTime >=oneMinute){
// set output pins LOW
timeRunning = 0;
}
} // end time check 
} // end loop

Same thing but implemented in a slightly different way

unsigned long startTime;
unsigned long interval = 60000;
const byte aPin = 13;

void setup() 
{
  pinMode(aPin, OUTPUT);
  digitalWrite(aPin, HIGH);
}

void loop() 
{
  if (millis() - startTime >= interval)
  {
    digitalWrite(aPin, LOW);
  }
  //do other stuff here every time through loop()
}

Thank you all very much for your replies, but what if I have:

void setup () 
{
     ...
}

void loop () 
{
     if () 
     {
          ...
     } 
     else if 
     {
           if (something) {

                  and NOW HERE "MY PIN" should go HIGH and stay HIGH for 1 minute
             
          }
     }
}

logitech: Thank you all very much for your replies, but what if I have:

Include some code that functions like the examples that you have been given.

...R

It doesn’t really matter where in your code you write the pin HIGH just that you get the time that it happened. So that you can calculate when the desired interval has passed.

if (CurrentMillis - StartMillis >= IntervalMillis) is true, you’re done turn it off.

My attempt at a text-book answer:

#define SECOND 1000UL
#define MINUTE (60 * SECOND)

#define OUTPUT_PIN ???
#define BUTTON_PIN ???
#define BUTTON_DOWN  LOW    // active low button

boolean pin_active = false ;

unsigned long pin_starttime ;

void setup ()
{
  pinMode (OUTPUT_PIN, OUTPUT) ;
  pinMode (BUTTON_PIN, INPUT_PULLUP) ;  // pullup used for active low button
}

void check_pin ()
{
  if (pin_active)   // pin active, only check for timeout
  {
    if (millis () - pin_starttime >= MINUTE)  // wraparound-safe timeout test
    {
      pin_active = false ;   // change state
      digitalWrite (OUTPUT_PIN, LOW) ;
    }
  }
  else  // pin not active
  {
    if (digitalRead (BUTTON_PIN) == BUTTON_DOWN) // just check for button
    {
       pin_active = true ;  // change state to active
       digitalWrite (OUTPUT_PIN, HIGH) ;
       pin_starttime = millis () ;   // setup for timeout testing
    }  // debouncing not needed since button won't be sensed again for a miniute...
  }
}

void loop ()
{ 
  check_pin () ;  // keep loop simple - a list of calls to handle various things
  ..
  ..
}
if (something) {

                  and NOW HERE "MY PIN" should go HIGH and stay HIGH for 1 minute

That is like my example; waits for a button push to start the one minute. Can be an occurrence of whatever you wish. If you include a flag to track that you are in the one minute period, you can ensure that it does not start again until the flag is cleared. Or you can leave the flag out, and let the one minute restart with every button push, only ending when one minute after the last push has occurred.

"My attempt at a text-book answer:"

I don't like text book answers, especially for embedded stuff. All the jumping back & forth, popping stuff on & off the stack & heap, would seem to me to make things run slower, and having everything broken out as function calls makes the code hard to read. I much prefer writing in-line code.

CrossRoads: "My attempt at a text-book answer:"

I don't like text book answers, especially for embedded stuff. All the jumping back & forth, popping stuff on & off the stack & heap, would seem to me to make things run slower, and having everything broken out as function calls makes the code hard to read. I much prefer writing in-line code.

Erm, the "inline" keyword not appeal then?

Sorry, I don’t understand your question MarkT.

Thank you all once more, all of your suggestions worked for me. Just one more question, not so connected with this one. I'm learning a bit about time interrupts and I'm using TimerOne library. I have made an ISR that reads an analog pin and prints the value on serial monitor. But when using initialize(period) I put the period about 100 and less nothing gets printed and when period is bigger then 100 same thing gets printed a couple of times. Can you tell why that is?

Not without seeing the code behind what you are talking about.

Can you tell why that is?

Reading an analog pin takes time. That may not be a reasonable thing to do in an ISR. Printing to serial requires interrupts be enabled, which they are not during an ISR. That is DEFINITELY not a reasonable thing to do in an ISR.

#include <TimerOne.h>
volatile int old_b = 0;
volatile int pressed;

void setup () {                             
    pinMode (A5, INPUT_PULLUP);            
    Timer1.initialize(100);                    
    Timer1.attachInterrupt(readButton);       
    Serial.begin(9600);                       
}

void readButton () {                               
  int b, c;                                         
  c = analogRead(5);                             
  if (b == old_b) {
    old_b = b;
    pressed = 0;
  } 
  else {
    old_b = b;                                 
    pressed = b;                             
  }                           
}                   

void loop () {
       Serial.println(pressed);
}
void readButton () {                               
  int b, c;                                         
  c = analogRead(5);                             
  if (b == old_b) {
    old_b = b;
    pressed = 0;
  } 
  else {
    old_b = b;                                 
    pressed = b;                             
  }                           
}

Local variables (b and c) are not initialized. You should never use uninitialized local variables in any test.

Why read from the analog pin if you don't care about the value? Why are you storing garbage in old_b as though it has some significance?

CrossRoads: Sorry, I don't understand your question MarkT.

"A function declaration [ . . . ] with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected." — ISO/IEC 14882:2011, the current C++ standard, section 7.1.2

IE no need to write poorly structured code (or arcane macrology) to persuade appropriate compiler optimizations, you tell the compiler which functions are probably best inlined.

Poorly structured code has more bugs and is harder and more expensive to maintain.

Inline declarations are easy to add/remove to see what effect it has, much easier than refactoring the code!

please sir anyone help me i am new to arduino i am using dtmf decoder for controlling water pump with mobile phone and i need to turn on a relay for 2 hour and then turn off for 12 hour , if i apply delay of two hour and 12 hour then it will not respond to dtmf decoder until it completes 2 and 12 hour delay , i also try mill() function to control the relay , but i did not sucess because if the turn on time gives more than 1 minute it will always gives high output even after the 1 minute

i also try mill() function to control the relay ,

Post the code that you tried