B4R Library rAdafruitMCP23017_I2C
Brief
rAdafruitMCP23017_I2C is an open-source library for MCP23017 I2C Port Expanders.
This library is partial wrapped (I2C only) and enhanced from the library Adafruit MCP23017 Arduino library.
Development Info
Files
The rAdafruitMCP23017_I2C-NNN.zip archive contains the library and sample projects.
Install
Copy the rAdafruitMCP23017_I2C library folder from the archive into the B4R Additional Libraries folder, keeping the folder structure intact.
Ensure the library Adafruit-MCP23017-Arduino-Library v2.3.2 is installed using the Arduino IDE libraries manager.
Wiring
MCP23017 = Arduino UNO
VCC = 5V (red)
GND = GND (black)
SDA = A4 (blue)
SCL = A5 (yellow)
MCP23017 = ESP-32
VCC = 3V3 (red)
GND = GND (black)
SDA = GPIO21 [D21] (blue)
SCL = GPIO22 [D22] (yellow)
MCP23017 = Button
PA0 (yellow) = Signal
GND = GND (black)
MCP23017 = LED
PB7 = + (yellow) with 330Ohm resistor
GND = GND (black)
I2C
MCP23017 I2C Address = 0x27
Basic Example
Example blinking all MCP23017 pins with one LED (for tests) connected to pin PA0.
Functions
Initialize() As Boolean
Initialize MCP using I2C with default I2C address 0x20.
Returns - true if initialization successful, otherwise false.
Initialize2(addr As Byte) As Boolean
Initialize MCP using I2C with custom I2C address.
Example: 0x27 = MCP23017 module has the address jumpers A0/A1/A2 pulled high.
addr - I2C address.
Returns - true if initialization successful, otherwise false.
SetPinMode(pin As Byte, mode As Byte)
Configures the specified pin to behave either as an input or an output.
pin - the Arduino pin number to set the mode of.
mode - INPUT, OUTPUT, or INPUT_PULLUP.
GetPinMode(pin As Byte) As Byte
Get the specified pin mode.
pin - Arduino pin number to get the mode of.
mode - INPUT, OUTPUT, or INPUT_PULLUP.
DigitalRead(pin As Byte) As Byte
Reads the value from a specified digital pin, either HIGH or LOW.
pin - Arduino pin number you want to read.
Returns - HIGH or LOW
DigitalWrite(pin As Byte, value As Byte)
Write a HIGH or a LOW value to a digital pin.
pin - Arduino pin number
value - HIGH or LOW
ReadGPIO(port As Byte) As Byte
Bulk read all pins on a port.
port - 0 for Port A, 1 for Port B (MCP23X17 only).
Returns - current pin states of port as byte.
WriteGPIO(value As Byte, port As Byte)
Bulk write all pins on a port.
value - pin states to write as a uint8_t.
port - 0 for Port A, 1 for Port B (MCP23X17 only).
SetupInterrupts(mirroring As Boolean, openDrain As Boolean, polarity As Byte)
Configure the interrupt system.
mirroring - true to OR both INTA and INTB pins.
openDrain - true for open drain output, false for active drive output.
polarity - HIGH or LOW
SetupInterruptPin(pin As Byte, mode As Byte)
Enable interrupt and set mode for given pin.
pin - Pin to enable.
mode - CHANGE, LOW, HIGH.
DisableInterruptPin(pin As Byte)
Disable interrupt for given pin.
pin - Pin to disable.
ClearInterrupts
Clear interrupts.
GetLastInterruptPin As Byte
Gets the pin that caused the latest interrupt, from INTF, without clearing any interrupt flags.
Returns - Pin that caused latest interrupt.
GetCapturedInterrupt As UInt
Get pin states captured at time of interrupt.
Returns - Multi-bit value representing pin states.
Custom Functions
AddInputHandler(StateChangedSub As SubVoidPinState)
Add input handler for the input/input_pullup pins
The Input_StateChanged in B4R only sees clean transitions:
Button press > 1 clean LOW event.
Button release > 1 clean HIGH event.
No multiple toggles caused by bouncing contacts.
StateChangedSub - Event name handling the input state change.
AttachInterrupt(intPin As Byte, buttonPin As Byte, StateChangedSub As VoidPinState)
Attach MCP pin interrupt with MCU pin for INTA/B
intPin - Interrupt pin INTA or INTB.
buttonPin - Button pin GPA0-7 or GPB0-GPB7.
StateChangedSub - Event name handling the input state change.[/U]
Constants
MCP23XXX_ADDR As Byte = 0x20 - Default I2C Address.
MODE_OUTPUT As Byte = OUTPUT - Pin Modes Output (LED).
MODE_INPUT As Byte = INPUT Pin Modes Input (Button).
MODE_INPUT_PULLUP As Byte = INPUT_PULLUP - Pin mode input pullup (Pushbutton).
STATE_CHANGE As Byte = CHANGE - Pin state change.
STATE_HIGH As Byte = HIGH - Pin state hight
STATE_LOW As Byte = LOW - Pin state low.
PINS As Byte = 0x10 - Number of PINS 16 (0-15).
Pin codes for PA0 to PB7 - 16 pins.
PIN_PA0 As Byte = 0
PIN_PA1 As Byte = 1
PIN_PA2 As Byte = 2
PIN_PA3 As Byte = 3
PIN_PA4 As Byte = 4
PIN_PA5 As Byte = 5
PIN_PA6 As Byte = 6
PIN_PA7 As Byte = 7
PIN_PB0 As Byte = 8
PIN_PB1 As Byte = 9
PIN_PB2 As Byte = 10
PIN_PB3 As Byte = 11
PIN_PB4 As Byte = 12
PIN_PB5 As Byte = 13
PIN_PB6 As Byte = 14
PIN_PB7 As Byte = 15
Credits
Adafruit Industries for the MCP23017 Arduino library.
Disclaimer
Licenses
Original Library (Adafruit)
Copyright (c) 2012 Adafruit Industries. Licensed under the BSD 3-Clause License (see LICENSE file in the original repository).
License for this wrapper
Copyright © 2025 Robert W.B. Linn. Licensed unter the MIT License (see LICENSE file).
Notes
The Adafruit library remains under the BSD license.
This wrapper code is MIT licensed. When distributing, both licenses apply.
Brief
rAdafruitMCP23017_I2C is an open-source library for MCP23017 I2C Port Expanders.
This library is partial wrapped (I2C only) and enhanced from the library Adafruit MCP23017 Arduino library.
Development Info
- Written in C++ (Arduino IDE 2.3.4 and the B4Rh2xml tool).
- Depends on the library Adafruit MCP23017 Arduino Library.
- Tested with
- Hardware - Arduino UNO, ESP-32, SEENGREAT MCP23017 IO Expander Module I2C, ELEGOO 5 mm LED, Keyes Pushbutton.
- Software - B4R 4.00 (64-bit), Adafruit-MCP23017-Arduino-Library v2.3.2, ESP-32 Board Manager 3.3.0.
Files
The rAdafruitMCP23017_I2C-NNN.zip archive contains the library and sample projects.
Install
Copy the rAdafruitMCP23017_I2C library folder from the archive into the B4R Additional Libraries folder, keeping the folder structure intact.
Ensure the library Adafruit-MCP23017-Arduino-Library v2.3.2 is installed using the Arduino IDE libraries manager.
Wiring
MCP23017 = Arduino UNO
VCC = 5V (red)
GND = GND (black)
SDA = A4 (blue)
SCL = A5 (yellow)
MCP23017 = ESP-32
VCC = 3V3 (red)
GND = GND (black)
SDA = GPIO21 [D21] (blue)
SCL = GPIO22 [D22] (yellow)
MCP23017 = Button
PA0 (yellow) = Signal
GND = GND (black)
MCP23017 = LED
PB7 = + (yellow) with 330Ohm resistor
GND = GND (black)
I2C
MCP23017 I2C Address = 0x27
Basic Example
Example blinking all MCP23017 pins with one LED (for tests) connected to pin PA0.
B4X:
Sub Process_Globals
Public Serial1 As Serial
Public mcp As AdafruitMCP23017_I2C
Private MCP_ADDRESS_I2C As Byte = 0x27
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
If Not(mcp.Initialize2(MCP_ADDRESS_I2C)) Then
Log("[Main.AppStart][ERROR] Initialize expander.")
Return
Else
Log("[Main.AppStart] Initialize expander: OK, address=0x", mcp.ByteToHex(MCP_ADDRESS_I2C))
End If
' Set all pins to mode output
Dim i As Byte
For i = 0 To mcp.pins - 1
mcp.SetPinMode(i, mcp.MODE_OUTPUT)
Next
CallSubPlus("TestBlink", 1, 5)
End Sub
Private Sub TestBlink(Tag As Byte) 'ignore
Dim i As Byte
For i = 0 To mcp.PINS - 1
mcp.digitalWrite(i, mcp.STATE_HIGH)
Next
Delay(1000)
For i = 0 To mcp.PINS - 1
mcp.digitalWrite(i, mcp.STATE_LOW)
Next
Delay(1000)
End Sub
Functions
Initialize() As Boolean
Initialize MCP using I2C with default I2C address 0x20.
Returns - true if initialization successful, otherwise false.
Initialize2(addr As Byte) As Boolean
Initialize MCP using I2C with custom I2C address.
Example: 0x27 = MCP23017 module has the address jumpers A0/A1/A2 pulled high.
addr - I2C address.
Returns - true if initialization successful, otherwise false.
SetPinMode(pin As Byte, mode As Byte)
Configures the specified pin to behave either as an input or an output.
pin - the Arduino pin number to set the mode of.
mode - INPUT, OUTPUT, or INPUT_PULLUP.
GetPinMode(pin As Byte) As Byte
Get the specified pin mode.
pin - Arduino pin number to get the mode of.
mode - INPUT, OUTPUT, or INPUT_PULLUP.
DigitalRead(pin As Byte) As Byte
Reads the value from a specified digital pin, either HIGH or LOW.
pin - Arduino pin number you want to read.
Returns - HIGH or LOW
DigitalWrite(pin As Byte, value As Byte)
Write a HIGH or a LOW value to a digital pin.
pin - Arduino pin number
value - HIGH or LOW
ReadGPIO(port As Byte) As Byte
Bulk read all pins on a port.
port - 0 for Port A, 1 for Port B (MCP23X17 only).
Returns - current pin states of port as byte.
WriteGPIO(value As Byte, port As Byte)
Bulk write all pins on a port.
value - pin states to write as a uint8_t.
port - 0 for Port A, 1 for Port B (MCP23X17 only).
SetupInterrupts(mirroring As Boolean, openDrain As Boolean, polarity As Byte)
Configure the interrupt system.
mirroring - true to OR both INTA and INTB pins.
openDrain - true for open drain output, false for active drive output.
polarity - HIGH or LOW
SetupInterruptPin(pin As Byte, mode As Byte)
Enable interrupt and set mode for given pin.
pin - Pin to enable.
mode - CHANGE, LOW, HIGH.
DisableInterruptPin(pin As Byte)
Disable interrupt for given pin.
pin - Pin to disable.
ClearInterrupts
Clear interrupts.
GetLastInterruptPin As Byte
Gets the pin that caused the latest interrupt, from INTF, without clearing any interrupt flags.
Returns - Pin that caused latest interrupt.
GetCapturedInterrupt As UInt
Get pin states captured at time of interrupt.
Returns - Multi-bit value representing pin states.
Custom Functions
AddInputHandler(StateChangedSub As SubVoidPinState)
Add input handler for the input/input_pullup pins
The Input_StateChanged in B4R only sees clean transitions:
Button press > 1 clean LOW event.
Button release > 1 clean HIGH event.
No multiple toggles caused by bouncing contacts.
StateChangedSub - Event name handling the input state change.
AttachInterrupt(intPin As Byte, buttonPin As Byte, StateChangedSub As VoidPinState)
Attach MCP pin interrupt with MCU pin for INTA/B
intPin - Interrupt pin INTA or INTB.
buttonPin - Button pin GPA0-7 or GPB0-GPB7.
StateChangedSub - Event name handling the input state change.[/U]
Constants
MCP23XXX_ADDR As Byte = 0x20 - Default I2C Address.
MODE_OUTPUT As Byte = OUTPUT - Pin Modes Output (LED).
MODE_INPUT As Byte = INPUT Pin Modes Input (Button).
MODE_INPUT_PULLUP As Byte = INPUT_PULLUP - Pin mode input pullup (Pushbutton).
STATE_CHANGE As Byte = CHANGE - Pin state change.
STATE_HIGH As Byte = HIGH - Pin state hight
STATE_LOW As Byte = LOW - Pin state low.
PINS As Byte = 0x10 - Number of PINS 16 (0-15).
Pin codes for PA0 to PB7 - 16 pins.
PIN_PA0 As Byte = 0
PIN_PA1 As Byte = 1
PIN_PA2 As Byte = 2
PIN_PA3 As Byte = 3
PIN_PA4 As Byte = 4
PIN_PA5 As Byte = 5
PIN_PA6 As Byte = 6
PIN_PA7 As Byte = 7
PIN_PB0 As Byte = 8
PIN_PB1 As Byte = 9
PIN_PB2 As Byte = 10
PIN_PB3 As Byte = 11
PIN_PB4 As Byte = 12
PIN_PB5 As Byte = 13
PIN_PB6 As Byte = 14
PIN_PB7 As Byte = 15
Credits
Adafruit Industries for the MCP23017 Arduino library.
Disclaimer
- This project is developed for personal use only.
- All examples and code are provided as-is and should be used at your own risk.
- Any guidance provided as-is, without any guarantee or liability for errors, omissions, or misconfiguration.
- Always test thoroughly and exercise caution when connecting hardware components.
Licenses
Original Library (Adafruit)
Copyright (c) 2012 Adafruit Industries. Licensed under the BSD 3-Clause License (see LICENSE file in the original repository).
License for this wrapper
Copyright © 2025 Robert W.B. Linn. Licensed unter the MIT License (see LICENSE file).
Notes
The Adafruit library remains under the BSD license.
This wrapper code is MIT licensed. When distributing, both licenses apply.
Attachments
Last edited: