Open GoogleCodeExporter opened 8 years ago
This won't work because during the Interrupt handler (keySwitchEvent),
interrupts are off. delay() works by counting timer interrupts. The timer never
gets interrupted, therefore delay() will wait forever.
The primary principle in creating any interrupt handler routine is to be very,
very short and return control back to the main program as soon as possible.
"Short" means microseconds. If you keep that in mind, it will guide your code
design and you'll stay out of trouble.
The way to handle this is to create a volatile variable that is set inside the
interrupt handler. Check the value of the variable inside the main loop. If
it's set, reset it and then go about your work.
Remember that switches bounce. You might want to use my tigger library
(https://code.google.com/p/tigger/) to handle your switches. See the usage
information there in the wiki.
Original comment by m...@schwager.com
on 13 Aug 2013 at 11:18
[deleted comment]
To m...@schwager.com:
Thanks for the response... However, I have a few more questions and comments on
interrupts. My code works now kind of as written... The problem I had above was
not with delay but with the while condition. I forgot to use digitalRead():
while (keySwitchState1 == LOW) should be while (digitalRead(keySwitchState1) ==
LOW).
The delay didnt work but did not wait forever it just didn't delay at all. So I
tried to increase it to 20000 instead of 2000 and it works!!! WEIRD HEY??? Any
I a have a weirder problem. The function I wrote relaySet works fine when I
call it in LOOP portion but not in setup. Nor does it work when I call it in
the interrupt function keySwitch1Event. If I take the code out of the relaySet
function and put it in the keySwitch1Event then the relay gets set. Can you not
call other function from within an interrupt??? I do now understand its not a
good practice because I should be doing something quick inside and interrupt
and get out but this shouldn't be a limitation is it? What I am doing is using
a keySwitch as an override to the normal functionality, when it is turned I
want 2 lights to flash alternately so one knows it is in override mode. I could
check in the loop function over and over to see if the key is turned but it is
almost perfect to have and interrupt handle it maybe I should just set a flag
and have my loop check for the flag and handle it? Again though why when I use
interrupts does my relaySet function not work in setup portion of the program
and when I remove the interrupt it works just fine? Thanks again for the
advice!! SMART SMART :) -Justin
Original comment by timothyf...@gmail.com
on 14 Aug 2013 at 12:16
First of all, using delay() inside any function that's called from an interrupt
is broken, so you shouldn't expect it to work at all inside an interrupt. If it
seems to work in any fashion then ok, I can't tell you why it would work, but I
can tell you that it should not and I would not trust the code that did so. The
exception to this is if you set the I-bit inside your event function. But then
you would have to be very deliberate about what you were doing.
The ATmega datasheet says, "When an interrupt occurs, the Global Interrupt
Enable I-bit is cleared and all interrupts are disabled. The user software can
write logic one to the I-bit to enable nested interrupts..." You are not
writing to the I-bit hence your code does not have nested interrupts.
The delay(int) function calls the micros() function (see cores/arduino/wiring.c
under the installed arduino code on your machine). micros() looks at the
timer0_overflow_count variable, which is updated- via an interrupt handler-
whenever TIMER0 overflows. TIMER0 is started during init(), which is loaded
into your Arduino the same as setup() and loop(). init()'s source is also in
wiring.c.
So fundamentally, you have an issue using delay(). Again, how/why it does
anything is explainable I'm sure but I don't have the time to look at it.
You should be able to call a function from within an interrupt handler, but
again you have delay()s in there so I don't know what is happening.
Regarding relaySet() in setup(), I would do the Serial.begin() at the beginning
of setup(), then start printing out the values of things that you expect to see
inside relaySet(). The only way to figure out why it doesn't work within
setup() is to check your expectations versus reality. What are the values of
your variables inside the function? Which leg of the if command is run? Why?
Again, I don't expect anything with delay() to work inside an interrupt. Weird
things will happen (if they happen at all), which is what you've found.
Original comment by m...@schwager.com
on 15 Aug 2013 at 6:39
Original issue reported on code.google.com by
timothyf...@gmail.com
on 10 Aug 2013 at 8:02Attachments: