my code is working but not exactly as desired

the code should water the plant at 9am and 4pm. but it has been slipping ahead by around 30-45mins every other day! monday:9am & 4pm, tues: 9:35am & 4:35 pm, wed: 10:10am & 5:10pm........the distance between morning and evening watering events is constant all the time(7 hours). why does it slip ahead every morning? is something wrong logically?

/*goal of this code is to activate a transistor(transistor is connected to A0 of arduino. pin13 is just
 used as an indicator), which in turn, turns on a relay and the relay powers a submersible motor in a 
water filled container. the motor waters the plant. the arduino is battery powered. The relay and 
motor take power in from ac mains. So each time before activating the motor,

the arduino checks whether mains supply is available and only then proceeds. The arduino does this 
by checking for input at pin 7. pin 7 is fed by a wall wart from mains and is connected to gnd by pull 
down resistor. And this check is performed using a while loop. i need to water the plant twice each 
day(9 am and 7 hours later at 4 pm). pseudo code would be: initialize all variables to 0. store millis() 
into timenow. read pin7 and store it in val. use while loop to check if supply is on. inside the while 
loop, i once again feed millis() into timenow5. and then feed timenow5 into timenow6. this is so that i 
can calculate the time for which there was no power and account for this fact when watering the 
plant. so for example, if there is no power at 9 am, and it only comes back at 10 am, the arduino can 
know, by doing (timenow6-timenow), that the watering has been delayed by an hour.the timenow7 
variable exists to handle any overflow that might happen(its not an issue now. happens once in 50 
days or so. and its been only 5 days since the project went live). so when the power comes back, it 
breaks out of the while loop, waters the plant and waits for 7 hours(minus the 1 hour delay due to 
power cut). The exact whole thing is happening all over again in the second part of the program i.e. 
where there is the second while loop to water at 4pm.*/

int motorPin = A0;
int blinkPin = 13;
int checksupplyPin = 7;
long watertime = 10000; // how long to water in miliseconds

void setup()
{
 pinMode(motorPin, OUTPUT);
 pinMode(blinkPin, OUTPUT);
 pinMode(checksupplyPin, INPUT);
}

void loop()
{
 int val1 = 0;
 long timenow2 = 0;
 long timenow3 = 0;
 long timenow8 = 0;
 long timenow9 = 0;
 long timenow = 0;
 long timenow5 = 0;
 long timenow6 = 0;
 long timenow7 = 0;
 int val = 0;
 timenow = millis();
 val = digitalRead(checksupplyPin);
 //while loop to check if external ac mains supply is available. the arduino itself is battery powered. 
 while(val != 1){
   delay(100);
   timenow5 = millis();
   if (timenow5 > timenow){
     timenow6 = timenow5;} else{
       timenow7 = timenow5;}
   val = digitalRead(checksupplyPin);
      
   }


 digitalWrite(motorPin, HIGH);
 digitalWrite(blinkPin, HIGH);
 delay(watertime);
 digitalWrite(motorPin, LOW);
 digitalWrite(blinkPin, LOW);
 if (timenow6 == 0){delay(25200000-timenow7);} else{
   delay(25200000-((timenow6-timenow)+timenow7)+watertime);}

 timenow3 = millis();
 val1 = digitalRead(checksupplyPin);
 while(val1 != 1){
   delay(100);
   timenow2 = millis();
   if (timenow2 > timenow3){
     timenow8 = timenow2;} else{
       timenow9 = timenow2;}
   val1 = digitalRead(checksupplyPin);
     }
 digitalWrite(motorPin, HIGH);
 digitalWrite(blinkPin, HIGH);
 delay(watertime);
 digitalWrite(motorPin, LOW);
 digitalWrite(blinkPin, LOW);
 if (timenow8 == 0){delay(63000000-timenow9);} else{
   delay(63000000-((timenow8-timenow3)+timenow9)+watertime);}
   
}

You really should have read the How to use this forum - please read post at the top of the index page and How to use this forum before posting.

ie Your code and any error messages should always be placed between code tags. Posting it inline as you have done makes it much harder to read or copy and paste for diagnosis.
(And you should already know this after 22 posts on these forums.)

It’s still not too late to edit your post and do this. You’ll make potential helpers much happier. :slight_smile:

And RTCs are cheap, (<$5). Even with the maths bugs removed from your program, an Arduino isn’t suited to accurate, long-period timing like this.

OldSteve:
You really should have read the How to use this forum - please read post at the top of the index page and How to use this forum before posting.

ie Your code and any error messages should always be placed between code tags. Posting it inline as you have done makes it much harder to read or copy and paste for diagnosis.
(And you should already know this after 22 posts on these forums.)

It’s still not too late to edit your post and do this. You’ll make potential helpers much happier. :slight_smile:

And RTCs are cheap, (<$5). Even with the maths bugs removed from your program, an Arduino isn’t suited to accurate, long-period timing like this.

apologies to all for discrepancies.all done now

cloud9: apologies to all for discrepancies.all done now

No worries. That looks much healthier now.

So, have you considered buying an RTC, (Real Time Clock), module? It would make this project much more accurate, and using a library, pretty easy to write code for. Take a look here:- Time

I'm sure your code could be sorted out, (though not by me right now, it's 11.30pm and I'm headed for bed), but an RTC is the best option IMHO.

 long timenow2 = 0;
 long timenow3 = 0;
 long timenow8 = 0;
 long timenow9 = 0;
 long timenow = 0;
 long timenow5 = 0;
 long timenow6 = 0;
 long timenow7 = 0;

Wait, what time is it NOW? The logic in your program is crazy. I can't even begin to follow it.

Understand that all of these are local to loop. So they get reset to 0 every time loop restarts.

Have a look at the Time library and see if you're not inspired to throw this whole thing away and start over with something that makes a little more sense and actually looks at the real time.

Even with that, Arduino is a really shitty timekeeper over the long haul. An RTC would really be in order if you want to know what time it really is.

check out this thread, it uses an RTC to do exactly what you are looking to do.

OldSteve:
No worries. That looks much healthier now.

So, have you considered buying an RTC, (Real Time Clock), module?
It would make this project much more accurate, and using a library, pretty easy to write code for.
Take a look here:-
Time

I’m sure your code could be sorted out, (though not by me right now, it’s 11.30pm and I’m headed for bed), but an RTC is the best option IMHO.

definitely oldsteve, have considered getting an RTC. was putting it off coz i thought it would be tedious to learn to use the time library. Also i wanted to know whats fundamentally wrong with my code, just to improve my coding .to rectify without using RTC would be only a stopgap and the plant is too rare to take such a risk.

cloud9: Also i wanted to know whats fundamentally wrong with my code

The logic with all those timenow variables is way too convoluted for anyone to tell. The whole thing needs to be scrapped unless you can explain each line to us and what you think each line does and how the math is supposed to fit together to make it do what you want. In doing that, if you can, you will probably find your logic error.

The Time library isn't hard to figure out. Go have a look at some of the example sketches with it.

cloud9: definitely oldsteve, have considered getting an RTC. was putting it off coz i thought it would be tedious to learn to use the time library. Also i wanted to know whats fundamentally wrong with my code, just to improve my coding .to rectify without using RTC would be only a stopgap and the plant is too rare to take such a risk.

If a precious rare plant's is at stake, I would follow Delta_G's recommendation and start over.

It's hard to follow your code but even harder to follow your description of how you are adjusting your timers...

and then there is this:

the code should water the plant at 9am and 4pm. but it has been slipping ahead by around 30-45mins every other day! monday:9am & 4pm, tues: 9:35am & 4:35 pm, wed: 10:10am & 5:10pm........the distance between morning and evening watering events is constant all the time(7 hours). why does it slip ahead every morning? is something wrong logically?

you really cannot accomplish this requirement without an RTC, unless you want to sync your arduino with another source of time, like the internet for example.

Delta_G: long timenow2 = 0; long timenow3 = 0; long timenow8 = 0; long timenow9 = 0; long timenow = 0; long timenow5 = 0; long timenow6 = 0; long timenow7 = 0;

Wait, what time is it NOW? The logic in your program is crazy. I can't even begin to follow it.

Understand that all of these are local to loop. So they get reset to 0 every time loop restarts.

Have a look at the Time library and see if you're not inspired to throw this whole thing away and start over with something that makes a little more sense and actually looks at the real time.

Even with that, Arduino is a really shitty timekeeper over the long haul. An RTC would really be in order if you want to know what time it really is.

yeah Delta_g, the logic is a bit crazy. there are 2 aspects that am looking to deal with simultaneously. First, there can be a power outage. Next, the millis() counter might overflow and start over at any point in the program. hence the use of so many time variables. Am thinking of switching over to using an RTC at the earliest. that said, it would still be good to know where my code is faulty coz that would help my coding in general

cloud9: Next, the millis() counter might overflow and start over at any point in the program.

If you understand how unsigned math works and write time comparisons properly, this won't matter even a little bit. The concept has been discussed ad nauseam on this form.

Like I said, if you can explain the logic in each of those lines then I'll help you find the hole in it. But I'm not going to try to figure out what you were thinking.

BulldogLowell: check out this thread, it uses an RTC to do exactly what you are looking to do.

thanks bulldoglowell

Delta_G: If you understand how unsigned math works and write time comparisons properly, this won't matter even a little bit. The concept has been discussed ad nauseam on this form.

if its not too much of an effort, could you provide a link.

Delta_G: The logic with all those timenow variables is way too convoluted for anyone to tell. The whole thing needs to be scrapped unless you can explain each line to us and what you think each line does and how the math is supposed to fit together to make it do what you want. In doing that, if you can, you will probably find your logic error.

Like I said, if you can explain the logic in each of those lines then I'll help you find the hole in it. But I'm not going to try to figure out what you were thinking.

k delta_g, i'll provide a full explanation soon

cloud9: if its not too much of an effort, could you provide a link.

Look in your IDE under the File -- Examples menu at Blink Without Delay.

Or hit the search box on this forum for either "Blink Without Delay" or "Millis rollover".

The best link to understand millis() rollover is http://www.gammon.com.au/millis

Any time you have numbers in your variable names then you either need an array or you have stupid variable names. Just by looking at it nobody, including yourself, can quickly understand why timenow9 is added or subtracted. If you gave it a name like TimeSince9am then you might have a better chance of working out where you went wrong.

You have also filled the code with magic numbers. What does 630000000 mean? If you wrote 4*60*60*1000 then it is more easily interpreted as 4 hours. Then only write that in one place: at the top where you declare the constant. While the Arduino is very slow at multiplication, the compiler knows this too and it will do the multiplication during the compilation so the Arduino doesn't have to do that calculation.

MorganS: The best link to understand millis() rollover is http://www.gammon.com.au/millis

Any time you have numbers in your variable names then you either need an array or you have stupid variable names. Just by looking at it nobody, including yourself, can quickly understand why timenow9 is added or subtracted. If you gave it a name like TimeSince9am then you might have a better chance of working out where you went wrong.

You have also filled the code with magic numbers. What does 630000000 mean? If you wrote 4*60*60*1000 then it is more easily interpreted as 4 hours. Then only write that in one place: at the top where you declare the constant. While the Arduino is very slow at multiplication, the compiler knows this too and it will do the multiplication during the compilation so the Arduino doesn't have to do that calculation.

thanks morgans, for the link. i'll soon post a detailed explanation of my code explaining all the variables. 63000000= 17.5 hours. 4 pm evening to 9:30 am next day the morning. then again wait for 25200000= 7 hours i.e. until 4:30

oh, oops i think i made a big mistake. Now that i think of it, if am telling the arduino to water after 17.5 hrs, it'll cause the 30 min slippage that i have been talking about. jesus, maybe nothing's wrong with my code after all. I'll check once again tomorrow morning and report back. am not sure yet, but guys really sorry for wasting your time. But like i said, i still have some doubt- maybe the code really is flawed.

cloud9: maybe the code really is flawed.

Yes it is. If it happens to work then that's kind if like the old adage that even a blind squirrel occasionally finds a nut. But this code is definitely a mess.

Delta_G: Yes it is. If it happens to work then that's kind if like the old adage that even a blind squirrel occasionally finds a nut. But this code is definitely a mess.

yeah, will start over with an RTC. the plant is so rare i got it 800 miles away from home- and that too unexpectedly. cant risk losing it

cloud9: the code should water the plant at 9am and 4pm. but it has been slipping ahead by around 30-45mins every other day!

So, it slips by about 1 in 100. Gotta tell you - 1% tolerance is pretty good. If you want better than that, you will need to invest in a real-time clock with an onboard crystal etc and work out how to talk to it.

learning is fun!