Interrupt with delay

Hi Guys, I working on a small project for which I have written some code (please see attached code). All I

am trying to achieve is to pull a digital pin LOW (which normally stays HIGH) for 500ms every time

a falling edge is detected on the interrupt pin. I am not sure where to put delay in the code to ensure the

pin stays low for 500ms.

Can you please help me.

Thanks.

const byte ledPin = 6;
const byte interruptPin = 2;


void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), eoc, FALLING);
}

void loop() {


digitalWrite(ledPin, HIGH);
}

void eoc() {
digitalWrite(ledPin, LOW);

}

Try this. Using delay() is easy but will stop the program for 500ms. Look at the blink without delay example (File, Examples, Digital in the IDE) and the several things at a time post for ways to do non blocking timing.

Set a flag in the ISR and if the flag is set, delay and reset the flag.

const byte ledPin = 6;
const byte interruptPin = 2;

volatile boolean flag = false;  //create flag.  Note volatile for variables changed in ISR

void setup() 
{
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), eoc, FALLING);
}

void loop()
 {

if(flag == true)  // don't really need the == true but makes intent clear for new users
  {
    delay(500);  // stop everything for a while
    flag = false;  // delay done, reset flag
  }

  digitalWrite(ledPin, HIGH);
}

void eoc()
{
  digitalWrite(ledPin, LOW);

  flag = true;  // set flag

}

Thank you @groundFungus for your prompt response. For some reason your code does not compile, it comes up with the following error:

exit status 1
stray '\240' in program

Please advise.

Thanks

No! Do NOT use delay!

const byte ledPin = 6;
const byte interruptPin = 2;

volatile boolean doDelay = false;
volatile unsigned long delayStart = 0;

void setup() 
{
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), eoc, FALLING);
}

void loop()
 {
    if((doDelay == true) && ((millis() - delayStart)) >= 5000L))
    {
       digitalWrite(ledPin, HIGH);
       doDelay = false; 
    }
}

void eoc()
{
    digitalWrite(ledPin, LOW);
    delayStart = millis();
    doDelay = true;
}

Regards,
Ray L.

Try This :slight_smile:

const byte ledPin = 6;
const byte interruptPin = 2;
volatile unsigned long PinTimer;
int onDelayTime = 500;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), eoc, FALLING);
}

void loop() {
  if ((millis() - PinTimer) >= (onDelayTime)) {
    digitalWrite(ledPin, HIGH);
  }
}

void eoc() {
  digitalWrite(ledPin, LOW);
  PinTimer = millis();
}

This resets the blink timer each time the falling is triggered so the output will stay high until 500 ms has elapsed from the last falling trigger
Z

I tried to compile my code and get an error because of a missing interrupt library. digitalPinToInterrupt(interruptPin) needs the library. I change to

attachInterrupt(0, eoc, FALLING);  // interrupt on pin 2

and it compiles without errors or warnings.

How did you copy the code? You must have picked up something outside the code tags window.

I do not recommend delay(). My point was to set a flag in the ISR and do the rest in loop().

zhomeslice:
Try This :slight_smile:

const byte ledPin = 6;

const byte interruptPin = 2;
volatile unsigned long PinTimer;
int onDelayTime = 500;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), eoc, FALLING);
}

void loop() {
  if ((millis() - PinTimer) >= (onDelayTime)) {
    digitalWrite(ledPin, HIGH);
  }
}

void eoc() {
  digitalWrite(ledPin, LOW);
  PinTimer = millis();
}




This resets the blink timer each time the falling is triggered so the output will stay high until 500 ms has elapsed from the last falling trigger
Z

Except.... if the interrupt occurs AFTER the if test evaluates to true, but BEFORE the digitalWrite completes, the output will be set LOW by the interrupt handler, and immediately set HIGH by the loop() code. It will not work reliably.

Regards,
Ray L.

RayLivingston:
Except.... if the interrupt occurs AFTER the if test evaluates to true, but BEFORE the digitalWrite completes, the output will be set LOW by the interrupt handler, and immediately set HIGH by the loop() code. It will not work reliably.

Regards,
Ray L.

Excellent point

Hi guys, thanks for the codes.

I have tried both codes, but they don't work reliably.

@RayLivingston I believe you have identified the right reason for that problem. any suggestions

please.

thanks.