Solved. Interrupt doesn't go back into main loop

Hi all, I’m trying to figure out external interrupts and I’m having a couple of problems. For my main program I have a single LED fading in and out. I have a shock sensor for the interrupt on pin 3, and when it reads HIGH, it should go into the interrupt function, start a motor for a few seconds, then jump back into the main loop. When the sensor gets a shock it jumps out of the main loop, starts the motor, but that’s it. It never turns the motor off, or jumps back into the main loop. Any help is much appreciated!

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
int pump = 8;         // relay is attached to pin 8
int x = 3000;

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
  pinMode(pump, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(3), interrupt, HIGH);
  
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}

void interrupt(){
 digitalWrite(pump,HIGH);
 delay(x);
 digitalWrite(pump,LOW);
 }

Elnolan99:
void interrupt(){
digitalWrite(pump,HIGH);
delay(x);
digitalWrite(pump,LOW);
}

Move the pump code out of the ISR. Within the ISR set a volatile flag to indicate an interrupt has been acknowledged. Use this flag to enable the pump code. Clear the flag when the pump sequence is finished.

delay(x) can work if you don't need to be doing anything else at all for three seconds. If other things need to happen look up the 'doing several things at the same time' tutorial so delay() can be replaced.

dougp beat me to it but I’ll post for posterity anyway:

Don’t do this in an ISR:

delay(x);

ISRs need to be quick snaps fingers. delay() relies on interrupts which are blocked when you’re inside an interrupt.

Set a flag and do you motor control and timing outside of the ISR. Something like:

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
int pump = 8;         // relay is attached to pin 8
int x = 3000;

volatile bool
    bFlag = false;
    
// the setup routine runs once when you press reset:
void setup() 
{
    // declare pin 9 to be an output:
    pinMode(led, OUTPUT);
    pinMode(pump, OUTPUT);
    attachInterrupt(digitalPinToInterrupt(3), interrupt, HIGH); //HIGH or RISING?
 
}

// the loop routine runs over and over again forever:
void loop() 
{
    // set the brightness of pin 9:
    analogWrite(led, brightness);
    
    // change the brightness for next time through the loop:
    brightness = brightness + fadeAmount;
    
    // reverse the direction of the fading at the ends of the fade:
    if (brightness <= 0 || brightness >= 255) 
    {
        fadeAmount = -fadeAmount;
    }
    
    // wait for 30 milliseconds to see the dimming effect
    delay(30);

    if( bFlag )
    {
         digitalWrite(pump,HIGH);
         delay(x);
         digitalWrite(pump,LOW);
         bFlag = false;
        
    }//if
}

void interrupt()
{
    bFlag = true;
}

@Elnolan99, please do not cross-post. Other thread removed.

That worked. I see what your saying about the interrupt function, just get in get out. So, at first it actually got stuck in the interrupt loop. I added a small delay to the end of the program, and it works great after that.

Change title to mark post as "solved" ?

When an interrupt completes it always returns to continue the code that was being executed at the time the interrupt was triggered. That code may or may not be in loop()

...R

Robin2:
When an interrupt completes it always returns to continue the code that was being executed at the time the interrupt was triggered. That code may or may not be in loop()

The problem here is that attempting to use "delay()" inside an interrupt simply (effectively) halts the processor. That is why it never returns.

If you use proper code, you do not need interrupts anyway. :grinning:

I'll spare everyone repeating the "newbies and interrupts" rant. :sunglasses: