Arduino time alarm without an external interrupt alarm pin on the RTC?
February 12, 2013 1:47 PM   Subscribe

I want to program my Arduino to go to sleep at 6 pm and wake back up at 5 am, and then execute a few simple functions once every hour while it's awake. I have a DS1307 real-time clock, but it doesn't have an alarm interrupt pin, so I can't just set up an external interrupt to tell the Arduino to wake when the alarm pin is set to high. What's the best way to do this without an alarm pin?

I'm a bit of a programming newbie, but I have written a program to which I need to add this functionality. I've played with a few of the libraries out there, but most of the best/most efficient methods require the alarm interrupt pin on the RTC, and I am having trouble figuring out how to accomplish this without it. Unfortunately, I am irrevocably stuck with the DS1307 and buying another RTC module that has an alarm pin is simply not an option. I would also like to use the narcoleptic library for the sleep function to extend my battery life.

Can somebody walk me through how to get my Arduino + DS1307 to sleep from 5am to 6pm and only trigger my function once every hour, while using the narcoleptic delay function somehow? I am willing to give up on the narcoleptic part if I need to, but using narcoleptic will give me a much longer run time, which is really important to the project as well (this is for a multiple-week data-logging application). Cheers and thanks for any advice you might have!
posted by dialetheia to Technology (5 answers total)
When you say 'once every hour', what do you mean? Do you mean "no more than once an hour" or "on the hour, every hour, to some degree of accuracy" or what?

Anyway, basically what you're going to do is use narcoleptic to sleep for some period of time, as determined by how inaccurate you're willing to be. Without an alarm, you'll be relying on the 128kHz oscillator, which is super-inaccurate. Like, ±3 minutes in an hour. Each time the Arduino wakes up, it will query the RTC, execute its function if the time is "close enough" to the right time, then go back to sleep.

During the inactive part of the day you could probably get away with longer periods of sleep between clock checks.
posted by jedicus at 2:01 PM on February 12, 2013

Sorry, I was unclear - I mean "no more than once an hour," and the closer I can get that interval to exactly one hour, the better - but no, it doesn't have to occur at exactly X pm on the dot or anything like that. As long as the timestamps on the data I collect are correct (which should be relatively easy using the RTC), the precise timing of the function is not mission-critical.
posted by dialetheia at 2:06 PM on February 12, 2013

It's been about two years since I've done AVR code, but if I remember there was a way to leave a countdown timer running and shut the rest of the chip down. What I'd do: Read the RTC, if it's time to do the event, do the event, if not, set the countdown timer for the minimum of the max it can do or the time 'til the next event based on the RTC data, and go back to sleep.

As Jedicus mentions, when you get closer to the time you might want to try to wake up a little early to make sure that you get close to your target time.

I'd be more specific, but it's either me or you reading spec sheets, and a quick Google suggests that there's already a lot of Arduino specific stuff out there on making it sleep in relatively low-power states and waking on the watchdog or other timers.
posted by straw at 2:24 PM on February 12, 2013

The DS1307 can use its SQW/OUT pin to produce a 1Hz pulse, which is infrequent enough that if the code wakes itself and queries the time each time, it won't take much power. (The length of an I2C transaction is so short...) Simply sleep, you don't need narcoleptic.

Make sure you're setting the I2C pins to input (high-z) before going to sleep, otherwise you'll burn a ton of power in the pull-up resistors. This may already be the default.

Of course, you'll want to measure the power consumption of whatever approach you try. Most multimeters won't do anything sensible with short bursts of power usage and long periods of idle, so DIY: Put a big capacitor on the Arduino's power rails, and then power it through a fairly-high-value resistor, one that'll experience measurable voltage drop under the estimated load. Once things have reached steady-state, simply measure that drop and do ohm's law to find the current.

Example math: I'm expecting my project to draw no more than 10uA at 4.5V. I know the Arduino won't be damaged by 5.5v so I want to set my power supply for that. That means I want 1v to drop across the resistor. Ohms=Volts/Amps, so Ohms=1/0.00001, so Ohms=100,000. Alright, I grab a 100k resistor and put it inline. I set the power supply to 5.5v, and watch the voltage on the cap come up. After a while I hit the Arduino's reset button to make sure my code is running (didn't get confused by the slow brown-up), and then after another while, I measure the voltage on the cap. It's sitting at 4.8 volts.

Okay, 5.5 - 4.8 = 0.7 volts being dropped across the resistor. Amps = volts / ohms, so amps = 0.7 / 100,000 so amps = 0.000007, or 7uA. My project is drawing 7uA. Powered by three AA batteries (4.5v at 2000mAh), it will last 285,000 hours. The batteries will rot first.

Note for this approach: This assumes you're using a digital voltmeter with a high input impedance (typically about a megohm), because it'll be in parallel with the shunt resistor during the measurement. An analog meter will throw things off and is beyond the scope of this explanation.
posted by Myself at 2:32 PM on February 12, 2013 [2 favorites]

Most AVRs have an OSCCAL register that allows you to tune the internal oscillator to better than 1% accuracy. This is about half a minute an hour. Search for OSCCAL calibration routines on the Atmel site. You use the real time clock for calibration and then occasionally update the real time as needed for the desired accuracy. Then you can use the internal timer of the microcontroller to wake up to perform your scheduled function. Even waking up once a second to update your timer will allow you to run for years on a battery. You have to be very attentive to detail to keep power usage to a minimum while sleeping. Again carefully read the datasheet for your microcontroller about power management. It will provide valuable tips for reducing power.
posted by JackFlash at 9:57 PM on February 12, 2013

« Older Where can I order customized red envelopes online?   |   Cape Cod trip with kid... tomorrow. Newer »
This thread is closed to new comments.