I'm currently working on a plant watering system, using a DS1302 RTC module I had laying around.
The idea is that the pump runs for 5 seconds straight daily. As of this moment the exact pumping moment is still pre-programmed, which is fine for now.
So far the RTC works, the pump does his 5 second action when commanded, however... immediately after the delay is where things seem to get odd. In the serial monitor I can see that the date remains the same, but the time resets to 0:0:0 and continues counting from there.
So, I was wondering:
Could it be the delay that causes this strangeness, is it something in my sketch that could cause this to happen or would it be something else?
#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(6, 7, 8);
int pompPin = 12;
void setup() {
Serial.begin(9600);
pinMode(pompPin, OUTPUT);
// seconds, minutes, hours, day of the week, day of the month, month, year
//myRTC.setDS1302Time(00, 01, 20, 6, 6, 5, 2020);
}
void loop() {
myRTC.updateTime();
Serial.print("Current Date / Time: "); //|
Serial.print(myRTC.dayofmonth); //|
Serial.print("/"); //|
Serial.print(myRTC.month); //|
Serial.print("/"); //|
Serial.print(myRTC.year); //|
Serial.print(" "); //|
Serial.print(myRTC.hours); //|
Serial.print(":"); //|
Serial.print(myRTC.minutes); //|
Serial.print(":"); //|
Serial.println(myRTC.seconds);
if (myRTC.hours == 20 && myRTC.minutes == 25 && myRTC.seconds > 1 && myRTC.seconds == 1) //stel hier de tijd in
{
Pompen();
}
delay(1000);
}
void Pompen() {
digitalWrite(pompPin, HIGH);
Serial.println("POMPEN");
delay(5000); //stel hier de pomptijd in
//digitalWrite(pompPin, LOW);
myRTC.updateTime();
}
UKHeliBob:
Why do you need the delay()s in the first place when you have an RTC to do timing with ?
myRTC.updateTime();
What does this do ?
What is the RTC time before and after the function call ?
Thanks for your reply, let me answer your questions:
-Good point. Could you provide any guidance on how to use the timer to set the output pin?
-In all honesty I can't tell you what the myRTC.updateTime() exactly does. I assumed it was mandatory for a correct time and it was used in the exaple sketch which was provided with the RTC library.
-I haven't tested to see what the time is before and after the function call
Do you think it might be the function call that confuses the RTC?
... ever be true, since that would require myRTC.seconds to be both equal to and greater than 1 at the same time?
Thank you for your response.
-I looked up some examples on Google and found someone else using the if condition in combination with an RTC module. Would you suggest using another statement instead?
-I'm don't fully understand what you mean. My idea was to 'pause' the loop by pulling the pin high and then inducing a delay as soon as the timer reaches the first second of the minute.
Edit: I see what you mean now! This was a mistake, my bad...
I haven't tested to see what the time is before and after the function call
Try it and see
Could you provide any guidance on how to use the timer to set the output pin?
Well, you could save the time when something starts and then monitor the time until the required period has passed then take the subsequent action. I am afraid that the best way to deal with this would be to restructure the program entirely into a "state machine" as the program is only ever in one of a few states.
However, if you really don't mind the program stalling during the delay()s then there is nothing wrong with using them but don't come back later and ask how to add a button that stops the pump during the delay()
I noticed that several of RTC modules were not keeping good time and would occasionally reset themselves. After extensive testing and several communications with the manufacturer it was discovered that they were counterfeit chips in a genuine module.
UKHeliBob:
Try it and see
Well, you could save the time when something starts and then monitor the time until the required period has passed then take the subsequent action. I am afraid that the best way to deal with this would be to restructure the program entirely into a "state machine" as the program is only ever in one of a few states.
However, if you really don't mind the program stalling during the delay()s then there is nothing wrong with using them but don't come back later and ask how to add a button that stops the pump during the delay()
Thanks for your advice.
I'm fine with restructuring the program. Could you elaborate some more on your idea to implement states?
blewtobits:
I noticed that several of RTC modules were not keeping good time and would occasionally reset themselves. After extensive testing and several communications with the manufacturer it was discovered that they were counterfeit chips in a genuine module.
That's quite interesting. As a matter of fact I'm using a counterfeit module. Might consider swapping it with another, just to be sure.
Klavkjir:
Might consider swapping it with another, just to be sure.
If that involves a purchase (as opposed to digging another one out of your parts box) you might as well upgrade to a DS3231. More accurate, I2C so fewer pins....
Indeed. That's what I did. Maxim (the original chip manufacturer) sent me a couple of genuine chips in exchange for a counterfeit, and everything worked. The only trouble was I was getting the modules from a reputable source so I never knew what was fake or genuine. The only way of knowing was to remove the battery, power up, read the date. It should be 01/01/00 00: and a few seconds. The fake chips would usually -not always- generate a random, sometimes invalid date like 43/15/67 33:87 but would sort themselves out after setting the correct date and time. I incorrectly assumed that this was normal. I compared the scope traces of the fake chip 32768 Hz outputs against a genuine, the difference was quite noticeable after an hour or so. The worst chip would gain about 2 minutes a month. I also compared the crystal output of a standard wall clock and even that was different, although the probe impedance may have skewed the reading.
First list the states that the program can be in and give them names. Maybe
WAITING_TO_PUMP
PUMPING
Then at the start of the program declare an enum
enum states
{
WAITING_TO_PUMP,
PUMPING
};
Declare a new byte variable named currentState and set its value to WAITING_TO_PUMP
Then all of the normal setup() function stuff. Leave loop() empty for the moment and post your code so far when you have done all of the above and I will provide more advice on the next steps