I am looking to use the DS3231 I2C RTC for a data logging project and I have been trying and failing to find a nice way to find out when the next nice round 5 Minute time value is reached....
The RTC can give total seconds since the begining of time itself (ie year 2000) with now.get()
2012/12/6 18:26:11 Fri
Seconds since 1/1/2000: 408133571
I am hoping to find the next round 5 minute time value and start logging from then:
So the time I am interested in, relative to the time above, would be 18:30:00.
Any idea how I would calculate a new 'rounded seconds count value' (ie the 408133571 number) so that I can evaluate it against the current time and then proceed when one equals the other?
Thanks folks - I now have 3 working choices, wonderful. I'm just testing the 'if ((now.minutes % 5) == 0 && now.seconds == 0)' method overnight to see how we go.
I will also run a test on the interupt method - the DS3231 can generate an interupt every minute so I guess I could simply check the time at the point of interrupt with 'if ((now.minutes % 5) == 0 {LogData()};' which would give logged data every 5th interupt.
...now, one of those questions - Arduino has absolutely nothing to do whilst it waits for the next interupt so.... what is the best way to do absolutely nothing.... whilst waiting for a minute to go by ?
point5:
Thanks folks - I now have 3 working choices, wonderful. I'm just testing the 'if ((now.minutes % 5) == 0 && now.seconds == 0)' method overnight to see how we go.
I will also run a test on the interupt method - the DS3231 can generate an interupt every minute so I guess I could simply check the time at the point of interrupt with 'if ((now.minutes % 5) == 0 {LogData()};' which would give logged data every 5th interupt.
...now, one of those questions - Arduino has absolutely nothing to do whilst it waits for the next interupt so.... what is the best way to do absolutely nothing.... whilst waiting for a minute to go by ?
volatile int not_time = 1;
while(not_time) {}
Will just stay in a type loop until in your interrupt routine you set the not_time variable to 0.
Or if you like to look hip like all the other C programmers are.
point5:
The RTC can give total seconds since the begining of time itself (ie year 2000) with now.get()
The number of whole five-minute increments since epoc would be
now.get() / 300
If the value changes then you know that a five minute interval has just passed. You could use the polling technique demonstrated in 'blink without delay' to detect the change, using the expression above in place of 'millis()'. With this approach, detection of the 'five minute crossing' can be done concurrently with serial port handling, elapsed interval detection, switch handling etc all in a consistent structure.
Thank you all - my code is now so much neater and works a treat
I'm using an interrupt flag 'alarmFlag' to control the flow - the RTC interrupt is fired every minute on the minute with every interrupt ocurring at a 5minute value resulting in simple/logging.
This is what I ended up with:
void loop ()
{
while(alarmFlag != true) {}
DateTime now = RTC.now();
if ((now.minute() % 5)==0)
{
Sample the sensors and write to SD.
}
else
{
alarmFlag = false;
RTC.clearINTStatus();
}
}
Since you are already using an isr, you can simply your code this way:
ISR: (assuming this fires every second)
static sec_counter=0;
sec_counter+=1;
if (sec_counter >= 60*5) { //if 5 minutes have passed
sec_counter -= 60*5; //reset sec_counter
alarmFlag=1; //set the flag
}
}
user code
void loop(void) {
...
if (alarmFlag) {
alarmFlag = 0; //reset the flag
do_something();
}
...
}