Delay() doesn't work inside ISR routines, but here I have used it in loop and outside interrupt section still Delay is not working, however there isn't any error coming. What is wrong?
int L = 2;
volatile int done0=0; //ISR variables
void recordL(); //ISR 1
void setup() {
Serial.begin(9600);
Serial.println("Start");
pinMode(L,INPUT);
}
void loop() {
interrupts();
attachInterrupt(0,recordL,RISING);
done0=0;
while(!done0)
{
Serial.println(millis());
}
noInterrupts();
Serial.println("Detected");
delay(5000);
Serial.println("After Delay");
}
void recordL()
{
Serial.println("in Interrupt0");
done0=1;
}
3 Answers 3
noInterrupts();
Serial.println("Detected");
delay(5000);
delay()
won't work with interrupts turned off.
-
Ok. Is there need to off interrupt ? or detaching it?MeetR– MeetR2017年11月15日 07:22:00 +00:00Commented Nov 15, 2017 at 7:22
-
If you don't want that interrupt while you are delaying and printing, detach the interrupt.2017年11月15日 20:50:12 +00:00Commented Nov 15, 2017 at 20:50
Do I need interrupts() noInterrupts() in the loop section?
Yes, you do. Always.
The optimal workflow is
- In the ISR itself, just raise a flag or directly change some global variable.
- In the
loop
you first copy that flag/variable to a local variable, using interrupts/noInterrupts to prevent the ISR changing the value while you are using/copying it.
Assignment are not atomic in Arduino World. That means that the value you are copying can change while you are doing it, and you end with garbage in your variables. Or, worse, it can change between one statement and the next. Try to debug that.
This is how you do it. In this example, I'm using an interrupt to manage a button (with debouncing). I need to detect state (pressed/not pressed) and timing (how long you pressed it). I can't directly use lastFallingEdge
in loop
; I copy it first so it won't change while I'm using it.
volatile unsigned long lastFallingEdge = 0; // For debouncing.
volatile boolean bPressed = false;
void buttonInterrupt(void)
{
lastFallingEdge = millis();
bPressed = true;
}
void loop()
{
if(bPressed) {
noInterrupts();
bPressed = false;
unsigned long falling = lastFallingEdge;
interrupts();
unsigned long len = millis() - falling;
// Do something.
}
}
-
In other answer it is mentioned that Delay won't work after noInterrupts(). How to deal with that?MeetR– MeetR2017年11月15日 08:14:08 +00:00Commented Nov 15, 2017 at 8:14
-
You put the delay() in loop(). You call the delay() after checking that an interrupt occurs.user31481– user314812017年11月15日 08:18:17 +00:00Commented Nov 15, 2017 at 8:18
-
There is the timestamp! Well done @LookAlterno. Perhaps the interrupt can stop updating the 'lastFallingEdge' while it has not been processed in the loop (while the flag is still true). Can the flag (byte) be reset after the interrupts are turned on ? (sorry for nitpicking).Jot– Jot2017年11月15日 08:29:24 +00:00Commented Nov 15, 2017 at 8:29
-
1Can the flag be ..? No. Look: 1) "loop()" calls "interrupts()", 2) An interrupt arrive, ISR is called, bPressed is set to true; 3) "loop()" execute "bPressed=false;". Now your system is in a inconsisten state (and you missed that button press). Interrupts are tricky; you have to keep it short and simple.user31481– user314812017年11月15日 08:40:47 +00:00Commented Nov 15, 2017 at 8:40
Delay() function works by using timer interrupts internally. If you disable all interrupts using NoInterrupt function , then how will it work. Using that function is not recommended in code, as it causes unexpected misbehaviors.
-
Yes got it. I am facing one more issue here, delay is not working when 2 ISR gets executed at same time (delay is in loop section), is that because there are only 2 interrupts in arduino and delay can't find free interrupt and so can't work?MeetR– MeetR2017年11月15日 13:37:15 +00:00Commented Nov 15, 2017 at 13:37
-
Delay () in loop () doesn't work cz it comes after nointerrupt() functionMitu Raj– Mitu Raj2017年11月15日 13:39:30 +00:00Commented Nov 15, 2017 at 13:39
-
This is happening also after removing nointerrupt() (means after keeping interrupt always on).MeetR– MeetR2017年11月15日 14:07:06 +00:00Commented Nov 15, 2017 at 14:07
-
Only attach interrupt is needed here....not needed in loop() ..only in setup()Mitu Raj– Mitu Raj2017年11月15日 14:09:54 +00:00Commented Nov 15, 2017 at 14:09
loop
do the thing.