Using interrrups correctly

To maximise battery life I want to put a pro-mini into deep sleep for 18 hrs & then use a RTC (DS3231) to awaken it for 6 hrs. During the wake time a motion sensor will be active. I have read that interrupt routines should be kept short and I understand why.

My question is, "Am I wrong to use interrupts in this way?"

Any help would be appreciated because I can't find a definitive answer.

If an interrupt is necessary for waking up then use it. The interrupt handler may do nothing, everything else can execute after the sleep invocation code.

Yes, interrupt routines should be kept short. No Serial.print nor any calls to high level code, libraries.
You could show code and schematics to explain what "this way" really means. Fuzzy, unclear word sallad, will be misleading helpers, and You.

It is in fact, the only way. You have no choice but to use an interrupt. Perhaps you conceive of your wake up code as one long ISR. That is not right. You want to just wake, so the interrupt will only do that. I haven't played with sleep yet, but that should be a very short ISR, only a few lines. That would be completely separate from your main code. It will resume from where you invoked sleep in your main code, in the first place.

I am perhaps needlessly elaborating on reply #2.


You use the word "If". Do you know of another way to awaken from deep sleep?

Apologies for the confusion. By "this way" I mean using interrupts to awaken from deep sleep.

Thank you for this. I believe you've answered my question. I can simply use the interrupt to awaken from deep sleep and then do whatever i want. I could then use interrupt 2 to send it back to deep sleep.

Thanks again

I thought so after reading the reply from @DrDiettrich. Just wanted to here it from You.
Often members being new in this game think that Interrupts is a magical miracle medicine fixing just any difficulty.
As @arg says, that's they way to do it.
However, putting the controller asleep You just command it in the code, without any interrupt.

Do you mean that you want the device (MCU) to be in deep sleep the whole day. During 6 hours of the day you want the device to be wakeable by an interrupt from a PIR ?

But the interrupt routine actually does nothing at all in this case. It is completely empty. The main code continues immediately after the command which implemented the sleep. There is nothing else to do.

If the RTC interrupt were to happen again whilst not in sleep mode - which it clearly should not - it will simply be ignored in the null handler.

Putting it to sleep has nothing to do with the interrupts.

Thanks for this

The MCU will be in deep sleep. At a specific time (I will use a RTC to keep time) an interrupt will awaken the MCU. Once awake the MCU will 'listen' to a PIR for a defined period of time. After that period has elapsed the MCU will return to deep sleep. - does that clarify it for you?

Thank you.

That covers everything 'I think' I need.


That makes sense.

You listen for an interrupt from the RTC. When one arrives, you check the RTC to see if it is for the start or end of the 6 hour period and set the mode accordingly and resume sleep. If it is in the ON period (6 hour window), you enable interrupts from the PIR pin and act accordingly (sound buzzer etc.) and resume sleep. If it is in the OFF period (18 hour window) you disable interrupts from the PIR pin.

This can be done with level change or pin change interrupts.

You have an alternative of sleeping for units of 8 seconds, say 32 seconds, then interrogating the RTC, setting the mode accordingly, and resuming the sleep. This means that setting alarms on the RTC and waking the MCU on an RTC interrupt is not necessary. However, you have then to configure the watch dog timer to wake the MCU. The "8 seconds" is assuming an AVR architecture (Uno etc.)

An interrupt on the period end is not required. The RTC interrupt wakes up the controller which enables PIR interrupts and goes to sleep again. On a PIR interrupt the current time is checked and, after the watch period, the PIR interrupt is disabled and the controller sleeps again, until the next RTC interrupt.

To be clear: the interrupt handlers do nothing, the interrupts are only required to wake up from sleep mode.

OK. In general, of course, as little as possible is done in the ISR itself.
In the case, as here, of two or more possible interrupt sources, the ISR is a good place to identify which interrupt caused the wake up.

1 Like

I decided on an external clock because it would save power (the DS3231 uses its own battery) and be more accurate.

I believe from the consensus here that only one interrupt is required i.e. to wake the MCU. Sending it back to sleep, at the end of the period, is done in the code.

I just sped read this and did not see anyone saying you shoukd know about this website:

if you are serious about real low power &c.

Any time spent there (while awake) is worth it.


Well, an alternative has been suggested, that you use the "wake" interrupt to respond to the motion sensor, given that you intend no other activity to be required in the absence of motion detected.

In which case, depending on how much motion activity you anticipate in the "off" period, you have two choices.

The first is to wake only on motion sense and check the clock to see if you "care" about motion at that time in which case you do not need to wake on the alarm.

The second is to respond to the alarm waking interrupt in order to enable motion interrupts and if on any given motion interrupt, it turns out you are past the time that it matters, you can then disable the motion interrupts again until the next alarm. This would absolutely minimise the amount of time you are "awake". :grin:

Amount of motion will fluctuate during sleep time and any activity here will work to reduce the battery life.

This is it in a nutshell - Thank You ...