I/O expander, MCP23017
Sixteen more pins, two ports of registers, and interrupts. Tie RESET and the address pins or it is not there.
- 28 pins
- In 1 project
- In 1 lesson
The I/O expander, MCP23017 in brief
What it is, and where it sits on the bench.
The MCP23017 adds sixteen pins over I2C as two eight-bit ports, A and B, in a 28-pin DIP. Unlike the PCF8574 it has a register for everything: each pin’s direction, an optional 100 kilohm pull-up, inverted reading, push-pull outputs, and interrupts on change with the port captured at that moment. Three address pins choose 0x20 to 0x27, so eight chips give a board 128 extra pins. It is a bare chip with no pull-ups or pull-downs on its control pins, and Mokxi models that faithfully: RESET and A0 to A2 have to be wired, or the part is simply absent from the bus, as a real one would be. The model covers both register layouts selected by IOCON.BANK, the register pointer’s three stepping behaviors, pull-ups, polarity and both interrupt modes with INTF and INTCAP, and the INTA and INTB outputs.
- Family
- Logic
- Pins
- 28
28 pins
Named as the editor names them, so a wire lands where you expect it.
GPB8
- GPB0
- GPB1
- GPB2
- GPB3
- GPB4
- GPB5
- GPB6
- GPB7
NC2
- NC1
- NC2
A3
- A0
- A1
- A2
GPA8
- GPA0
- GPA1
- GPA2
- GPA3
- GPA4
- GPA5
- GPA6
- GPA7
Other7
- VDD
- VSS
- SCL
- SDA
- RESET
- INTB
- INTA
Show all 28 pins
0x20 to 0x27.0x20 to 0x27.0x20 to 0x27.How to use the MCP23017 I/O expander with an Arduino
Power on VDD (5 V) and VSS (GND), and the bus on SDA (A4) and SCL (A5). Then the three pins people forget: RESET to VDD, and each of A0, A1 and A2 to VDD or VSS. In the More pins project all three address pins go to 5 V, which makes the address 0x27. A pushbutton runs from GPB0 to ground.
With Adafruit’s library, begin_I2C(0x27) finds the chip, and the pins are numbered 0 to 15: 0 to 7 are GPA0 to GPA7, and 8 to 15 are GPB0 to GPB7. The project sets pin 8 to INPUT_PULLUP, so GPB0 reads LOW while the button is held, and sets pin 0 as an output that goes HIGH while it is held; wire an LED and resistor from GPA0 to ground to see it. The serial monitor prints "button held" or "button up" every 250 ms.
The chip runs from 1.8 to 5.5 V, so a 3.3 V board can power it directly; tie RESET and the address pins to that same 3.3 V.
#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp;
void setup() {
mcp.begin_I2C(0x27);
mcp.pinMode(0, OUTPUT); // GPA0
mcp.pinMode(8, INPUT_PULLUP); // GPB0
}
void loop() {
bool pressed = mcp.digitalRead(8) == LOW;
mcp.digitalWrite(0, pressed ? HIGH : LOW);
}Common I/O expander, MCP23017 errors and fixes
Questions and answers
How are the MCP23017 pins numbered in the Adafruit library?
Pins 0 to 7 are GPA0 to GPA7 and pins 8 to 15 are GPB0 to GPB7, in the order of the chip’s two ports.
Does the MCP23017 need pull-up resistors on SDA and SCL?
A bare chip has none, so a real bus wants 4.7 k pull-ups. On a short breadboard bus the board’s own weak pull-ups, which Wire turns on, often carry it at 100 kHz.
Can the MCP23017 tell the Arduino when a button is pressed?
Yes. Enable interrupt-on-change for the pin and INTA or INTB goes low; INTF names the pin and INTCAP holds the port as it was at that moment.
Should GPA7 and GPB7 be used as inputs?
Microchip’s current datasheet says to use them as outputs only on real chips. The simulation lets them work as inputs, so keep inputs on the other fourteen pins if the design is going to hardware.
What is true about the I/O expander, MCP23017, here
In its help article’s own words: what the simulation gets right, and where it stops.
Modeled
Both register maps and the pointer's three behaviors. Outputs from OLAT, 100 kΩ
pull-ups from GPPU, and IPOL inverting what GPIO reads. Interrupt-on-change:
compare against the last value (INTCON 0) or against DEFVAL (INTCON 1), INTF
naming the pin, INTCAP catching the port at that moment, and a read of INTCAP or
GPIO clearing it. With DEFVAL, a pin that is still different fires again at once.
INTA and INTB are push-pull active low at power-up; INTPOL, ODR and MIRROR
change that as the datasheet says.
Not modeled
SPI, which is the MCP23S17. Output current limits. The slew-rate control. Microchip's
current datasheet says GPA7 and GPB7 should be outputs only, because a change on
either during a read can corrupt SDA on real silicon; here they work as inputs like
the rest, so a circuit that relies on that works in Mokxi and may not on the bench.
From MCP23017 I/O expander, in full.
See the I/O expander, MCP23017 in a project
One built-in project uses it. It opens in the editor, already wired.
Where it turns up in a lesson
One lesson places it in its own circuit.
The boards it is shown on
This board has a built-in project with the I/O expander, MCP23017 in it.
Arduino libraries for the I/O expander, MCP23017
Built in, so the sketch compiles with nothing to install. Each page has the calls, the wiring and an example to run.
The rest of the bench
Every one of these is drawn and simulated the same way.
Wire up the I/O expander, MCP23017
Open the editor and push it into the breadboard. It is free, and it runs on your own machine.