Want to learn interrupts - comprehension question

Hi!

I wanna learn to use interrupts, so I read some tutorials, watched some youtube-videos and finally tried some stuff in the IDE for myself.
Everything fine so far, all stuff worked as expected.
BUT: now I want to do some advanced blinky-stuff. Just like the well known BIOS-beep-codes, I want to flash the LED two or more short times every x seconds.

My very short test script looks like this:

#include "TimerOne.h"  
const int ledPin = 13;
int every_x_seconds = 5;

void blinken() {

  int i = 1;
  do { // set the LED with the ledState of the variable:
    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
    delay(200);
    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
    delay(200);
    i++;
  } while (i <= 3);
  
}

void setup()   {
  pinMode(ledPin, OUTPUT);
  Timer1.initialize(every_x_seconds * 1000000);
  Timer1.attachInterrupt(blinken);
}

void loop(){


}

But now it just blinks one short moment "every_x_seconds", not 3 times as expected. Why?

PS: I know that I have to keep the interrupt-code short and the "delay()" is only used for me figuring out, how to do... Speaking about this: Whats the way to do this?

Thanks for reading my post and I appreciate every help :slight_smile:

So is ledPin and input or an output? Cant be both at the same time.

    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
    delay(200);
    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
    delay(200);

This is code for "inverting". It reads the current state and inverts it ( the ^1 ).

so to speak:

digitalWrite(ledPin, digitalRead(ledPin) ^ 1)

write on LedPin the inverted state of what u read now on LedPin.

I didn't tell, but the function blinken() works fine if put it in loop()

Heh I've got no idea how that works. Personally I'd specify a pin to either be an input, and read from it, or specify an output and write to it. I wouldn't mix on the same pin on the same line.

I know that I have to keep the interrupt-code short and the "delay()" is only used for me figuring out, how to do...

delay() will not work properly inside an ISR. delayMicroseconds() does, I believe. So you could change your code to:

delayMicroseconds(200000UL);

But would be better to rewrite the ISR to set a flag that you then check for and act on in loop().

You should NOT use delay or any kind in an ISR - it completely defeats the point of using interrupts.

Reading an output pin is perfectly legitimate, and will return the current state of the pin.

Regards,
Ray L.

Reading an output pin is perfectly legitimate, and will return the current state of the pin.

Learn something new every day. :slight_smile:

More rationally, don't delay more than a few 100us in an ISR. For instance I've
used delayMicroseconds (10) in an ISR to generate stepper motor control pulses,
this is perfectly valid.

Somethings don't / can't work in an ISR and busy-waiting is one of them - Serial calls
and delay() busy-wait, so they can jam the entire system if called in an ISR and they
sit there waiting for something to change.

By default interrupts are disabled throughout the ISR. You can re-enable interrupts
explicitly before returning, and thereafter delay() and Serial (for instance) will
work, but you had better understand what re-entrant code is before you do this,
since the ISR is then potentially re-entrant.

Yes, you can re-enable interrupts inside your ISR so that delayMicroseconds() and the communication functions work. A classic case is reading a sensor such as an SPI accelerometer inside an interrupt so that you get a precise timing on the readings.

If you forget to enable interrupts and call one of the delay functions then it will lock up at a random time, when the timer underneath the delay overflows and tries to call its own interupt.

tammytam:
Heh I've got no idea how that works.

digitalWrite(ledPin, ! digitalRead(ledPin));

is a very common way of inverting the value of a pin

Pins that are set as OUTPUT can always be read - though much of the time it is rather pointless.

...R

Robin2:
digitalWrite(ledPin, ! digitalRead(ledPin));

is a very common way of inverting the value of a pin

Pins that are set as OUTPUT can always be read - though much of the time it is rather pointless.

...R

Yes that's ignorance on my part. Despite never reading it anywhere I must of decided that pins set as OUTPUT can only be written to and not read. Definitely good to know though.