Using the MCP23008 interrupts, get 2 INT pulses.. one press, one release.

Thanks for reading my question.

Can you please suggest a way to handle the fact that the MCP23008 generates an interrupt on CHANGE of state of the GPA0-7 pins. That CHANGE apparently is the reason I get an interrupt output when, say, a button on GPA2 is pressed, and then an INT pulse again when the button is released. This causes two calls to the ISR, one for each change of state of the pin. The datasheet doesn't offer RISING, FALLING, LOW, HIGH options.. it simply says that interrupts are generated with 'change'.

So, generally speaking, what approach is considered good practice to prevent two calls to the ISR?

I did try adding noInterrupts() to the ISR.. not good. I have looked for couple days for a solution. No luck yet. Thanks.

Non... The interrupt just tells you something changed. It's up to you to decide you want to do something with it. And if you're using the MCP23008 for buttons interrupts are overkill anyway...

The datasheet doesn't offer RISING, FALLING, LOW, HIGH options.. it simply says that interrupts are generated with 'change'.

True but if you configure the DEFVAL register you can interrupt on change from the default value. So if you configure all buttons unpushed as the default you should get one interrupt on press and no interrupt on release.

septillion:
------> And if you're using the MCP23008 for buttons interrupts are overkill anyway...

Thanks for the reply. This comment has my curiosity aroused. I am using the Trinket M0, 5 pins total. All pins except 1 are 'busy', thus the MCP23008. Where's the 'overkill' ? I must be overlooking a good alternative.

Thank you.

Grumpy_Mike:
True but if you configure the DEFVAL register you can interrupt on change from the default value. So if you configure all buttons unpushed as the default you should get one interrupt on press and no interrupt on release.

Thank you. I see your helpful replies to others here quite often and the shared knowledge has accelerated my learning curve. Thank you for that.

I am enthused with the suggestion regarding the DEFVAL reg. I had previously visited that method and tried a couple things but I must have done it wrong and abandoned the failed attempt. I will now re-investigate, tinker, and otherwise give it my best shot. Thank you again for your expertise and time to reply.

Regards, Gov.

"Stock" answer:


Govner:
Thanks for the reply. This comment has my curiosity aroused. I am using the Trinket M0, 5 pins total. All pins except 1 are 'busy', thus the MCP23008. Where's the 'overkill' ? I must be overlooking a good alternative.

Whenever I see a post which includes the word "interrupt", I instinctively cringe.

Seems you - and many other "newbies" of course - do not understand what an interrupt is.

An interrupt is a mechanism for performing a task that can be performed virtually instantaneously, that must be performed virtually immediately, and that is not in itself intended to affect the flow of the main program (or delay it) in any way. Servicing a pushbutton essentially tends to fail all three criteria. The terms "instantaneously" and "immediately" are here defined in microprocessor, not human context, that is in terms of microseconds.

You wish to "interrupt" the operation of a particular part of your code. This is quite different to the above; to do this, you must insert decisions into the code where you wish it to be "interrupted".

What you can do - if precise timing is necessary and it is perfectly valid - is to record a value of millis() within an ISR so that you know precisely (to plus or minus a millisecond) when an event occurred. And while an interrupt cannot affect the flow of the main program, it can do something (called a flag) which is recognised in the main loop to affect the flow of that program.

The trick is to write "non-blocking" code. This prohibits the use of "While" loops or equivalent constructs (which automatically precludes "delay()"), but is instead, a chain of "If" constructs within the main loop(). Which incidentally, is a state machine. The important thing is that many different tasks are allowed to be performed apparently simultaneously given that each only does what it must at any given instant, promptly passing on to the next.

De-bouncing of contact closures or opening is performed by such a sub-process which repeatedly polls a button, key or switch and indicates a valid press or release only when a change from a previously accepted state is maintained on every poll while the millis() count advances a given interval, such as ten (milliseconds). Every time the change reverts to the previous within the prescribed de-bounce interval, the status is reset and a new starting millis() count will then be determined if and when a change from the previously accepted stable state is again found.

The interrupt pin on this device. Need not, and probably should not, be used to generate an interrupt. I use them by polling them ( looking at them frequently ) to save time interrogating them with the I2C or SPI protocol, dependent on the chip variation. I normally use the 16 pin version.

I have used this technique many times to make efficient musical instruments where many switches have to be monitored for change. I do not consider their use to be overkill, in fact they are my chip of choice over input or output shift registers.

The internal pull up resistors alone is a win over a shift register as is the inversion of polarity of an input read and pin change monitoring.

Grumpy_Mike:
The interrupt pin on this device. Need not, and probably should not, be used to generate an interrupt. I use them by polling them ( looking at them frequently ) to save time interrogating them with the I2C or SPI protocol, dependent on the chip variation. I normally use the 16 pin version.

My comment of course, was specifically in respect of the misunderstanding of interrupts in the processor itself.

The "interrupt" pin of the MCP23008 and such like chips, could just as well be considered a "status" indicator.

Much food for thought for a "newbie". Thanks for all the super advice gents. Regards, Gov.

This discussion of the MCP23017, MPC23008's big brother, may be relevant/useful.