Triggering Interrupts with Real Time Clock

How would I use a RTC (such as the DS1307) to trigger an interrupt? The overall goal is to put the processor to sleep and then wake it after an hour or so. I looked at using a watchdog timer, but it only goes up to 8 seconds and is reportedly unreliable.

Other info:
Data logging kit w/ RTC - Adafruit Data logging shield for Arduino [v1.0] : ID 243 : $24.80 : Adafruit Industries, Unique & fun DIY electronics and kits
Fourm post that alludes to using an RTC as an interrupt - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1291420085
Watchdog tutorial - http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
RTClib - GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library

To clarify, I understand how interrupts work; I just don't know how to implement one using the RTC. I don't get how the interrupt is supposed to trigger if the RTC has to be called to get the time (The code uses DateTime now = RTC.now(); to get a snapshot of the current time).

tl;dr How do you trigger an interrupt using an RTC such as the DS1307?

I looked at using a watchdog timer, but it only goes up to 8 seconds and is reportedly unreliable.

I know about the eight second limit, but I've never heard of an unreliable watchdog - what would be the point?

Eight second periods can be stacked, one after the other.

Some RTCs (e.g. the DS3234) have programmable alarms. You can set the alarm so that it fires when the current time matches a specified number of seconds,minutes,hours. So, for example, you could have the clock fire the alarm at 5 minutes and 32 seconds after every hour. The alarm itself is just a logic level on one of the pins. You hook that pin up to pin 2 or 3 on the Arduino and then you can attach an interrupt routine which will be called when the alarm goes off.

Pete

Does someone know if you could feed the square wave output of the DS1307 into one of the timer/counters and have it trigger an interrupt that will wake the processor? It would be a simple matter to set to DS1307 to provide a 1 Hz pulse stream. Then count the pulses. I just don't know if the counter could then wake the processor.

Yes, one way or another but I don't see the point. I assume this is to save battery power. Sleeping for 8 seconds seems to me to save more power than sleeping for 1 second. This is because it takes time to wake (say, 65 mS). So you are waking up for 8 x 65 mS rather than 1 x 65 mS.

Your only real issue is knowing the time accurately, right? So use the watchdog, and when you wake, power up the RTC chip, read the time, and see if your hour is up. I describe this technique here:

The RTC chip has it's own power source (coin battery) so I think I'll just set an alarm and use that to trigger an interrupt. Thanks for the responses and I'll try to remember to post code here once I get it working.

The RTC chip has it's own power source (coin battery) so I think I'll just set an alarm and use that to trigger an interrupt

I don't think the coin battery (3V) can be used to drive the clock output (TTL is nominally 5V). It only keeps the clock running when the normal supply voltage disappears.

Pete

el_supremo:

The RTC chip has it's own power source (coin battery) so I think I'll just set an alarm and use that to trigger an interrupt

I don't think the coin battery (3V) can be used to drive the clock output (TTL is nominally 5V). It only keeps the clock running when the normal supply voltage disappears.

Pete

Hmmmm that's a good point. The problem right now is that I'm trying to write code while my parts are ordered. I think the best solution is to wake every 8 seconds and check the clock, as suggested by Nick Gammon.

Which RTC are you using?

The DS1307 that is mounted on the Data Logging Shield from Adafruit: Adafruit Data logging shield for Arduino [v1.0] : ID 243 : $24.80 : Adafruit Industries, Unique & fun DIY electronics and kits

To address an earlier question, SQW/OUT on the DS1307 is open-drain, so with a pullup resistor to 5V it can drive an MCU input or other logic operating at 5V.

But the lowest frequency for SQW/OUT is 1Hz, so from a power saving standpoint, I'd favor the watchdog interrupt with an 8 sec period slightly. This would only be as accurate as the system clock, but judging from your initial post ("an hour or so"), maybe that's good enough and an external RTC wouldn't be needed.

Another approach would be to use the 1Hz output from the RTC to clock Timer1 or Timer2 externally, this would provide better accuracy than a resonator-controlled system clock. With Timer1 being 16 bits, the MCU could sleep continuously for an hour (actually could sleep for quite a bit longer). With Timer2, it would have to wake about every 4 minutes. But as with the watchdog, the wake periods can be extremely brief if there is nothing to do.

Yet another approach could dispense with the external RTC completely, clocking Timer2 from an external 32.768kHz crystal and implementing an RTC in software. This necessitates using the internal RC oscillator for the system clock, which can work very well for many situations.

Lots of ways to achieve the same thing!

entioc:
The DS1307 that is mounted on the Data Logging Shield from Adafruit: [http:
[/quote]

Ummmm. There's little point in sleeping the MCU on a standard Arduino board. The voltage regulator and other peripheral circuitry draw as much or more current than the ATmega328P and continue to do so even if the ATmega is sleeping.](Adafruit Data logging shield for Arduino [v1.0] : ID 243 : $24.80 : Adafruit Industries, Unique & fun DIY electronics and kits)

My question was about feeding the 1Hz clock stream into one of the counters

It would be a simple matter to set to DS1307 to provide a 1 Hz pulse stream. Then count the pulses.

The ideas was to get the processor to count the pulses in its sleep. It could then wake-up on overflow or threshold.
So an 8-bit counter, like counter 2, would overflow every 256 seconds or 4 1/4 minutes.

I did some more reading and I found some more data but I don't know that it is more information

From the datasheet

17.3 External Clock Source
An external clock source applied to the T1/T0 pin can be used as Timer/Counter clock (clkT1/clkT0). The T1/T0 pin is sampled once every system clock cycle by the pin synchronization logic.

This makes is sound like you can not "Power Down" but you may be able to go into "Stand-By" where the clock keeps running.
T0 is used to clock the Timer 0 and since that is used for "delay()", "millis()" and such. I don't think that is a good option.

14.3.3 Alternate Functions of Port D
PD5
T1 (Timer/Counter 1 External Counter Input)
OC0B (Timer/Counter0 Output Compare Match B Output)
PCINT21 (Pin Change Interrupt 21)

I don't know which pin that is on the Arduino.

• T1/OC0B/PCINT21 – Port D, Bit 5
T1, Timer/Counter1 counter source.
OC0B, Output Compare Match output: The PD5 pin can serve as an external output for the Timer/Counter0 Compare Match B. The PD5 pin has to be configured as an output (DDD5 set (one)) to serve this function. The OC0B pin is also the output pin for the PWM mode timer function.
PCINT21: Pin Change Interrupt source 21. The PD5 pin can serve as an external interrupt source.

16.11.2 TCCR1B – Timer/Counter1 Control Register B
• Bit 2:0 – CS12:0: Clock Select
The three Clock Select bits select the clock source to be used by the Timer/Counter, see Figure 16-10 and Figure 16-11.

It looks like you can select the external clock just like you would select a prescaled clock.

Now, since Counter 1 is a 16 bit counter, you should be able to set a threshold of up to 65536 seconds or over 18 hours.

There may be a lot of reason this won't work. I may be totally wrong in my reading of the datasheet, and I am still learning but I thought I would like learn why this wouldn't work.

RandallR:
I don't know which pin that is on the Arduino.

T1 is D5. I list them in here:

Nick,
I read your page on interrupts and I look forward to using you code to calculate frequency by checking the period in a project of mine in the future.

For this project, can the 1 Hz signal be feed to T1 (D5) and the counter continue to count even when the processor is a sleep? If the value 3600 (or 3599) where placed in the CTC register. Could an interrupt be generated to wake the processor?

Because of the synchronization process, the processor clock could not be stopped. So as noted in Gammon Forum : Electronics : Microprocessors : Power saving techniques for microprocessors the SLEEP_MODE_STANDBY "...similar to power-down mode, except that the oscillator is kept running." If that is the case then will counter 1 continue to accumulate until it reaches 3600, raise the interrupt, and wake the processor in one hours time?

As I see it, the greatest advantage to this is that a DS1307 and a crystal is less than a dollar (US or Australian). The only question would be, is it saving enough power to make it worth it? I would think that if you are putting your processor to sleep, there is a good change you will want to know the time when you wake up, but maybe not.

I don't believe the timer is running except in IDLE sleep mode (which doesn't save a heap of power).

I think you are better off going into a deep sleep mode with the watchdog timer, and then finding out the time when you wake up (via the DS1307).

I have come to the conclusion that the DS1307 will not work.

However, the PCF8563 will. This is a very similar chip and rather inexpensive (10 for $8.12 on ebay). It only needs a 32.768 kHz crystal to work. The crystals are on ebay 10 for $2.50 or 50 for $7. So for about a dollar (US) each you have an RTC with interrupt output.

There are two types of interrupts, Alarm and Timer. The timer is a count down timer of an 8-bit register. It can count down at 4 different clock rates but the most useful would be the one second and one minute rates. So in one second resolution you can sleep for 255 seconds (4 minutes 15 seconds). Or with one minute resolution you can sleep for 255 minutes (4 hours 15 minutes).

This a both cheap and versatile.

RandalIR, have you figured out this issue with the PCF8563 clock? I am running into the same thing with the PCF8525 on the Adafruit data logging shield. I cannot figure out which pin to set the interrupt and monitor to wake it from a deep sleep.