No interruptions - example interrupt sketch that actually works?

Ello

I am working on a project to read data from a digital scale. My code captures high/low on a data line, on the falling edge of a clock line.

I have used interrupts to successfully do this... until I upgraded by IDE to 1.6 and suddenly the interrupts no longer work.

In fact I cannot get interrupts to work at all on my Uno. I have followed several different tutorials online without success - using:

  • the 'old' method: attachInterrupt(0, dataReceived, FALLING)
  • the 'new' method: attachInterrupt(digitalPinToInterrupt(2), dataReceivedY, FALLING)
  • using avrlib: following this example
  • the reference example here

Has something changed in the 1.6 IDE?

Can anyone point me to an example that is known to work? I just want to turn the pin-13 LED on an off on an interrupt.

B

This works on my Pro Mini

const byte irqPin = 2;

void toggleLED() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(irqPin, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(irqPin), toggleLED, FALLING);
}

void loop() {
  static unsigned long lastStop;
  if (millis() - lastStop > 250) {
    lastStop = millis();
    digitalWrite(irqPin, !digitalRead(irqPin));
  }
}

Many thanks Whandall

That does work for me but not quite what I am looking for...

So it's true what some (but not all) examples say: you have to declare the ISR before the attachinterrupt()?

If I modify the code slightly as below - why doesn't this work?

I would expect the LED to be on when the board boots, then toggle on/off when I press my switch. Instead the LED is off when the board boots and does not turn on when I press the switch.

const byte irqPin = 2;

void toggleLED() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(irqPin, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  attachInterrupt(digitalPinToInterrupt(irqPin), toggleLED, FALLING);
}

void loop() {
}

What is triggering the interrupt on pin 2? In Whandall's code, the loop() function is toggling pin 2. In your code, nothing is toggling pin 2. Unless you have an external interrupt source applied to pin 2, the behavior you see is what I would expect.

The interrupt is triggered by a tactile switch between pin 2 and ground.

Do I need to set internal pull-down resistor on pin 2?

B

Do I need to set internal pull-down resistor on pin 2?

You could try. The Arduino doesn't have internal pulldown resistors. It only has internal pullup resistors. If you don't have an external resistor, you have a floating pin condition - hardly useful for triggering an interrupt.

You need to change the pinMode, it was still set to OUTPUT.

const byte irqPin = 2;

void toggleLED() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(irqPin, INPUT_PULLUP);
  digitalWrite(LED_BUILTIN, HIGH);
  attachInterrupt(digitalPinToInterrupt(irqPin), toggleLED, FALLING);
}

void loop() {
}

Thanks again Whandall.

I have copied your code and it is working - kinda. I am getting a flickering LED which turns fully on/off on button push, then goes back to flickering after a 1/2 second or so.

I have got to this point before, with the flickering. I appreciate that my button is not debounced but the behavior does not change even when I remove my two lead wires from the switch.

Seems like such a basic function, not sure why I am struggling so much with it.

Aha. Got it.

I added a 10k external pull-up resistor on pin 2 and all is working as expected.

It's a shame this isn't shown in the many many online examples. Many thanks Whandall for your help.

B

If you activate the internal pullup - as my suggested code did - you should not need an external one.
But you will have to debounce the button probably.

The first code I posted switched the port out output to use the software interrupt.
This works with pinchange interrupts also, but you have change events only.