2

This question is not for a project, I am just trying to understand what happens and why.

The sketch below works as expected as long as the ISR trigger is FALLING. The red led in the main loop is blinking, apparently without any disturbance from the interrupts. The question is what goes wrong, and why, when the ISR trigger is set to LOW.

int sensorPin3=3;
int ledPinGreen=12;
int ledPinRed=11;
int sensorStatus;
byte ledGreenStatus;

void setup() {
pinMode(ledPinGreen,OUTPUT);
pinMode(ledPinRed,OUTPUT);
pinMode(sensorPin3,INPUT_PULLUP);
ledGreenStatus=HIGH ;
Serial.begin(9600);
}

void loop() {

attachInterrupt(digitalPinToInterrupt(sensorPin3), sensorOn, LOW);
digitalWrite(ledPinRed,HIGH);
delay (5000);
digitalWrite(ledPinRed,LOW);
delay (5000);
}


void sensorOn()
{
static unsigned long lastInterruptTime=0;
unsigned long interruptTime=millis();
if(interruptTime-lastInterruptTime>100)       
{                                            
digitalWrite(ledPinGreen,ledGreenStatus);
ledGreenStatus =! ledGreenStatus; 
lastInterruptTime=interruptTime;      
}
}

If the sensor is activated and the signal on interrupt pin 3 is LOW, sensorOn will be executed. What happens if the ISR has been executed once? Does the program return to the main loop to the place where the interrupt was initiated and then right back to the ISR, or does it stay in the ISR without getting back to the mainloop for as long as the signal stays LOW?

If the sensor is activated for a couple of seconds: 1) if the program keeps running the ISR, I would not expect activity from the red led (main loop), but that led is blinking, with delay of about 2 seconds (without the interrupt that should be 5 seconds). This way it looks to me that the program returns to the main loop, but the delay time is wrong, so it doesn’t return to the right place, or the timing is not correct anymore. Why doesn’t this happen with the ISR trigger set to FALLING? Is the amount of interrupts disturbing the timing of the main loop delay?

2) if the program keeps executing the ISR but returns to the main loop every time in between, I would expect the millis() to be updated every time. In that case I would also expect the green led to blink because of the debouncing time. However the green led is not bliking. This makes me think that the program stays in the ISR so the millis() are not updated and the green led won’t blink. But that doesn’t match with the red led behaviour.

3) if the sensor is only activated for a short amount of time, the red led turns on or off the moment the signal on the interrupt pin is no longer LOW. No visible delay. I don’t understand why a longer LOW time on the interrupt pin makes a blink with about 2 seconds delay and a short LOW time makes no delay at all.

Thank you in advance for your help!

1
  • Please, post your complete, working sketch. The code you provided is incomplete and doesn't compile.
    – user31481
    Oct 13, 2017 at 21:12

3 Answers 3

1

As Look Alterno said in another post, the key is that the ISR is called every time the condition is fulfilled. Your condition is LOW, so, every time the MCU find the pin in LOW, it call ISR ... thousands of times each second. That takes lot of time and that is what makes your code slow.

Solution: You have to set your interrupt to RISING, FALLING or CHANGING, but not LOW or HIGH. RISING and FALLING only look for an edge in the input signal, so they will call ISR only one.

BUT ... you have to debounce your input pin if you have it connected to anything mechanical, or else you will get several RISING and FALLING in a quick serie.

Also, you only need execute attachInterrupt once, in the setup

0

You need to understand the concept of an interrupt.

When a given condition is meet (a timer, a button, a signal), an ISR is called. Whatever the MCU was doing at that time is "suspended". In practical terms, it doesn't matter what it was doing when the interrupt comes.

ISR must be as short as posible (and don't call Serial, anything comms related),

Once the ISR is finished, the MCU continues the execution of the main program as if the interrupt never happened. (Almost; ISR changes things in the program).

If the same condition occurs again, the same ISR will be called again.

The usual pattern is just signal a condition inside the ISR and testing it inside the loop, like

bool buttonPressed = false;

void loop() {
   if (buttonPressed) {
     // Execute some action.
    buttonPressed = false;
    }
  ...
 }

void ISRButtonPressed() {
  buttonPressed = true;
}

There is no state, no memory. Each time is the same thing.

2
  • ok, so if the MCU continues the execution of the main program as if the interrupt never happend, then why does the red led blink with a delay time of about 2 seconds when the sensor is activated for say 10 seconds, and not with a delay time of 5 seconds as it does without the interrupt?
    – Rob
    Oct 13, 2017 at 21:44
  • @Rob. Post your complete, working sketch to answer your question.
    – user31481
    Oct 13, 2017 at 21:46
0

The question is what goes wrong, and why, when the ISR trigger is set to LOW.

edge vs. level triggered interrupts.

Read the datasheet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.