Go Down

### Topic: Looking for 5 minutes - the next nice round 5 minutes. (Read 1 time)previous topic - next topic

#### point5

##### Dec 06, 2012, 07:45 pm
Hi,

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()
Code: [Select]
`2012/12/6 18:26:11 FriSeconds 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?

long now = 408133571
long rounded = 40813xxxx ?

If now = rounded then..... do something.

Thanks for any help.

#1
##### Dec 06, 2012, 07:56 pm
Code: [Select]
`const unsigned long SecondsPerMinute = 60UL;const unsigned long RoundToInMinutes = 5UL * SecondsPerMinute;unsigned long now = 408133571;unsigned long rounded = ((now + (RoundToInMinutes - 1)) / RoundToInMinutes) * RoundToInMinutes;`

#### johnwasser

#2
##### Dec 06, 2012, 09:03 pm
Assuming the RTC can also return minutes and seconds you could try:
Code: [Select]
`   if ((now.minutes % 5) == 0 && now.seconds == 0)`
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

#### dhenry

#3
##### Dec 06, 2012, 10:12 pm
You can poll the rtc - not terribly efficient.

Or you can use the rtc to trigger interrupt and use the mcu to keep track of elapsed time to 5 minutes.

The 2nd approach is more efficient as it doesn't tie up the mcu.

#### point5

#4
##### Dec 06, 2012, 10:52 pm
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 ?  :-)

#### retrolefty

#5
##### Dec 07, 2012, 12:34 amLast Edit: Dec 07, 2012, 12:49 am by retrolefty Reason: 1

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 ?  :-)

Code: [Select]
`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.

Code: [Select]
`volatile boolean time_is_up = false;while(!time_is_up) {}`

#### dhenry

#6
##### Dec 07, 2012, 12:43 am
Quote
what is the best way to do absolutely nothing

You can just leave it looping around.

Or to put it to sleep, if your interrupt can wake up the mcu.

#### PeterH

#7
##### Dec 07, 2012, 01:27 am

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
Code: [Select]
`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.
I only provide help via the forum - please do not contact me for private consultancy.

#### point5

#8
##### Dec 07, 2012, 01:34 pmLast Edit: Dec 07, 2012, 01:38 pm by point5 Reason: 1
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:

Code: [Select]
`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();    }} `

Happy days.

#### dhenry

#9
##### Dec 07, 2012, 02:08 pm
Code: [Select]
`    while(alarmFlag != true) {} `

Unless alarmFlag is set in an interrupt, you will never get out of that loop.

#### point5

#10
##### Dec 07, 2012, 04:47 pm
This is my ISR:

Code: [Select]
`void Alarm(){    alarmFlag = true;}`

#### dhenry

#11
##### Dec 07, 2012, 05:12 pm
Since you are already using an isr, you can simply your code this way:

Code: [Select]
`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 codevoid loop(void) {  ...  if (alarmFlag) {    alarmFlag = 0; //reset the flag    do_something();  }  ...}`

So it runs do_something() once every 5 minutes.

#### point5

#12
##### Dec 07, 2012, 09:57 pm
Thanks dhenry - I guess thats kinda handy if you don't have an onboard RTC - do you know how accurate that method is by any chance?

I am now trying to get this all to work with sleep mode - making progress slowly.

Could I ask if:

Code: [Select]
`/*Initialize INT0 for accepting interrupts */     PORTD |= 0x04;      DDRD &=~ 0x04;`

...is the same as attachInterrupt ?  and if not what is it doing and is there an Arduino way of coding the same thing?

#### dhenry

#13
##### Dec 07, 2012, 10:25 pm
Quote
do you know how accurate that method is by any chance?

It is as accurate as the rtc is.

Quote
if not what is it doing and is there an Arduino way of coding the same thing?

It sets a pin (PD.2) and turns it as input -> with pull-up.

Go Up

Please enter a valid email to subscribe