Arduino interrupt clear issues

I am working on a project that has an external device that produces pulses for arduino to count.

The count is not very clean so what I am trying to do is to detach interrupt after the first interrupt and just use delay to debounce. The thing is, it always counts twice. I read about the issue with not clearing a counter:

https://code.google.com/p/arduino/issues/detail?id=510

(please copy paste. Inserting link isn't working.)

I wonder if anyone is up to date with this issue and could give me guidance.

OK, I checked out Winterrupts.c and made the recommended change. It works now. The issue dated back in 2011-2012. If this change is not made on Arduino IDE 1.6.5, I can only imagine that the ideal of clearing interrupt flag before attaching ISR is not well received by the Arduino folks. There must be some reasons to not clearing the flag. Can someone provide some examples? Especially when considering not having attached an ISR means there is no need to be servicing the interrupt source. This arrangement is odd to me. Maybe they should add a macro to clear interrupt flag so everyone is happy.

I can't get a response from the link in the original post, so I'm not sure what you mean when you say,

liudr:
I checked out Winterrupts.c and made the recommended change.

I think that you're talking about attachInterrupt(), and that it doesn't clear a pending interrupt flag when it's called. I suspect that the recommended change is to add code to attachInterrupt(), in WInterrupts.c, to clear the associated interrupt flag before the interrupt is enabled.

Before I embarrass myself by droning on about the wrong subject, tell me: have I got that right?

You got everything correct. I tried several times now to fix the link but the stupid forum won't let me. It always inserts %22 in the link, or not recognizing https. I tried everything like removing https, changing it to http.

https://code.google.com/p/arduino/issues/detail?id=510

Just copy and paste then. Don't click the stupid link.

IE seems to be part of the problem too. Now that I'm using firefox, at least I can post an address without it turning into a link (i.e. bad link) all the time.

We just went through something like this, here: Left over variables on reset or strange interrupt behaviour - #9 by tmd3 - Programming Questions - Arduino Forum. In that case, the programmer used the internal resistors on the external interrupt pins as pullups, and set the mode to FALLING. He saw spurious interrupts already active when he called attachInterrupt(). It looks like the external interrupt pins were logging a transition during the few microseconds while they were floating, and the system processed the interrupts immediately when they were enabled. Is that something like what you're seeing?

As for whether attachInterrupt() should reset the associated interrupt flag, I would vote against it. Here's why:

It's easy enough for me to reset the flag myself, by writing a 1 to it, immediately before calling attachInterrupt(). If attachInterrupt() reset the flag for me, when I wanted to process an interrupt that was pending before calling attachInterrupt(), I'd have to test the flag before calling it, and then do something if the flag were set. One thing I couldn't do would be to call the ISR - I'd have to process the pending interrupt with some separate code. And, there's a chance that an interrupt event, whose occurrence I'd want to know about, would happen between the call to attachInterrupt() and the statement that actually enables the interrupt - if that happened, I'd miss it for sure.

As I see it, leaving any pending interrupts alone leaves me more options, and it's easier for me to deal with, than resetting them. All I have to do is ask, "Do I want to process a pending interrupt here?" I should probably ask that question every time I enable any interrupt, and deal with the flag appropriately.

That's exactly what I meant: pending interrupt flag. I agree with you but I also think, because the arduino abstraction (such as INT0 is arduino interrupt 0 on 328 but arduino interrupt 2 on 2560), they should provide resetPendingInterrupt() to help developers to avoid mistakes, and to talk about this issue of pending interrupt. Good memory of 8259A is surfacing now (interrupt priorities etc.) :smiley: Anyone calling INT 10, 13, or 21?

It seems like a bug to me. Why have an abstracted interface and then require direct access of a register? I always clear the flag before enabling an interrupt. I just finished writing button debounce code that depends on that.

Can you provide a real life case where keeping a previously latched pending interrupt is desirable? I'm sure it must happen, I just can't think of a situation.

jboyton:
Can you provide a real life case where keeping a previously latched pending interrupt is desirable?

Technically, we want to respond to latched interrupt flags immediately on enabling the interrupt all the time - when we disable interrupts globally for atomic access to a multibyte variable, and when we return from one interrupt while another is pending. But, that doesn't seem to be what we're talking about. I think that we're talking about when we might enable a specific interrupt, and care about whether an interrupt is pending when we do it. I think also that we're talking about times when the interrupt has been disabled for some non-trivial amount of time, as opposed to disabling interrupts globally to read a volatile variable.

I have a real-life case. I'm debouncing a switch connected to pin 2 using the external interrupt. The sketch enables the interrupt in setup(). The ISR logs the time of any state change of the switch and the state, and disables itself. The sketch reenables the interrupt every 6.67 milliseconds. The process runs until there hasn't been an interrupt for 0.1 seconds; then loop() processes the transition and, if it's a switch closure, changes the display mode.

So, the interrupt function is used as a latch to log the fact that the switch changed, and when it changed. loop() pays little attention, merely reenabling the interrupt every so often to let the ISR timestamp any changes, and testing how long it's been since the last change to see if it's time to act. I'm using attachInterrupt() and detachInterrupt() to manage the interrupt state, and they're fast enough in this application.

So, that's a real-life case, with repetitive enabling of the interrupt, where I care about stuff that happened while the interrupt was disabled, repeatedly. I'll admit that it's a narrow application: it works because I don't care about exactly what happened while the interrupt was disabled, only that something happened, or nothing did. And, debouncing doesn't really call for precise timing - if the switch responds a few milliseconds faster for one operation than for the next, no one cares.

tmd3:
I have a real-life case. I'm debouncing a switch connected to pin 2 using the external interrupt. The sketch enables the interrupt in setup(). The ISR logs the time of any state change of the switch and the state, and disables itself. The sketch reenables the interrupt every 6.67 milliseconds. The process runs until there hasn't been an interrupt for 0.1 seconds; then loop() processes the transition and, if it's a switch closure, changes the display mode.

Thanks for the real-life case. I knew that some had to exist.

I'm not sure you really need an interrupt for the debouncing part. After the initial interrupt all you really want to do is check and clear the latch periodically until it isn't set anymore. Maybe the easiest and most portable way to do that is with AttachInterrupt but the most parsimonious method would be to test and clear the bit in the external interrupt flag register without actually enabling the interrupt.

jboyton:
... the most parsimonious method would be to test and clear the bit in the external interrupt flag register without actually enabling the interrupt.

Indeed. All I need is that something I can see will latch the fact that there's been a state change on the input. I can keep an eye on that from the sketch. But, we were talking about an abstracted interface. Is there a way to do it without an interrupt, and without direct register access?

I'd expect that applications that want to manage an ISR in real time would typically be time-critical, and couldn't tolerate the overhead of an abstracted interface. It may be hard to find an application that doesn't already need direct register access, but needs to manage the interrupt this way.

I don't think the Arduino abstraction exposes the flag register. But that's not to say it couldn't.

There doesn't have to be a severe penalty with portable code.

If you don't use arduino abstraction, you can easily get caught. That was my point. If you use pin 2 on UNO for arduino interrupt 0, and have to access the interrupt flag bit using register name for it, you will be resetting the wrong flags when you switch to arduino mega, since MEGA's pin 2 is INT4, not INT0. Then the 32U4 based boards even have different register structures. Having a macro that clears Arduino interrupt numbers will solve all the problems. It's not that hard to write. Same #if just different commands. I'll make a recommendation but don't expect the team to take it though.