class electronics.devices.mcp23017.MCP23017I2C(bus, address=32)

Interface for the Microchip MCP23017/MCP23S17 16-Bit I/O Expander with Serial Interface

>>> expander = MCP23017I2C(gw)
>>> # Set up a few ports
>>> expander.direction_A6 = MCP23017I2C.DIRECTION_OUTPUT
>>> expander.direction_A7 = MCP23017I2C.DIRECTION_OUTPUT
>>> expander.direction_B0 = MCP23017I2C.DIRECTION_OUTPUT
>>> # Send the new pin config to the expander chip
>>> expander.sync()
>>> # Set pin A7 high
>>> expander.write('A7', True)

Instead of manually setting pins to states on the expander you can also get a reference to the pins that you can pass to other devices. For example: driving a HD44780 lcd.

>>> expander = MCP23017I2C(gw)
>>> # Set all A pins to output mode
>>> expander.IODIRA = 0xff
>>> expander.sync()
>>> # Get references for all pins
>>> pins = expander.get_pins()
>>> # Give them names, not required
>>> datalines = pins[0:4]
>>> rs = pins[5]
>>> enable = pins[6]
>>> rw = pins[7]
>>> # Pass them to the hypothetical HD44780 module
>>> lcd = HD44780(gw, datapins=datalines, enable=enable, rs=rs, rw=rw) 
>>> lcd.write("Hello pyElectronics") 

Most operations on this module modify the copy of the registers in the class instance. If you modify one of the register attributes or use the helper attributes (like direction_A0) then you need to call sync() to send the modified registers to the chip.

This class exposes 4 helper attributes for every pin. For pin A0 this is:

  • mcp23017.direction_A0
  • mcp23017.polarity_A0
  • mcp23017.pullup_A0
  • mcp23017.value_A0

You can set the direction_x register to one of the mcp23017.DIRECTION_* constants to set the pin to input or output mode. The polarity_x registers inverses the polarity for the pin. The pullup_x attribute can be used to enable the internal pull-up resister for the pin on the chip. Use the value_x attribute to set the value for the pin.

After you changed the state of the chip with these attributes you need to call the sync() method to actually modify the registers on the device


Get a reference to a named pin on the chip.

>>> expander = MCP23017I2C(gw)
>>> expander.get_pin('B3')
<GPIOPin B3 on MCP23017I2C>
Parameters:name – Name of the pin (Ex: B3)
Returns:GPIOPin instance for the pin

Get a list containing references to all 16 pins of the chip.

>>> expander = MCP23017I2C(gw)
>>> pins = expander.get_pins()
>>> pprint.pprint(pins)
[<GPIOPin A0 on MCP23017I2C>,
 <GPIOPin A1 on MCP23017I2C>,
 <GPIOPin A2 on MCP23017I2C>,
 <GPIOPin A3 on MCP23017I2C>,
 <GPIOPin A4 on MCP23017I2C>,
 <GPIOPin A5 on MCP23017I2C>,
 <GPIOPin A6 on MCP23017I2C>,
 <GPIOPin B0 on MCP23017I2C>,
 <GPIOPin B1 on MCP23017I2C>,
 <GPIOPin B2 on MCP23017I2C>,
 <GPIOPin B3 on MCP23017I2C>,
 <GPIOPin B4 on MCP23017I2C>,
 <GPIOPin B5 on MCP23017I2C>,
 <GPIOPin B6 on MCP23017I2C>]

Read the pin state of an input pin. Make sure you put the pin in input modus with the IODIR* register or direction_* attribute first.

>>> expander = MCP23017I2C(gw)
>>> # Read the logic level on pin B3
>>> # Read the logic level on pin A1
Parameters:pin – The label for the pin to read. (Ex. A0)
Returns:Boolean representing the input level

Read the pin state of a whole port (8 pins)

>>> expander = MCP23017I2C(gw)
>>> # Read pin A0-A7 as a int (A0 and A1 are high)
>>> expander.read_port('A')
>>> # Read pin B0-B7 as a int (B2 is high)
>>> expander.read_port('B')
Parameters:port – use ‘A’ to read port A and ‘B’ for port b
Returns:An int where every bit represents the input level.

Upload the changed registers to the chip

This will check which register have been changed since the last sync and send them to the chip. You need to call this method if you modify one of the register attributes (mcp23017.IODIRA for example) or if you use one of the helper attributes (mcp23017.direction_A0 for example)

write(pin, value)

Set the pin state. Make sure you put the pin in output mode first.

  • pin – The label for the pin to write to. (Ex. A0)
  • value – Boolean representing the new state
write_port(port, value)

Use a whole port as a bus and write a byte to it.

  • port – Name of the port (‘A’ or ‘B’)
  • value – Value to write (0-255)