timing problems if interrupts deactivated

Hi there,

I’ve written some code to identify the absence of input events to trigger an output a specified time after the last event on input.

Please find the code below:

/*
  TriggerOut_if_delay_on_InterruptIn
 
 Monitors an input for edges and pushes out a pulse if no activity on input.
  
 The circuit:
 * TTL-signal to pin 2 (The signal to be monitored for none-event)
 * Pin 13 (the one with the LED) is the output for the pulse
 
 The program was written and tested with a Arduino Uno R3
 
 created 2015-10-01
 by DaZeller (DaZeller86(at)googlemail.com)
 
 */
 
int outPin = 13;          // pin for pulse-out
int inPin = 2;            // pin for the signal to be monitored
long counter = 5001;      // couter to identify the abscence of a edge

void setup() {
  pinMode(outPin, OUTPUT);
  pinMode(inPin, INPUT);
  attachInterrupt(0, resCount, RISING);  // setup the interrupt 
  digitalWrite(outPin, LOW);
}

void loop() {
  delayMicroseconds(100);
  if (counter < 5000) {
    counter++;
  }
  if (counter == 5000) {
//    noInterrupts();    // Switch of the interrupts seems to disturb the delay() accuracy
    digitalWrite(outPin, HIGH);
    delay(2);
    digitalWrite(outPin, LOW);
//    interrupts();
    counter = 5001;      // after counter is set to 5001 nothing more will happen in main loop, 
                         // except an interrupt will reset counter to 0 and the game starts again.
  }
}

void resCount() {  // This is the ISR. Reset counter if interrupt occoures
  counter = 0;
}

The strange thing is, that the timing of the 2ms pulse is quite terrible if I disable interrupts.
(I thought I had to disable interrupts to prevent problems, if a interrupt occours during the pulse generation)

Does someone know how I get strange results?
Or does someone have other comments to the code? :wink:

best regards

DaZeller

Why should you want to disable interrupt for more than 2 mS?

delay() uses millis() which needs interrupts from a timer...

Its a little bit like moaning "when I nail my hand to the desk it hurts, how can I avoid that?"

I've written some code to identify the absence of input events to trigger an output a specified time after the last event on input.

You seem to have done it in a very convoluted way.

How about capturing the time an event happens from millis() or micros() depending on the timescale then triggering the output if the timeout period is exceeded ? All done in loop() with no need for interrupts, delay() or delay(microseconds().

Hi Whandall,

as I wrote:

I thought I had to disable interrupts to prevent problems, if a interrupt occours during the pulse generation

Thanks for the info about the need of interrupts for the delay().

So I could write:

detachInterrupt(0);
    digitalWrite(outPin, HIGH);
    delay(2);
    digitalWrite(outPin, LOW);
attachInterrupt(0, resCount, RISING);

Is this correct?

The reason why I'm not polling the input is thath i would prevent to miss an event.

DaZeller:
The reason why I'm not polling the input is thath i would prevent to miss an event.

This, with your interrupts disabled and your controller blind in the delay, would miss the same events.

DaZeller:
Is this correct?

No, thats even worse.

Just let the interrupts happen,
in your case there is nothing that needs protection against isr accesses.

If the functionality of the isr is unwanted from time to time,
block it via a volatile flag set in main that is checked in the isr.

volatile bool iBlocked = false;

void myISR() {
  if (iBlocked) {
    return;
  }

// ......

}