As Majenko already said, you cannot do that. But you can look for alternative ways of achieving a similar end result. The real question is: what are you trying to achieve? Interrupts may not be the best answer.
I assume what you have in mind is a program roughly along these lines:
// Interrut handler called when input > 600.
void handleHigh()
{
// ...
}
// Interrut handler called when input < 10.
void handleLow()
{
// ...
}
void setup()
{
// Register the interrupt handlers.
attachInterrupt(ANALOG0, handleHigh, MORE_THAN_600);
attachInterrupt(ANALOG0, handleLow, LESS_THAN_10);
}
void loop()
{
doSomeStuff();
}
Of course, that syntax for calling attachInterrupt()
does not work, I
just made it up.
The most obvious alternative is to read the value through an analog
input in loop()
and act accordingly:
void loop()
{
// Check the analog input.
int sample = analogRead(A0);
if (sample > 600) handleHigh();
if (sample < 10) handleLow();
// Do the rest of the job.
doSomeStuff();
}
No need to use interrupts. The only drawback is that the latency of your
response to a change in the joystick position can be as long as the time
your program takes to run through loop()
. This should normally not be
a problem: the joystick is a very slow mechanical device, and your loop
should take no more than a few milliseconds. If the loop if really too
slow, you are probably doing something wrong, like using delay()
. You
should then fix that problem rather than trying to work around it with
interrupts.
Just for completeness, there is an interrupt-based solution. Assuming you have no other analog input to read, you could configure the ADC to continously read the same input (say, A0) in the so called "free running mode", and trigger an interrupt on each reading. In the ISR, you can then call one of your interrupt handlers if needed (if the sample you get is outside [10, 600]). Here is how you can do it on an Arduino Uno:
void setup()
{
// Configure the ADC in "free running mode".
ADMUX = _BV(REFS0) // ref = AVCC
| 0; // input channel = A0
ADCSRB = 0; // free running mode
ADCSRA = _BV(ADEN) // enable
| _BV(ADSC) // start conversion
| _BV(ADATE) // auto trigger enable
| _BV(ADIF) // clear interrupt flag
| _BV(ADIE) // interrupt enable
| 7; // prescaler = 128
}
// ADC interrupt service routine.
// Called each time a conversion result is available.
ISR(ADC_vect)
{
// Read the ADC.
int sample = ADC;
// Call the handlers if needed.
if (sample > 600) handleHigh();
if (sample < 10) handleLow();
}
Edit: With the code above, the ISR runs every 104 μs. Then you
should make sure that your handlers take significantly less than that
time to complete. Otherwise they will consume 100% of the CPU power
whenever the joystick is in the range to trigger one of them. As a small
optimization, you could declare the handlers static inline
in order to
avoid the overhead of a function call.
- 45.1k
- 4
- 42
- 81