Offline
Newbie
Karma: 0
Posts: 8
|
 |
« on: January 03, 2013, 05:30:36 pm » |
Greetings. 1st post.
I've got two interrupts running: an external and a timer, both set up using <avr/interrupt.h> register writes since I'm used to that level of control and know I will need it as this gadget evolves. No problems there. The timer interrupt is slow (1s) to service a temperature control loop, and the external is a once-around pulse on a slow running motor (~3.5Hz). I need to turn off the temperature control loop from time to time to act on some motor events. And I'll ultimately need to turn of the external motor interrupt when I add a faster timer interrupt (say 125us) to sample some data. There must be a slick way to turn interrupts on and off individually with minimal avr register writes. Or something. Any good ideas?
Many thanks!
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 278
Posts: 25577
Solder is electric glue
|
 |
« Reply #1 on: January 03, 2013, 05:34:26 pm » |
Yes you simply disable them. This is normally done by setting / clearing a flag in the appropriate register for the device generating the interrupt. See the data sheet of the processor for the name of the memory location and the bit to use.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #2 on: January 03, 2013, 06:15:29 pm » |
The timer interrupt is slow (1s) to service a temperature control loop, and the external is a once-around pulse on a slow running motor (~3.5Hz). I need to turn off the temperature control loop from time to time to act on some motor events. And I'll ultimately need to turn of the external motor interrupt when I add a faster timer interrupt (say 125us) to sample some data. That makes zero sense. There must be a slick way to turn interrupts on and off individually with minimal avr register writes. Or something. Yes, there is - all outlined in the datasheet.
|
|
|
|
|
Logged
|
|
|
|
|
North Queensland, Australia
Offline
Edison Member
Karma: 31
Posts: 1209
|
 |
« Reply #3 on: January 03, 2013, 06:21:06 pm » |
Check out the link in my signature, I have a class that works on global interrupts for atomic blocking. The 'Atomic_Force' mode emits only 2 instructions for interrupts off/on, you'd be up for a challenge writing code faster than it.
It has a 'Protect' function so you can make variable reads/writes, and function calls all protected from interrupts.
|
|
|
|
« Last Edit: January 03, 2013, 06:23:28 pm by pYro_65 »
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13897
Lua rocks!
|
 |
« Reply #4 on: January 03, 2013, 06:30:31 pm » |
Yes, there is - all outlined in the datasheet.
It would be less typing to actually give the answer: noInterrupts ();
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #5 on: January 03, 2013, 08:14:22 pm » |
The timer interrupt is slow (1s) to service a temperature control loop, and the external is a once-around pulse on a slow running motor (~3.5Hz). I need to turn off the temperature control loop from time to time to act on some motor events. And I'll ultimately need to turn of the external motor interrupt when I add a faster timer interrupt (say 125us) to sample some data. That makes zero sense. There must be a slick way to turn interrupts on and off individually with minimal avr register writes. Or something. Yes, there is - all outlined in the datasheet. hmmm... Seems perfectly clear to me. Let me try again. -Temperature control loop interrupt fires every second. -Motor control loop interrupt fires ~3 times per second -My sample clock wants to be 125us which I think will be another timer interrupt (I'll write that part tomorrow). Sometimes, depending on what is happening in the main loop, I want to respond to a motor interrupt by starting to sample an analog signal. When that happens, I don't want the slower, relatively less critical ISRs to cause me to miss the faster critical timing interrupts, so I'd turn off only the ones I want to ignore, then turn them back on when I care less.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #6 on: January 03, 2013, 08:24:09 pm » |
When that happens, I don't want the slower, relatively less critical ISRs to cause me to miss the faster critical timing interrupts, so I'd turn off only the ones I want to ignore, then turn them back on when I care less. That makes absolutely zero sense, if you have understood the interrupt section of the datasheet. 1) global interrupt is disabled once you are in an isr. So unless you do something weird, you will miss (as in not servicing their respective isrs) when one isr is being serviced. There are ways around this, but unless you know more than what you are doing, don'g go there. 2) your other isrs will not be missed, however, in the sense that the flags remain set after the interrupts have arrived, even if you are in the middle of another isr. So once you exit the isr, your execution will jump back to the pending isr. In a properly designed system, you will never have an isr that takes too much time. ISRs are all about being quick and small. The fact that you are even facing such issues suggests a fundamental lack of understanding of how interrupts should be used.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #7 on: January 03, 2013, 08:52:03 pm » |
No, I understand what I'm doing. But thanks for the insults ;~) If I get a motor interrupt while in the middle of a PID calculation in my temperature control ISR, by the time I service the pending motor interrupt, it will be too late (motor will have moved). So I'll turn off the temperature control interrupts to prevent that. Similarly, I may need to turn off the motor interrupts so my sample timing is deterministic (so I can implement good digital filters). It looks like I can just reset the appropriate bits in the mask registers (TIMSKO and EIMSK for the timer and external interrupts, respectively).
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13897
Lua rocks!
|
 |
« Reply #8 on: January 03, 2013, 09:09:45 pm » |
When that happens, I don't want the slower, relatively less critical ISRs to cause me to miss the faster critical timing interrupts, so I'd turn off only the ones I want to ignore, then turn them back on when I care less.
... I add a faster timer interrupt (say 125us) to sample some data. What is the nature of this sampling, out of curiosity? Counting pulses? ADC conversion? Something else?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13897
Lua rocks!
|
 |
« Reply #9 on: January 03, 2013, 09:11:30 pm » |
... you will miss (as in not servicing their respective isrs) when one isr is being serviced. ... your other isrs will not be missed, ...
Well, I'm confused. Will they be missed, or not? Hints about interrupts: http://www.gammon.com.au/interrupts
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #10 on: January 03, 2013, 09:34:04 pm » |
When that happens, I don't want the slower, relatively less critical ISRs to cause me to miss the faster critical timing interrupts, so I'd turn off only the ones I want to ignore, then turn them back on when I care less.
... I add a faster timer interrupt (say 125us) to sample some data. What is the nature of this sampling, out of curiosity? Counting pulses? ADC conversion? Something else? Short bursts of ADC from a rather novel optical scanner of my design (I've done a lot of scanners...).
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6415
-
|
 |
« Reply #11 on: January 03, 2013, 09:36:20 pm » |
No, I understand what I'm doing. But thanks for the insults ;~)
I don't understand why you're using interrupts to trigger the temperature control processing or the motor control. Is there some unusual latency requirement which requires this?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #12 on: January 03, 2013, 10:12:04 pm » |
No, I understand what I'm doing. But thanks for the insults ;~)
I don't understand why you're using interrupts to trigger the temperature control processing or the motor control. Is there some unusual latency requirement which requires this? It's just the best way to do background-running real time feedback loops in my experience. There's quite a lot happening in the main loop, and if we neglect the temperature or speed longer than spec'd we'll have errors in temp or speed. Plus the code is way cleaner (and finishable) without all the polling of inputs. Or did you have a better alternative?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13897
Lua rocks!
|
 |
« Reply #13 on: January 03, 2013, 10:13:38 pm » |
Short bursts of ADC from a rather novel optical scanner of my design (I've done a lot of scanners...).
Using analogRead? SPI? I2C? Just wondering how the data gets to you.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #14 on: January 03, 2013, 10:31:05 pm » |
Short bursts of ADC from a rather novel optical scanner of my design (I've done a lot of scanners...).
Using analogRead? SPI? I2C? Just wondering how the data gets to you. analogRead() seems to be fast enough. Sensor is ballsy optical receiver of my design (optics, PIN diode preamp, 20KHz homodyne modulation (chop) on the light source and receiver). I might try to demodulate in the avr if i can live with ~8KHz chop. But we're drifting off topic...
|
|
|
|
|
Logged
|
|
|
|
|
|