Skip to content

Commit 50b3978

Browse files
authored
Merge pull request #14 from jardiamj/improve_interrupt
Improve interrupt
2 parents 999b4f7 + 5383e4a commit 50b3978

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed

adafruit_mcp230xx/mcp23017.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
_MCP23017_GPPUB = const(0x0D)
5050
_MCP23017_GPIOA = const(0x12)
5151
_MCP23017_GPIOB = const(0x13)
52+
_MCP23017_INTFA = const(0x0E)
53+
_MCP23017_INTFB = const(0x0F)
54+
_MCP23017_INTCAPA = const(0x10)
55+
_MCP23017_INTCAPB = const(0x11)
5256

5357

5458
class MCP23017(MCP230XX):
@@ -218,7 +222,6 @@ def default_value(self):
218222
def default_value(self, val):
219223
self._write_u16le(_MCP23017_DEFVALA, val)
220224

221-
222225
@property
223226
def io_control(self):
224227
"""The raw IOCON configuration register. Bit 1 controls interrupt
@@ -234,3 +237,43 @@ def io_control(self):
234237
@io_control.setter
235238
def io_control(self, val):
236239
self._write_u8(_MCP23017_IOCON, val)
240+
241+
@property
242+
def int_flag(self):
243+
"""Returns a list with the pin numbers that caused an interrupt
244+
port A ----> pins 0-7
245+
port B ----> pins 8-15
246+
"""
247+
intf = self._read_u16le(_MCP23017_INTFA)
248+
flags = [pin for pin in range(16) if intf & (1 << pin)]
249+
return flags
250+
251+
@property
252+
def int_flaga(self):
253+
"""Returns a list of pin numbers that caused an interrupt in port A
254+
pins: 0-7
255+
"""
256+
intfa = self._read_u8(_MCP23017_INTFA)
257+
flags = [pin for pin in range(8) if intfa & (1 << pin)]
258+
return flags
259+
260+
@property
261+
def int_flagb(self):
262+
"""Returns a list of pin numbers that caused an interrupt in port B
263+
pins: 8-15
264+
"""
265+
intfb = self._read_u8(_MCP23017_INTFB)
266+
flags = [pin+8 for pin in range(8) if intfb & (1 << pin)]
267+
return flags
268+
269+
def clear_ints(self):
270+
"""Clears interrupts by reading INTCAP."""
271+
self._read_u16le(_MCP23017_INTCAPA)
272+
273+
def clear_inta(self):
274+
"""Clears port A interrupts."""
275+
self._read_u8(_MCP23017_INTCAPA)
276+
277+
def clear_intb(self):
278+
"""Clears port B interrupts."""
279+
self._read_u8(_MCP23017_INTCAPB)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from time import sleep
2+
3+
import board
4+
import busio
5+
from digitalio import Direction, Pull
6+
from RPi import GPIO
7+
from adafruit_mcp230xx.mcp23017 import MCP23017
8+
9+
# Initialize the I2C bus:
10+
i2c = busio.I2C(board.SCL, board.SDA)
11+
12+
# Initialize the MCP23017 chip on the bonnet
13+
mcp = MCP23017(i2c)
14+
15+
# Optionally change the address of the device if you set any of the A0, A1, A2
16+
# pins. Specify the new address with a keyword parameter:
17+
#mcp = MCP23017(i2c, address=0x21) # MCP23017 w/ A0 set
18+
19+
# Make a list of all the pins (a.k.a 0-16)
20+
pins = []
21+
for pin in range(0, 16):
22+
pins.append(mcp.get_pin(pin))
23+
24+
# Set all the pins to input
25+
for pin in pins:
26+
pin.direction = Direction.INPUT
27+
pin.pull = Pull.UP
28+
29+
# Set up to check all the port B pins (pins 8-15) w/interrupts!
30+
mcp.interrupt_enable = 0xFFFF # Enable Interrupts in all pins
31+
# If intcon is set to 0's we will get interrupts on
32+
# both button presses and button releases
33+
mcp.interrupt_configuration = 0x0000 # interrupt on any change
34+
mcp.io_control = 0x44 # Interrupt as open drain and mirrored
35+
mcp.clear_ints() # Interrupts need to be cleared initially
36+
37+
# Or, we can ask to be notified CONTINUOUSLY if a pin goes LOW (button press)
38+
# we won't get an IRQ pulse when the pin is HIGH!
39+
#mcp.interrupt_configuration = 0xFFFF # notify pin value
40+
#mcp.default_value = 0xFFFF # default value is 'high' so notify whenever 'low'
41+
42+
def print_interrupt(port):
43+
'''Callback function to be called when an Interrupt occurs.'''
44+
for pin_flag in mcp.int_flag:
45+
print("Interrupt connected to Pin: {}".format(port))
46+
print("Pin number: {} changed to: {}".format(pin_flag, pins[pin_flag].value))
47+
mcp.clear_ints()
48+
49+
# connect either interrupt pin to the Raspberry pi's pin 17.
50+
# They were previously configured as mirrored.
51+
GPIO.setmode(GPIO.BCM)
52+
interrupt = 17
53+
GPIO.setup(interrupt, GPIO.IN, GPIO.PUD_UP) # Set up Pi's pin as input, pull up
54+
55+
# The add_event_detect fuction will call our print_interrupt callback function
56+
# every time an interrupt gets triggered.
57+
GPIO.add_event_detect(interrupt, GPIO.FALLING, callback=print_interrupt, bouncetime=10)
58+
59+
# The following lines are so the program runs for at least 60 seconds,
60+
# during that time it will detect any pin interrupt and print out the pin number
61+
# that changed state and its current state.
62+
# The program can be terminated using Ctrl+C. It doesn't matter how it
63+
# terminates it will always run GPIO.cleanup().
64+
try:
65+
print("When button is pressed you'll see a message")
66+
sleep(60) # You could run your main while loop here.
67+
print("Time's up. Finished!")
68+
finally:
69+
GPIO.cleanup()

0 commit comments

Comments
 (0)