Source: https://mokxi.com/libraries/adafruit-mcp23017
Updated: 2026-11-02

Libraries / Input
Arduino library · Input

# Adafruit MCP23017: sixteen extra pins on two I2C wires

The MCP23017 is Microchip’s 16-bit I/O expander: two eight-pin ports, GPA and GPB, controlled over I2C. Each pin can be an input, with an optional internal pull-up, or an output that sources or sinks up to 25 mA, so a board with two spare pins can run a keypad, a row of LEDs and a set of switches.

Open the example in the editor See the calls

Built in on Mokxi: #include <Adafruit_MCP23X17.h> and it builds, with nothing to install. Free, and no account needed.

## What Adafruit MCP23017 Arduino Library does

Adafruit’s library makes the pins feel like the board’s own: mcp.pinMode(), mcp.digitalWrite() and mcp.digitalRead() with pin numbers 0 to 15, where 0 to 7 are GPA0 to GPA7 and 8 to 15 are GPB0 to GPB7. Each call is a read-modify-write over I2C, so for speed write a whole port at once with writeGPIOA() or writeGPIOAB().

The chip’s own pins are what trip people up. RESET must be tied high, and A0, A1 and A2 must be tied to GND or 3.3 to 5 V, never left floating; together they set the address, 0x20 to 0x27. Version 2 of the library renamed the class to Adafruit_MCP23X17 and begin() to begin_I2C(), so old tutorials no longer compile as written.

Library Manager name | Adafruit MCP23017 Arduino Library

Author | Adafruit

Include | #include <Adafruit_MCP23X17.h>
#include <Adafruit_MCP23X08.h>

Boards | every board Mokxi compiles for but ATtiny85

In the simulator | Simulated: it runs against the part the way it does on the bench.

Parts it drives | I/O expander, MCP23017

## Install it

It builds on every board Mokxi compiles for but ATtiny85.

In Mokxi it is built in: #include <Adafruit_MCP23X17.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "Adafruit MCP23017 Arduino Library" by Adafruit from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add Adafruit MCP23017 Arduino Library to lib_deps in PlatformIO. Mokxi follows the calls of release 2.3.2, so a sketch written here builds there too.

What to know in the simulator: Mokxi has the MCP23017 part only: Adafruit_MCP23X08 builds, with no chip to drive (run its sketches with Adafruit_MCP23X17, pins 0 to 7), and the SPI chips (begin_SPI) say they are not simulated.

ESP32-C3 · Arduino Uno · Arduino Nano · Arduino Mega 2560 · Arduino Leonardo · SparkFun Pro Micro · Arduino Micro · ESP32-C6 · Raspberry Pi Pico · Raspberry Pi Pico W · Seeed XIAO SAMD21 · STM32 · STM32 Nucleo-F411RE · STM32 Blue Pill · micro:bit V2 · Arduino Uno R4 · ESP32 DevKit · ESP32-S3-DevKitC-1 · ESP8266 NodeMCU · Arduino Pro Mini 3.3 V · Seeed XIAO ESP32-C3 · ESP32-C3 SuperMini · Seeed XIAO ESP32-C6 · ESP32-DevKitC V4 · LOLIN32 Lite · Wemos D1 R32 · Cheap Yellow Display · TTGO T-Display · Seeed XIAO ESP32-S3 · Arduino Nano ESP32 · Arduino Nano RP2040 Connect · Seeed XIAO RP2040 · Waveshare RP2040-Zero · Arduino Uno R4 WiFi

## The calls you will use

In the order a sketch meets them.

### Adafruit_MCP23X17 mcp

The expander object. Adafruit_MCP23X08 is the eight-pin MCP23008.

### mcp.begin_I2C()

Finds the chip at 0x20, or at the address you pass, such as begin_I2C(0x21). Returns false when nothing answers.

### mcp.pinMode(8, INPUT_PULLUP)

Makes GPB0 an input with the internal 100 kΩ pull-up. OUTPUT and INPUT work as on the board.

### mcp.digitalWrite(0, HIGH)

Drives GPA0 high.

### mcp.digitalRead(8)

Reads GPB0, HIGH or LOW. With INPUT_PULLUP a pressed button to GND reads LOW.

### mcp.writeGPIOA(0b10101010)

Sets all eight GPA outputs in one I2C transfer. readGPIOAB() reads all sixteen pins at once.

### mcp.setupInterrupts(true, false, LOW)

Configures the INTA and INTB outputs: mirrored, push-pull, active low. Then setupInterruptPin(pin, CHANGE) arms a pin.

### mcp.getLastInterruptPin()

Which pin caused the interrupt. clearInterrupts() releases the INT line for the next one.

## Example: More pins

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino · Arduino Uno R3

Open it in the editor, wired and ready to run · More pins: the project page

## Common errors and how to fix them

### begin_I2C() returns false

Tie RESET high and A0 to A2 to GND (address 0x20) or to VCC, never floating. Then run an I2C scanner to confirm the address, and check SDA and SCL have pull-up resistors.

### 'class Adafruit_MCP23017' has no member named 'begin_I2C'

The sketch mixes the old and new libraries. Library version 2 and later use #include <Adafruit_MCP23X17.h>, the Adafruit_MCP23X17 class and begin_I2C(); the old begin(0) took 0 to 7 instead of the full address.

### An input pin reads random values

The pin is floating. Use INPUT_PULLUP and wire the button to GND, or add an external resistor, so the pin has a defined level when nothing drives it.

## Keep going

### Learn

- Arduino PCF8574 and MCP23017 I/O Expanders
- I2C Explained: Addresses, Acknowledges and Pull-Ups
- I2C Scanner for Arduino and ESP32, and Fixes

### Parts

- I/O expander, MCP23017

### More input libraries

- XPT2046_Touchscreen
- Keypad
- OneButton
- Encoder
- RotaryEncoder
- CapacitiveSensor
- IRremote
- PCF8574 (Rob Tillaart) and PCF8574 library (Renzo Mischianti)

Every built-in library · Open the editor

## Try Adafruit MCP23017 Arduino Library without installing anything

Open the example, change the sketch, and keep your version in a free account.

Start building free

Open the editor
