Interrupt driven ports on Quick2wire port extender (i2c)

605 views
Skip to first unread message

Dave Shaw

unread,
Aug 29, 2013, 8:19:56 AM8/29/13
to quick2wi...@googlegroups.com
Hi all,

I've got interrupt driven updates working (in python using the RPi.GPIO package) for the standard GPIO pins on the Quick2wire interface board. So now, when a PIR on my alarm goes active the python program on my Pi detects this and prints a lovely message (actually it sends it back to OpenHAB for my home automation to update an item status).

My next task is to build and connect the port extender board and connect all the Alarm detectors to it (14 in all). This will require me to communicate with the ports with I2C instead of the standard GPIO routines I use now. Unfortunately Rpi.GPIO doesn't support I2C yet, so I'm wondering if anyone else has a working interrupt driven I2C monitor which is python friendly? It needs to be interrupt driven as I can't spend CPU cycles constantly polling the pins - I want to be notified there and then!

I know the expander board has interrupt functionality, just can't seem to figure out to use this within a program like I can with RPi.GPIO (these are the examples I used for the GPIO programs).

Any guidance or wisdom would be appreciated

Dave

Andrew Scheller

unread,
Aug 29, 2013, 9:34:11 AM8/29/13
to quick2wi...@googlegroups.com
On the http://quick2wire.com/mcp23017-i2c-port-expander-schematic/
both the INTA and INTB signals connect to pin6 of the I2C sockets
("Int" on http://quick2wire.com/i2c-pinouts/ ). On the
http://quick2wire.com/interface-board-schematic/ pin6 of the I2C
socket connects to pin7 on the Pi's P1 header (as long as you have the
I2C interrupt jumper fitted).
So using RPi.GPIO, you simply need to listen for interrupts on GPIO4 :-)

I haven't played with interrupts myself, so you may need to "configure
something" over i2c to get the port-expander chip to fire interrupts.

Andrew
> --
> You received this message because you are subscribed to the Google Groups
> "Quick2Wire Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to quick2wire-use...@googlegroups.com.
> Visit this group at http://groups.google.com/group/quick2wire-users.
> For more options, visit https://groups.google.com/groups/opt_out.

Dave Shaw

unread,
Aug 29, 2013, 10:35:24 AM8/29/13
to quick2wi...@googlegroups.com, raspb...@loowis.durge.org
Ah... now the fog lifts! Thanks for clearing that up. That sounds fairly straight forward. I have found a good (albeit Arduino) website for enabling interrupts on the MCP23017 and then determining which of the ports actually caused the interrupt. That's my weekend gone!
 
Thanks for your help

Tony Massey

unread,
Jan 29, 2014, 8:05:55 PM1/29/14
to quick2wi...@googlegroups.com, raspb...@loowis.durge.org
In case anyone else hit the same problem as me trying to get interrupts to work using the IO expander board...
Ive been struggling for days trying everything but getting no interrupt back at the interface board. I tried all combinations of setups for the MCP23017 chip registers without joy. Then I checked if there was any signal on pin 20 of the chip (INTA), and there was! It looks like the diode D2 is blocking the INTA signal. If I short this out the interrupt is detected by the PI!
Looking at the board schematic I think the only reason the diodes are there is because the INTA and INTB lines are physically joined together on the board. However, they can be linked in software by setting bit 6 (the Mirror bit) of the IOCON (IO control) register to 1, which joins the INT pins internally.
To get around this issue I'm therfore going to replace diode D2 with a piece of wire, and remove D1 all together, then set the mirror control bit on. 

For ref. here's the setup sequence that worked for me (in python);

# Set IO expander pins direction
bus.write_byte_data(DEVICE,IODIRA,0b11111111)

# setup interrupt comparison values
bus.write_byte_data(DEVICE,DEFVALA,0b00000000)

# setup interrupt comparison: 1=on
bus.write_byte_data(DEVICE,INTCONA,0b00000000)

# setup pull-up resistors: 1=on
bus.write_byte_data(DEVICE,GPPUA,0b11111111)

# set up the control register
# bit 6 = MIRROR bit: if set to 1 the INT pins are internally connected
# bit 2 = The Open-Drain (ODR) control bit enables/disables the INT pin for open-drain configuration.
# the effect of ODR=1 is to pull INT low
# bit 1 INTPOL: This bit sets the polarity of the INT output pin
bus.write_byte_data(DEVICE,IOCONA,0b01000000)

# set polarity: 1=inverted
bus.write_byte_data(DEVICE,IPOLA,0b11111111)

# enable interrupts
bus.write_byte_data(DEVICE,GPINTENA,0b11111111)

# to be safe read INTCAP to clear any interrupt
myports = bus.read_byte_data(DEVICE,INTCAPA)

Cheers,
Tone

Andrew Scheller

unread,
Jan 30, 2014, 4:51:25 AM1/30/14
to quick2wi...@googlegroups.com
> Ive been struggling for days trying everything but getting no interrupt back
> at the interface board. I tried all combinations of setups for the MCP23017
> chip registers without joy. Then I checked if there was any signal on pin 20
> of the chip (INTA), and there was! It looks like the diode D2 is blocking
> the INTA signal. If I short this out the interrupt is detected by the PI!

As previously mentioned, I've not experimented with interrupts on the
Quick2Wire board myself (so can't comment on your example code), but
if diode D2 is blocking the signal, I wonder if that means you
accidentally fitted it the wrong way around? Or maybe you've simply
got a defective / damaged diode?

I'm also guessing that the diode(s) means the Pi can only detect when
the INT pin goes high?

Andrew

Tony Massey

unread,
Feb 6, 2014, 6:56:05 PM2/6/14
to quick2wi...@googlegroups.com, raspb...@loowis.durge.org
I think the cause of the problem with the interrupt not triggering was that I had set the INT pin to go low on the IO expander (as you suggested might be the case).
However I do want it to work that way because I am setting the internal pullup resistor on the Pi's GPIO pin, so that it triggers a callback routine when the pin is pulled low.
So I did remove the diodes from the board in the end and replaced D2 with plain wire, and the interrupt is being picked up by the Pi now.
I've linked the rotary encoder output from a Lego NXT motor to 2 of the IO expander pins. I've got some python code running on the PI so that when the encoder values change the interrupt triggers the program to read the IO port and put the port value on a queue. A thread running in parallel gets the port values in FIFO sequence from the queue and calculates the direction of movement of the motor. I've used interrupts and queues in the program rather than having a read loop in the main code, as its important not to miss any readings from the encoder. Tests so far seem to be working OK. Next stage is to combine this with an adafruit motor shield (v2) so that I can control motor speed and distance directly from the PI (wish me luck!).     

Andrew Scheller

unread,
Feb 6, 2014, 7:56:25 PM2/6/14
to quick2wi...@googlegroups.com
> I think the cause of the problem with the interrupt not triggering was that
> I had set the INT pin to go low on the IO expander (as you suggested might
> be the case).
> However I do want it to work that way because I am setting the internal
> pullup resistor on the Pi's GPIO pin, so that it triggers a callback routine
> when the pin is pulled low.

The Pi does also have internal pull-down resistors ;-)
http://raspi.tv/2013/rpi-gpio-basics-6-using-inputs-and-outputs-together-with-rpi-gpio-pull-ups-and-pull-downs

> expander pins. I've got some python code running on the PI so that when the
[snip]
> movement of the motor. I've used interrupts and queues in the program rather
> than having a read loop in the main code, as its important not to miss any

For timing-critical code, you may get more reliable results using
(compiled) C rather than (interpreted) Python. Of course Python is
still useful for prototyping your logic is correct, before
implementing the time-critical parts in C.

> motor speed and distance directly from the PI (wish me luck!).

Good luck!

Andrew
Reply all
Reply to author
Forward
0 new messages