Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« on: January 07, 2012, 11:23:03 pm » |
I have written a lengthy post about how interrupts work on the Atmega: http://www.gammon.com.au/interruptsAny constructive comments welcome.
|
|
|
|
|
Logged
|
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #1 on: January 07, 2012, 11:41:02 pm » |
Informative and interesting. Thanks!
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 47
Posts: 2567
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #2 on: January 08, 2012, 12:01:39 am » |
Good work, Nick. Since millis() comes up in a couple places, as a bit of an aside, I might expand just a bit on the mechanism. Folks might find it interesting to know that while their sketch is running, the processor is already being interrupted nearly 1000 times per second for the purpose of keeping time. And it's another example of how interrupts can be used.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #3 on: January 08, 2012, 12:11:37 am » |
Good idea. I've added a paragraph at the end to explain that.
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #4 on: January 08, 2012, 10:50:12 am » |
- external interrupts need a good signal (5V 0V) to be triggered. A long wire can disrupt signal squarenes.
- something about bouncing switches and interrupts might be useful ... (One IRQ?? I got 15!!)
- enabling irq's within an ISR can give rise to reentry of the same ISR. Not trivial to handle though ...
- length of irq's versus frequency ... (short flag setting IRQ's are preffered)
|
|
|
|
|
Logged
|
|
|
|
|
ਪੰਜਾਬ
Offline
Edison Member
Karma: 4
Posts: 1232
WANTED! A Girl with LOVE for me and Arduino!
|
 |
« Reply #5 on: January 08, 2012, 11:50:15 am » |
Much Appreciated thank you for putting precious time into it, I have read a lot there.
|
|
|
|
|
Logged
|
"Real Men can Accomplish Anything" - Website - skype : nishants5 ਫ਼ਤੇਹ ਕਰੂਂ !
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #6 on: January 09, 2012, 04:05:23 am » |
- external interrupts need a good signal (5V 0V) to be triggered. A long wire can disrupt signal squarenes.
- something about bouncing switches and interrupts might be useful ... (One IRQ?? I got 15!!)
- enabling irq's within an ISR can give rise to reentry of the same ISR. Not trivial to handle though ...
- length of irq's versus frequency ... (short flag setting IRQ's are preffered)
I mentioned about the re-entrancy, and how it is best just to set a flag. However I extended the post to show an example of debouncing. Useful idea, as interrupts can be confusing if you expect one button press but get 20. 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #7 on: January 09, 2012, 10:07:56 am » |
This is great, Nick. I have vainly looked in various Arduino books for this kind of info on interrupts. Thanks for putting it out there.
I am interested in using the interrupts on "any pin" -- the PCINTx stuff; it would be good to get a little bit more on how to differentiate different interrupts on the same "port"; maybe an example or some other pointer to an example. I am concerned about the interaction with pins I am not using for interrupts; whether there are uses that cannot be combined with interrupt usage etc. Will I be triggering a PCINT2 ISR if I am using pin D4 for PWM output, and pins D5 and D6 for interrupts?
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 47
Posts: 2567
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #8 on: January 09, 2012, 10:37:40 am » |
This is great, Nick. I have vainly looked in various Arduino books for this kind of info on interrupts. Thanks for putting it out there.
I am interested in using the interrupts on "any pin" -- the PCINTx stuff; it would be good to get a little bit more on how to differentiate different interrupts on the same "port"; maybe an example or some other pointer to an example. I am concerned about the interaction with pins I am not using for interrupts; whether there are uses that cannot be combined with interrupt usage etc. Will I be triggering a PCINT2 ISR if I am using pin D4 for PWM output, and pins D5 and D6 for interrupts?
Not if things are set up properly. The PCICR register has three bits that enable pin change interrupts on a port-by-port basis. Then there are three mask registers (one for each port) PCMSKn which enable the interrupts on a pin-by-pin basis. The tricky part is that there is no built-in facility to indicate exactly which pin caused the interrupt. The PCIFR register has flags to indicate which port caused the interrupt, but again, only three bits. So I might have the ISR save a copy of the PORTx register, so that the bits can be compared to determine the pin that caused the interrupt.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 13
|
 |
« Reply #9 on: January 09, 2012, 12:21:02 pm » |
Great, that is the info I was missing. Nick, it would be great if you could add that stuff about the masking to your writeup.
I don't really have a problem with figuring out which pin (which is to say, I haven't tried it yet ...), but being able to mask out the pins that I am using for other purposes is what I was after.
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 47
Posts: 2567
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #10 on: January 09, 2012, 03:11:52 pm » |
Great, that is the info I was missing. Nick, it would be great if you could add that stuff about the masking to your writeup.
Good deal. All Things Are In The Datasheet  Nick might want to stop somewhere short of replicating the whole thing though. I could see maybe a general discussion of interrupt mask and flag registers because they are a recurring theme, but I'm not sure he wanted to get down to the bit-biting level. OTOH it can be difficult not to do that when playing with interrupts. Not sure which way is best. I don't really have a problem ... (which is to say, I haven't tried it yet ...)
Haha, I like that! Might have one of those t-shirts around here somewhere!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Faraday Member
Karma: 16
Posts: 3220
20 LEDs are enough
|
 |
« Reply #11 on: January 09, 2012, 03:21:22 pm » |
Great work. Some details I would add:
Other reasons to use interrupts: - to wake up from sleep mode (you mention it but not so prominently). - super agressive performance optimization, not checking loop conditions but using timer interrupts to terminate loops thus allowing to optimize the check condition out of the code into the hardware
The interrupt event queues will hold at most 1 event per eventsource
ISRs will be much slower to start if processor has to wake up from deep sleep - because the oscillator needs to stabilize.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 226
Posts: 14097
Lua rocks!
|
 |
« Reply #12 on: January 09, 2012, 03:44:02 pm » |
Good deal. All Things Are In The Datasheet To be honest I didn't want to get too bogged down in detail, although interrupts can be complex enough. Also, I haven't done much with pin change interrupts. I regard them as a bit of a "fallback" if you can't use the dedicated interrupt pins. There are a few pin change libraries around, it could be helpful to check them out. A problem, if it is a problem, is that libraries tend to hide what is really happening from you. So a library can be great if you want a quick solution, but not so great if you want to understand what is really happening. Some details I would add:
Other reasons to use interrupts: - to wake up from sleep mode (you mention it but not so prominently). - super agressive performance optimization, not checking loop conditions but using timer interrupts to terminate loops thus allowing to optimize the check condition out of the code into the hardware
I've amended the page a bit to incorporate both of your suggestions (Udo and Jack), that is, the pin changes, and the waking etc. The interrupt event queues will hold at most 1 event per eventsource
The page currently mentions that, as follows: The ones that set a flag could be regarded as being queued, as the interrupt flag remains set until such time as the interrupt routine is entered, at which time the processor clears the flag. Of course, since there is only one flag, if the same interrupt condition occurs again before the first one is processed, it won't be serviced twice. Thanks for the feedback. 
|
|
|
|
|
Logged
|
|
|
|
|
South Texas
Offline
God Member
Karma: 8
Posts: 978
|
 |
« Reply #13 on: January 09, 2012, 03:54:22 pm » |
Interrupts VS polling - SPEED
For a routine that has to run NOW like an encoder input.
If anyone has experience programing other devices or computers - Interrupts are like events in Windows and other operating systems. The program doesn't have to wait for the interrupt event to happen but can continue doing whatever, and the interrupt routine will do its thing when the interrupt condition (HIGH, RISING, FALLING, LOW, CHANGE) is met.
|
|
|
|
|
Logged
|
|
|
|
|
Copenhagen, Denmark
Offline
God Member
Karma: 21
Posts: 884
Have you testrun your INO file today?
|
 |
« Reply #14 on: January 09, 2012, 03:55:47 pm » |
Oh, I wanted to write that... just skimmed it now, certainly seems comprehensive (when is it too large and when is it the essentials?). I happened across one part at the end: Yes the Arduino 1.0 DOES use interrupts to handle Serial output as a background activity. (checked the core code). So you comment about believing it, can be less relgious  Great work.
|
|
|
|
|
Logged
|
|
|
|
|
|