Programming steps using millis()

Hi all,

I have got a sketch which turns on/off relay for a user defined on-time. The problem is my sketch uses the delay() function with a variable setTime assigning the mS values.

I would like to use millis() to determine how much time has passed since the relays were switched on, then switch them off after the required mS. The main reason for this so I can monitor an override switch to manually turn off the relay.

Getting my head around the logic required to use millis() properly here is proving troublesome. i.e. turn on the relay then start counting mS in a separate function?

Any pointers for me?

Many thanks.

Have you looked at the blink without delay example in the IDE?

Also look at recent topic of blinking 2 LEDs at different rates.

Getting my head around the logic required to use millis() properly here is proving troublesome.

millis() gives you the current time. Read and record the current time as the Start time. Calculate the End time by adding your variable time to the Start time. Keep reading the currnet time till it exceeds or is equal to your End time.

Your code does not sit there doing nothing as it would with a delay. Complex timing schemes can be boiled down to variations of the above.

This is simple and works. All time variables are unsigned long. I use micros() for clocks instead of millis().

void loop(){
currentTime = millis();

//and if its time to make one do something, do it and store the next time to check for an action:

if ( (currentTime - nextTime1) >= duration1){
nextTime1 = nextTime1 + duration1;
// do LED1 stuff
}

if ( (currentTime - nextTime2) >= duration2){
nextTime2 = nextTime2 + duration2;
// do LED2 stuff
}
} // end loop

Thanks a lot all.

Ok, the problem really is implementation. How does this look...

unsigned long setTime = 30000;
unsigned long startTime = millis();
relayOn(); //separate function
if (currentTime - startTime >= setTime)
{
relayOff();
}
unsigned long currentTime = millis();

Is my thinking correct or?

negativ3: Is my thinking correct or?

You're setting startTime microseconds before you check its value against the currentTime (assuming relayOn() doesn't take a long time to run), which means it's not likely to be greater than 0, let along greater than 30 seconds. You're also setting currentTime after you check it's value in your if statement, how is that supposed to work?

startTime should be set only when a condition is met to turn the relay on, and it shouldn't be set again unless you are intending to reset the 30 second count down.

I think making this a function makes it harder. I might try it like this, using a flag or two:

void loop(){
// is relay button or something similar  closed to Gnd, and the relay is currently off?
if ( (digitalRead (relayStartPin) == 0) && (relayOn == 0) ){  
relayStartTime = millis();  // note the start time
relayOn = 1;  // set a flag to show that relay is energized
digitalWrite (relayControlPin, HIGH);  // set the relay energization pin, say this turns on a transistor to sink coil current
// could also use the state of the control pin as the flag - I like a little indepence/flexibility in my code tho
}

//  if the relay is energized, see if it's time to turn the relay off
if ( (relayOn ==1) &&( (millis() - relayStartTime)>= relayOnTime) ){
relayOn = 0;
digitalWrite (relayControlPin, LOW);
}
//
// do other stuff in while time is passing  for the above
//
} // end loop

CrossRoads: I think making this a function makes it harder. I might try it like this, using a flag or two:

void loop(){
// is relay button or something similar  closed to Gnd, and the relay is currently off?
if ( (digitalRead (relayStartPin) == 0) && (relayOn == 0) ){  
relayStartTime = millis();  // note the start time
relayOn = 1;  // set a flag to show that relay is energized
digitalWrite (relayControlPin, HIGH);  // set the relay energization pin, say this turns on a transistor to sink coil current
// could also use the state of the control pin as the flag - I like a little indepence/flexibility in my code tho
}
//  if the relay is energized, see if it's time to turn the relay off
if ( (relayOn ==1) &&( (millis() - relayStartTime)>= relayOnTime) ){
relayOn = 0;
digitalWrite (relayControlPin, LOW);
}
//
// do other stuff in while time is passing  for the above
//
} // end loop

Quite elegant sir CrossRoads. I have moved my "setTime" function call to void setup (out of the main loop) and am using the main loop to check the relay condition and timing as you have hinted.

Many thanks for the help all.