I came from professional Python programming with GTK - very high level in relation to C and AVR. At the beginning I have some conceptual questions now.
To give a practical background to my abstract problem: I plan to program a chain oiler for my own. That's mean to pause for approx. 15 minutes, give an impulse for approx. 1 second, pause again and so on. To set up the exact time values I will implement an button to trigger some settings "dialog".
To react on the pressed button I would use the interrupt attachInterrupt(0, button_interrupt_rising, RISING). How I read there are the recommendation: "ISRs should very short. The best would be only to set a flag evaluated in the main loop." - That's contradicts the desire of interrupts, doesn't it?
Many parts of the system can go to sleep and will be awaked via interrupt. But with using flags the main loop is a busy waiting (for the total 15 minutes when usually nothing happens) to check the flags.
And if I ignore that recommendation and put my whole settings dialog into the ISR, I have the problem with further interrupts within the ISR for more button inputs to set the value.
I hope you can help me to clarify this issue "Let system sleep until heavy work triggered by button".
The main use of interrupts is to detect with really short duration events.
Imagine you have a device sending really short pulses.
One way of reading them is to poll the corresponding input (checking its value whenever you can). However, it uses computing time and if your MCU is busy doing something else, you might miss the pulse.
Now here is where interrupts are useful: you detect the pulse using an interrupt, you set a flag in the ISR, and you treat that information in the main program when you want. The reason for that is when in an ISR, everything else (almost) pauses. The code is not being executed and can hang during an important task (communication that will fail, controlling an actuator but the interrupt comes in the middle of the command being send, etc.).
With the flag, you treat the information only when YOU want, making sure that it won't suspend anything critical.
That's a good practice but it's not mandatory in all case, of course.
In your case, you're not using interrupts to detect short events while doing something else.
Since everything is sleeping (no code executed) and your interrupt's role is to wake up the system, checking the value of a flag is not a good idea since it prevent the system from sleeping, indeed.
OK. To get the system into sleep mode it sticks in delay(15*60000) the most time. Do you have an idea to abort this delay via ISR to handle the action in main code?
Delta_G:
delay isn't the same as sleep mode. [...] Delay just has the chip busy running nothing.
delay_micros() is busy waiting, delay() uses the hardware timer.
Separate sleep mode is the right hint. Thank you.
So I will activate directly sleep mode in main loop. Wake up via button interrupt or external Timer (TimerOne keeps system in sleep mode?) and check whether the 15min are over or to react on button.
Chickenmarkus:
OK. To get the system into sleep mode it sticks in delay(15*60000) the most time. Do you have an idea to abort this delay via ISR to handle the action in main code?
As @Delta_G has said that is not sleeping and I assumed you meant sleeping so it did not occur to me to give you this link to several things at a time which illustrates how to manage timing using millis() rather than delay(). It uses the same technique as BWoD.
Henry_Best:
? Indeed. Both are busy doing nothing.
You're right. I understood this post that delay() only locks until interrupt of hardware timer and only delayMicroseconds() is busy due something like while (true). But if we see in codedelay() uses while (true) too. It's only not working in ISRs because of millis() inside.
Summary what we've got until now:
I don't want to have full CPU load for 15 minutes while usually do nothing (busy waiting). This is the case with delay(), delayMicroseconds() and permanently checking over main loop (like several things at a time).
Instead I will send sleep the system directly like in this minimal (untested) code:
Chickenmarkus:
I don't want to have full CPU load for 15 minutes while usually do nothing (busy waiting).
You still seem a trifle confused here (and you seriously need to read the instructions on how to post, especially but not only, item 7).
"Sleep" mode is only used to conserve power. Not the same as a multi-tasking operating system where it passes control to another process. It is not used to invoke delays unless you also want to conserve power.
You have not indicated a requirement to conserve power, so unless that is what you require, "busy waiting" is exactly what you want to be doing.
That said, it is most certainly not in the slightest necessary that waiting prevents you from performing other tasks whilst waiting. You can interleave numerous other tasks in the waiting process limited only by code space and overall task complexity. If however, you only have the one task, then there is no reason not to "busy wait" - the processor is not sentient - it does not care and it will not wear out!
Sorry, I thought it was clear that I aim to conserve power if I do not want busy waiting for 15 minutes for only 1 second action within.
My final device will be something like DigiSpark driven by battery.
Sometimes it's absolute clear what I mean - for me.
After 5 years using busy waiting (if nothing else was to do) on graphical programmable calculater as only possibility for waiting it was a challenge to find alternatives for the last 10 years of PC programming without. So it's good to know busy waiting is exactly the right way again, 15 years later now - without the need of power saving
So is it possible to wake up the system from sleep mode by Timer1?
Yes, I did. The datasheets are available online and linked by the product page. So Google will crawl it. There are a lot of literature in PDF format I found only by some headlines this way.
Now it's everything clear (for the moment). Thanks again to all.