Support Forum

Share your projects and post your questions

Register   or   Sign In
The Forum

IO Pi Plus interrupt-driven input

The IO Pi Plus is a 32 channel MCP23017 GPIO expander for the Raspberry Pi

23/11/2015

Posted by:
jeckardt

jeckardt Avatar

I am trying to use multiple the IO Pi Plus boards to allow the Rpi to read a large number of switches. It's really not practical to poll the switches for input changes -- obvious approach is to use an interupt-driven input structure. I went into this thinking thinking the IO Pi Plus directly provided INT to Rpi on register changes, but after some experimenting and studying the IO Pi Plus schematic, I see that is not the case. Working through the demo-iointerrupts.py example, I see that I as-is I still have to poll each IO Bus for inputs.
It seems that I could probably wire the INTA/INTB pins of each bus, through a level shifter, then into one of the standard GPIO pins. Then I could use GPIO.add_event_callback() to set up a button handler for each IO Bus.
[This project is going to require four stacked IO Pi Plus boards, so managing the button presses is going to be no small matter.]
Has anyone done this? Is there a better way to implement a true interrupt driven input with the IO Pi Plus?
Thanks,
Joe

23/11/2015

Posted by:
andrew

andrew Avatar

To implement a true interrupt-driven input with the IO Pi Plus you will need to connect the interrupt pins on the IO Pi Plus to a GPIO pin on the Raspberry Pi. We did not include this on the IO Pi Plus mainly because with four boards stacked on the Raspberry Pi you would need up to 16 GPIO pins and as the GPIO pins may already be used by another expansion card it would be difficult to make a design that is compatible with all of the other expansion cards available and make it easy to configure. It was easier to leave the interrupt pins unconnected and let the user decide how they want to connect them.

As the interrupt pins are 5V you will need a voltage divider to drop the voltage down to 3.3V before connecting it to a GPIO pin. We have a voltage divider calculator you can use to find suitable values but a 10K between the interrupt pin and GPIO and a 19.1K between the GPIO and ground should work.

To reduce the number of GPIO pins needed you can use the mirror_interrupts function to connect both interrupt pins on each bus together so if an interrupt occurs on any of the 16 pins on the bus both interrupt pins will go high. This way only 8 GPIO pins will be needed for 4 IO Pi Plus boards. When an interrupt is triggered on the Raspberry Pi GPIO pin you will know which bus it occurred on so you can use two read_port function calls to poll both ports on the bus and find out which pin was pressed.

I will try and work on a tutorial to explain all of this better over the next couple of days.

23/11/2015

Posted by:
jeckardt

jeckardt Avatar

Thank you, Andrew. It's good to know I was on the right track. Using the mirror_interrupts is a good suggestion as well.

24/11/2015

Posted by:
andrew

andrew Avatar

I have added a new tutorial onto Github which shows how you can use the interrupt pins connected to the GPIO port.

tutorial3.py demo

After playing around with the code and the Raspberry Pi I found that a level shifter works more reliably than a voltage divider. With the voltage divider, the interrupts would not always reset for some unknown reason. It is also more reliable if the interrupt pins are set to be high by default and then fall low when triggered.

The tutorial uses a function which is triggered in a new thread by a falling edge on the GPIO pin. The function checks the status of the interrupts and returns a list of the pins which are set high.

Hopefully, this should help you with your project.

25/11/2015

Posted by:
jeckardt

jeckardt Avatar

Your notes, comments, and suggestions on this are most appreciated and useful. Thank you!
I assume you used one of the DFC6301 type level shifters? Unfortunately I don't have any of those in-hand.
Did you happen to try a diode/pull-up style converter? I would expect that would give a cleaner level than the voltage divider and might work better, but not sure if "better enough". I'll give that a try since I have the parts on-hand to try it.

25/11/2015

Posted by:
andrew

andrew Avatar

The level shifter I used was one of the 4 channel level converters that we sell in our shop but any sort of logic level shifter should probably work.

15/06/2016

Posted by:
richp999

richp999 Avatar

Hi,Another question on a similar topic - I am using this board to interface with a number of buttons.I have moved over to using Windows 10 IOT on my Pi 2.I have pretty much everything working, but am having trouble with the interrupts.I have the IA and IB connected via your level shifter to 2 gpio ports on the Pi. They are directly connected via the level shifter, no other components. Firstly is this correct ? I havent been able to find a schematic of how to connect the IA and IB pins to the GPIO ports.My interrupt is caught in the c# code on windows 10 iot, but I have having problems specifically resetting the interrupt afterwards.Watching the pin it starts low, when I press a physical button it goes high,. the interrupt is caught. But the the pin stays High from then on.I tried resetting the interrupt by reading PORT_EXPANDER_INTCAPx_ADDRESS (0x10 & 0x11) , but this doesnt seem to work properly.My code reads both these registers when either interrupt (A or B) is caught, in an attempt to reset both interrupts. Interstingly if I catch an interrupt on bank A, the interrupt on bank B will reset , and vice versa. So something is working, but for some reason it wont reset the interrupt on the bank it has just caught.I know most of your examples are in python, but do you have any ideas ?? Thanks..

15/06/2016

Posted by:
andrew

andrew Avatar

Hi

Have you tried using our Windows 10 IOT library for the IO Pi? It includes a ResetInterrupts() function in the IO Pi class for resetting the interrupts which should pull both of the interrupt pins low. Although looking at how the ResetInterrupt function works it does appear to be doing the same as you by reading the INTCAP register.

You may also find the interrupt pins are more reliable with a level shifter if you set them to be high by default so they go low when triggered. I am not sure why this is but it does seem to work more reliably this way. Alternatively, adding a 10K resistor to the interrupt pin and ground may help with making sure the pin pulls back low when it is reset.

Sign in to post your reply


Note: documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view.
Download Adobe Acrobat Reader or other PDF reading software for your computer or mobile device.

Home

Shop

Learn

Forum

FAQ

Contact

0 item

Your cart is empty

Please browse our shop to order from the wide range of Raspberry Pi boards and accessories.

Subtotal:£0.00
View Basket Continue to Checkout