Is MCP23017 16-Bit I2C GPIO Expander Compatible with Home Assistant (ESPHome)?
Electrical Specifications
Always confirm pin assignments against the manufacturer datasheet before wiring.
Compatibility Overview
16-bit I2C parallel port expander with configurable interrupt output pins for adding buttons and relays to microcontrollers.
Wiring MCP23017 16-Bit I2C GPIO Expander to ESP32
| Module pin | ESP32 | Note |
|---|---|---|
| VDD | 3V3 | It runs at 5V too, but then the I2C pull-ups on the module lift SDA and SCL to 5V, which the ESP32 is not rated for. |
| VSS | GND | |
| SDA | GPIO21 | |
| SCL | GPIO22 | |
| RESET | 3V3 | Must be tied high on a bare DIP; modules usually do it for you. Held low, the chip stays in reset and the bus scan finds nothing. |
| A0, A1, A2 | GND | All three low is 0x20. Tie them — floating address pins wander. |
| INTA / INTB | unconnected | ESPHome polls the expander; the interrupt outputs are unused. |
Host pins are the ones the configuration on this page uses. Move a pin here and change it in the YAML — they are documented together so they cannot disagree.
Technical Specification Matrix
| Feature / Attribute | Specification / Status |
|---|---|
| Hardware Protocol | I2C Bus / 3.3V |
| Bridge Required | NO |
| Border Router Needed | None |
| Hardware Capabilities & Peripherals | 16x Expanded Digital GPIOs Interrupt Output Pins Note: these entities come from the ESPHome configuration you flash — each one needs its matching component in that YAML before it appears. |
| Pairing Complexity | Plug-and-Play |
| Factory Reset Instruction | Hold BOOT button for 3s. |
Wire, Flash, Adopt, Check
Wire it up
Follow the wiring table above. The ESP32 pins there are the ones the configuration uses, so if you move one, change it in both places.
Flash the configuration
Create a new device in the ESPHome dashboard (the Home Assistant add-on) and paste the configuration below into it, or save it as emb_esp32_mcp23017_esphome.yaml and run esphome run emb_esp32_mcp23017_esphome.yaml. The first flash goes over USB. If it is not detected, hold BOOT button for 3s to put it in download mode. Every update after that is over the air.
Adopt it in Home Assistant
Settings → Devices & Services. A node on the same network shows up as a discovered ESPHome device within a minute of joining Wi-Fi; choose Configure and enter the API encryption key from your secrets.yaml. If discovery does not find it, add the ESPHome integration by hand with the node's IP address.
Check it works
The I2C scan at boot lists 0x20 (or whatever the address pins are set to), and shorting pin 0 to ground flips Expander Input 0 on in Home Assistant. A scan that lists nothing is the RESET pin or the address straps.
ESPHome Configuration
Starting configuration for MCP23017 16-Bit I2C GPIO Expander on ESP32. Untested on hardware — verify wiring and pins against your own board.
# ESPHome configuration for MCP23017 16-Bit I2C GPIO Expander
# Host: ESP32. Pin numbers below are host-side defaults — any free
# GPIO will do, and you should change them to match your own wiring.
esphome:
name: emb_esp32_mcp23017_esphome
friendly_name: "MCP23017 16-Bit I2C GPIO Expander"
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
i2c:
id: i2c_main
sda: GPIO21
scl: GPIO22
scan: true
# A0-A2 strapping selects 0x20-0x27; 0x20 is all three tied low.
mcp23017:
- id: 'mcp_hub'
address: 0x20
binary_sensor:
- platform: gpio
name: "Expander Input 0"
pin:
mcp23xxx: mcp_hub
number: 0
mode:
input: true
pullup: true
inverted: true
Before you flash:
the !secret values come from your
secrets.yaml, and the GPIO numbers are host-side
defaults rather than properties of this part — change them to match how you actually wired it.
If the device is not found:
it is usually the I2C address, not the config. Many breakouts strap their address with
solder jumpers, so two boards of the same part can differ. This config leaves
scan: true on — the boot log lists every address
actually present on the bus, and you can copy the right one from there.
What Appears in Home Assistant
The one pin the config declares. Every further pin is another binary_sensor, switch or output block using the mcp23xxx: pin schema; nothing appears until you declare it.
Known Problems and Fixes
Polled, not interrupt-driven
ESPHome reads all sixteen pins on every pass of the main loop. That is fine for buttons, reed switches and relays and wrong for anything fast: a rotary encoder or a pulse counter on an expander pin misses edges. Keep those on host GPIOs.
Numbering
Pins 0–7 are GPA0–GPA7, 8–15 are GPB0–GPB7. The silkscreen uses the letter form; the config uses the number.
The pull-ups are weak
The internal pull-ups are about 100kΩ. A button on a metre of cable picks up enough noise to trigger. Add a 10kΩ external pull-up per input on anything that leaves the enclosure, and keep inverted: true with pullup: true as the config shows.
Output current
25mA per pin: enough for an LED or the opto-isolated input of a relay module, not enough for a relay coil directly.
Eight of them
A0–A2 give 0x20 through 0x27, so eight expanders — 128 pins — fit on one bus, each as its own mcp23017: entry with a different id and address.
Shares I²C address 0x20
These parts default to the same address. At least one can be re-strapped, so they can coexist once you change it:
- PCF8574 8-bit I2C GPIO Expander — resolvable
A0-A2 strapping selects 0x20-0x27. Check a full build in the planner
Report a Pinout Error or Submit Tested Code Snippets
Found a pin mapping quirk or built a custom ESPHome YAML driver for MCP23017 16-Bit I2C GPIO Expander? Submit a pull request or report corrections to our index.
Hardware Correction Reporter (emb-esp32-mcp23017-esphome)
Frequently Asked Questions
Does MCP23017 16-Bit I2C GPIO Expander work without an internet connection?
How is MCP23017 16-Bit I2C GPIO Expander powered and wired to the host board?
How does the host board reach Home Assistant (ESPHome)?
Alternatives
PCF8574 8-bit I2C GPIO Expander
Eight pins instead of sixteen, cheaper, quasi-bidirectional: fine for buttons and relay modules, weaker as a driver.
4-Channel 5V Relay Shield Module
If the goal is four relays, a relay board on four host GPIOs needs no expander at all.