Using attachInterrupt (0, isr0Handler, CHANGE)

Hello,

I'm trying to use a hardware interrupt (Interrupt 0 Pin 2) on my application and I am finding that if I use attachInterrupt (0, isr0Handler, CHANGE), and my interrupt signal goes from 0V to 5V and stays at 5V the interrupt is called over and over. I expected the interrupt to be called when the voltage went from 0V to 5V and then again when it changed from 5V to 0V. Am I wrong in this expectation and if so, how can I change this so that the controller is interrupted with a change from 0V - 5V and then again from 5V - 0V?

Thanks in advance for any suggestions!

Rick

Post your code (in code tags) and also explain what device is generating the interrupt and how it is wired.
And DON'T crosspost.

Pete

rprowbo1:
my interrupt signal goes from 0V to 5V and stays at 5V the interrupt is called over and over. I expected the interrupt to be called when the voltage went from 0V to 5V and then again when it changed from 5V to 0V.

That is what you should expect. Since it is not acting like that there is most likely a mistake in the sketch or the device connected to Pin 2. I can't see either of those so I can't help further.

http://www.gammon.com.au/interrupts

Read this before posting a programming question

How to use this forum

Pin 0 is used by serial.

aarg:
Pin 0 is used by serial.

But the interrupt on pin 2 is numbered 0.

What board are you using? You should always use digitalPinToInterrupt(pin).

Are you sure your signal hitting pin2 is stable? You might see it at 5v if you have a slow voltmeter but it may oscillate for a while for example if you have a push button connected to it without debouncing.

Here’s the code… I am using interrupt 0 on digital pin 2 of the Arduino Uno board. I’ve had more than one version of this but this is the latest. Again, my input to pin 2 interrupt 0 goes high (5v) and stays high. Since it stays high (5v) and “attachInterrupt()” is set to “CHANGE”, I expected the interrupt to be triggered when the input goes from 0V - 5V and then again when it goes from 5v - 0V. The way that it is working is when the trigger circuit goes from 0v - 5v and stays at 5v, the interrupt is triggered over and over. I’m not sure what I’m doing wrong or how to get around this triggering over and over.

Here’s the code…

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT);
  //digitalWrite(interruptPin, HIGH);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), blink, LOW);
  //attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}
void loop()
{
  digitalWrite(ledPin, state);
  if (state)
  {
    //Serial.println("shuting down interrupts");
    //noInterrupts();
  }
  /*if(!state)
    {
    Serial.println("state is Low");
    }*/
}
void blink()
{
  state = !state;
  Serial.println("In the interrupt service routine");
  if (state)
  {
    Serial.println("state is High");
  }
  if (!state)
  {
    Serial.println("state is Low");
  }
  //noInterrupts();
}

Moderator edit: [code][/code] tags added. (Nick Gammon)

remove the Serial prints from your ISR. That will definitely trip you up.

By the way, I did read Nicks posts on interrupts and they were very good. Thanks Nick.

You can see that the CHANGE works as expected by looking at this code and its output.
I use software generated interrupts here.

const byte ledPin = 13;
const byte interruptPin = 2;

volatile byte state;
volatile int countIRQs;
volatile bool newIRQ;

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
  Serial.begin(115200);
}

unsigned long lastIRQ;

void loop()
{
  digitalWrite(ledPin, state);
  if (newIRQ) {
    noInterrupts();
    int countCopy = countIRQs;
    interrupts();
    newIRQ = false;
    Serial.print(millis());
    Serial.print(" IRQ# ");
    Serial.print(countCopy);
    Serial.print(" state is ");
    Serial.println(state ? F("ON") : F("OFF"));
  }
  if (millis() - lastIRQ >= 500) {
    digitalWrite(interruptPin, !digitalRead(interruptPin));
    lastIRQ = millis();
  }
}

void blink()
{
  state = !state;
  countIRQs++;
  newIRQ = true;
}
0 IRQ# 1 state is ON
500 IRQ# 2 state is OFF
1000 IRQ# 3 state is ON
1500 IRQ# 4 state is OFF
2000 IRQ# 5 state is ON
2500 IRQ# 6 state is OFF
3000 IRQ# 7 state is ON
3500 IRQ# 8 state is OFF
4000 IRQ# 9 state is ON
4500 IRQ# 10 state is OFF
5000 IRQ# 11 state is ON
5500 IRQ# 12 state is OFF
6000 IRQ# 13 state is ON
6500 IRQ# 14 state is OFF
7000 IRQ# 15 state is ON
7500 IRQ# 16 state is OFF
8000 IRQ# 17 state is ON
8500 IRQ# 18 state is OFF

But you didn't read Nick's sticky post about How to post code properly.

Pete

Sorry about that el_supremo, I'm new to the forum. I'll do better next time.

Thanks for the tip Whandall I'll look it over.

rprowbo1:
By the way, I did read Nicks posts on interrupts and they were very good. Thanks Nick.

You skipped the part about not doing serial prints inside an ISR, eh? :stuck_out_tongue: