ISR (CHANGE) how to do something without causing fault

I want to alert myself when a pin changes, and the pin value will change very fast so I am using an interrupt to catch when it changes.

Apparently when you use Serial.println the ISR can't handle it and the program crashes. So how can I alert myself that something took place?

ex: A bullet passes over a IR reciever breaking the IR beam and triggers a change on the GPIO for a couple of milliseconds.

I need to know that the bullet was caught, but it looks like you can't put any real logic inside the ISR, only maybe a state change. The problem is, the state would change again way to fast for any VOID LOOP logic to catch a change was made.

int inPin = 12;    // pushbutton connected to digital pin 7
volatile byte state = LOW;
int count = 1;

void setup() {
  Serial.begin(115200);
  Serial.println("Started");
  pinMode(inPin, INPUT);    // sets the digital pin 7 as input
  attachInterrupt(digitalPinToInterrupt(inPin), blink, CHANGE); 
}

void blink() {
   state = !state;
   Serial.println( "This breaks the code causing a panic.")
}

void loop() {
}

Global flag, declared volatile. In outline:


volatile char event_flag=0;
...
ISR () {
event_flag=1;
}

void loop() {
if (event_flag) {
   flag=0;
   do_something();
}
...
}

it looks like you can't put any real logic inside the ISR

Yes, you can, but it should be minimal, and it MUST NOT call functions that depend on interrupts, like serial I/O.

Hi jremington,

I thought about that, but will the loop even catch it once the change happens if it changes back really fast?

In other words, won't the interrupt change the flag, then change it back before the loop can notice something changed?

The interrupt does not "change the flag back". It only sets the flag.

If interrupts happen too fast for the loop function to complete the required tasks, then your code is too slow to handle the event rate.

Derp...

The examples uses this line:
state = !state in the ISR.

I thought that's how you have to handle the change, which would instantly toggle it back and forth, but yes, I can just set it in there and use it elsewhere when I feel like it.

Thanks !

Seems like a bad example, and not as useful as simply setting a flag.

which would instantly toggle it back and forth

Not "instantly", rather only when interrupts occur, which are often random in time.

True, but for my use case you get a LOW for only a few milliseconds before it goes back to high for a long time.

So the flip they used as an example was overwriting before it would catch in the loop. I'm sure it works fine in most cases.

Example is here:

Anyway, thanks for the help, that's what I needed.

That is not fast and easy to catch in a proper constructed loop.

On a standard Arduino, you have 16000 clock cycles per millisecond.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.