I2C and MCP23017, part 2

I2C and MCP23017, part 2

After being able to set basic outputs and inputs in the previous post, the next step could be to be understand the inputs, internal pull ups and the triggers INTA and INTB.

Let’s start with internal pull ups. The MCP23017 has the ability to software define internal pull ups. This means that you do not have to build these outside the chip. The registers GPPUA (0x0C) and GPPUB (0x0D) are used to set or remove this internal pull up. As with the other registers, 8 bits can be set. 0 means do not use internal pull up while a 1 means use an internal pullup. For the remainder of this article, we will assume a range of buttons or other inputs on bank A.

Let’s tell the MCP23017 that all of bank A needs to have the internal pull up set:
(again pseudo code. The code will be different for the Raspberry Pi and the NodeMCU)


Now our inputs only need to connect to ground or float to send a signal. Next let’s tell the chip that we want any change on an input in bank A to send a signal to INTA. We do this by setting the individual bits on GPINTENA (0x04) high. (The corresponding GPINTENB can be found on 0x05).


All set, now if a change happens on any port on bank A, INTA is triggered. On your device (Raspberry PI or NodeMCU) you can define a trigger to react on this.

VERY IMPORTANT!! After each trigger on INTA (or INTB) you will NOT receive another trigger until you clear this one. You do this by either reading from GPIOA (or GPIOB) or by reading INTCAPA (0x10) (or INTCAPB at 0x11). Since you don’t know whether or trigger has happened during the initial boot up of your program, I suggest doing a read of GPIOA and/or GPIOB after you define your trigger to make sure the trigger is cleared.

The values you read from INTCAPA (or INTCAPB) show (in bit order) which ports set off the trigger.

If you are short on input ports on your device, it is possible to OR both INT ports such that you only have one trigger to alert you that there is a change on EITHER bank A or B. To do this, you set bit 6 (0x40) of either IOCONA (0x0A) or IOCONB (oxoB). To do this, you read the value first and than set or unset bit 6 and write it back.

current_value = read_from_i2c_bus(device_address,IOCONA)
new_value = current_value OR 0x40 (to set the 6th bit, chose one line \/)
new_value = current_value AND 0xBF (to unset the 6th bit, chose one line /\)

Depending on whether you want to set or unset the bit, you chose one of the 2 lines in the example above.

3 thoughts on “I2C and MCP23017, part 2

  1. Hi thanks for this detailed explanation of how to use the MCP23017 chip. I was wonder if I could ask you a couple questions about this. Would greatly appreciate your help 🙂


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s