Part

I/O expander, MCP23017

Sixteen more pins, two ports of registers, and interrupts. Tie RESET and the address pins or it is not there.

See every part
  • 28 pins
  • In 1 project
  • In 1 lesson
Drawn live by the editor's own code, at the size you see it.
At a glance

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
Pins

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
Pin
What it does
GPB0
GPB1
GPB2
GPB3
GPB4
GPB5
GPB6
GPB7
VDD
Supply, 1.8 to 5.5 V, and ground.
VSS
Ground.
NC1
Not connected.
SCL
I2C.
SDA
I2C.
NC2
Not connected.
A0
The low three bits of the address, 0x20 to 0x27.
A1
The low three bits of the address, 0x20 to 0x27.
A2
The low three bits of the address, 0x20 to 0x27.
RESET
Active low.
INTB
Interrupt outputs for port A and port B.
INTA
Interrupt outputs for port A and port B.
GPA0
GPA1
GPA2
GPA3
GPA4
GPA5
GPA6
GPA7
How to use it

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.

Part pin
Board pin
VDD
5 V
VSS
GND
SDA
A4
SCL
A5
RESET
5 V
A0, A1, A2
5 V each: address 0x27
GPB0
Pushbutton to GND

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.

Arduino Uno: a PCF8574 and an MCP23017 on one buslive0.000 s 0.00x
Hold the button
This is the simulator itself, running here. Click anything to open it in the editor.
A button in and an output out, from the More pins sketch
#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 errors

Common I/O expander, MCP23017 errors and fixes

What goes wrong
The fix
The chip does not answer at any address.
RESET or an address pin is floating. RESET has no internal pull-up and must go to VDD; A0, A1 and A2 must each go to VDD or VSS.
Code from an old tutorial calls mcp.begin(0) and fails.
The current Adafruit library takes the full address: begin_I2C(0x20) for all address pins low, up to 0x27 for all high.
After setting IOCON, later writes land in the wrong registers.
Setting the BANK bit moves port B’s registers at once. Leave BANK at 0 unless you have rewritten every address for the other layout.
An input reads random values.
Pins power up as inputs with no pull-up. Turn the pull-up on with INPUT_PULLUP, or add your own resistor.
Questions

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.

How it is modeled

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.

Projects

See the I/O expander, MCP23017 in a project

One built-in project uses it. It opens in the editor, already wired.

Lessons

Where it turns up in a lesson

One lesson places it in its own circuit.

Boards

The boards it is shown on

This board has a built-in project with the I/O expander, MCP23017 in it.

Libraries

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.

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.