Very long timed-driven event

I need to build a project that does a certain task every week or 2 weeks when a certain condition is met, specifically: Condition A+B met -> start 2~week timed interval -> perform task for X minutes ->stop and wait for Conditions A+B cycle With a very large delay i could do this i know, the problem is that the A/B conditions CAN CHANGE during the interval and must force a reset of the timer, so i can't simply use a delay because the arduino wouldn't be doing anything else in the meantime.

What i've been considering: 1) using Time library, but that's for an absolute RTC(ofc i could simply ignore the "real date" and play with the seconds results) but i think there must be a more elegant approach 2) using a modified timedaction for long intervals so i can check for conditions A+B and do other stuff whilst the system counts 3) using Delay with a 1209600000 value(60*60*24*14*1000=mS) and setting input for A and B as an interrupt source, which should efefctively abort the delay(but i lost ability to do anything else that's not related to A and B) 4) use milis() and compare to the 1209600000 value

i think option 4 is the more elegant, but i'm not an Arduino pro, you guys are :)

There is no reason why (2) or (4) shouldn't work. I agree more with (4), I'd always do my own timer counting. You can check the millis() and your "stop/break/reset" conditions in the loop. Interrupts are tricky things and avoided unless necessary, IMHO.

The long unsigned timer wraps at around 49 days, so 2 weeks is less than half, giving you a "safe margin". The chip really counts to 1209600000 as well as to just 100, people worry needlessly about a chip "wearing out". I've done a project that needed the program to run several months. Worked fine. Just keep feeding the board with fresh electrons ;)

I’d go with option 4, maybe something like this

void loop(){

// read A&B conditions, decide if starting
if ((started == 0) && (A&B meet start condition)){
starttime = millis();  // capture the current time
endtime = starttime; // set the end time to the current time
started = 1; // flag to say long event is started
// see how long it has been
endtime = millis(); // capture the time
elapsedtime = endtime-starttime; // calculate how long it has been

if ((started == 1) && (elapsedtime <= duration){  // check if its time to stop
// not done, keep doing long duration stuff
else {
// stop doing long duration stuff
// reset for the next duration
started = 0;

// do other program stuff 

}// end void loop

there are soem things i’m having a hard time wrapping my head around, specifically the overflow of millis and the nightmare of signed/unsigned…
Crossroads, interesting code, a couple questions:
why do you do a endtime = starttime; // set the end time to the current time in the “started set” if?
how does your code handle the wraparound?(taken from the timingrollover example), i.e.:
millis wrapped, that means that endtime - starttime is negative (since you don’t declare type, what data type is elapsedtime?, unsigned long?, long?, how does the compiler take it?) and so elapsettime is <= duration but it doesn’t means that it’s time to stop…
if it doesn’t wraps then it works ok.

what happen when you convert a big unsigned long to a long?, what happens to the values above the signed limit(2147483647)?

Also, instead of the 2nd if, should’t it be better a while, or do…while?, like while counter != endvalue then do X Y Z stuff?

Also as well, since if the conditions a/b change i need to reset it, it’s better to do a while or do…while(can’t decide which), i need to write some example code i see…

First, there is no nightmare. Make all the variables associated with time/millis unsigned long. Then there is no negative, its always some number from 0 to 492million (2^32) minus another number in the same range. Then do all the time calculations as (later_time) - (earlier_time). Then if you have something going on around day 49, and you go across the rollover, you'll get a valid result. for example 0x0000 0020 (a later time) - 0xFFFF FF20 (an earlier time) = 0x0000 0100.

I set endtime = starttime so the first calculation starts at 0. I didn't use a while( miniloop) because you indicated other stuff would be going on.

And after all, it was just something for you to build on. Put in some shorter durations and try it out, with LEDs going on/off or something to simulate your other actions occurring.