Description
The MCP23017 module provides a 16-bit general purpose bidirectional I/O port using the I2C bus.
PACKAGE INCLUDES:
- MCP23017 16-bit I/O Expander module with I2C bus
KEY FEATURES OF MCP23017 MODULE:
- 16 bidirectional I/O lines
- I2C bus operates up to 1.7MHz
- 3 address lines for up to 8 devices on same I2C bus
- 2 configurable interrupt outputs
- 25mA per pin / 150mA per package current capability
- 3.3 or 5V operation
It’s not unusual to run out of I/O pins on a microcontroller and the MCP23017 is a popular way to increase the number of GPIO available and has good library support.
This module brings all of the pins of the MCP23017 chip out to header pins. It also includes 10K pull-up resistors on the I2C SDA and SCK lines, 10K pull-up resistor on the RESET line and 10K pull-down resistors on the address lines..
I2C Bus
Since it interfaces using the I2C bus, the MCP23017 module uses only 2 pins on the MCU and up to 8 modules can be operated off the same I2C bus for a total of up to 128 I/O lines. The I2C SDA and SCK lines have built-in pull-up 10K resistors.
Three address pins (A0-A2) are used for setting the I2C address of the chip. The module has all three pins pulled to ground through 10K resistors giving the base address of 0x20 and can go up to 0x27 if they are all tied to Vcc. If more than one module is used on an I2C bus, each must be set to a unique address.
The I2C bus can operate at up to 1.7MHz for fast manipulation of the I/O lines for higher speed applications. Note that to achieve 1.7MHz operation, Vcc needs to be 5V. When operating at 3.3V the maximum speed is limited to 400kHz which can still handle most I/O requirements.
I/O Ports
The 16 GPIO lines are configured as two 8-bit ports (PORTA and PORTB). Each pin can also be individually defined as an input or output for complete flexibility.
When pins are configured as inputs, an internal 100K pullup resistor can be enabled which is handy for inputs such as switches that require a pullup to Vcc when the switch is open and pull to ground when pressed. This removes the need to add external pullup resistors in some applications.
Another nice feature is that the input pins can be selectively inverted. For instance, a button press that would normally return a logic LOW can be inverted so it returns a HIGH.
Each GPIO pin can handle up to 25mA, but the total current for all pins must be kept under 150mA. If driving something like 16 LEDs, each LED current needs to be kept down around 9mA if they may all be on at the same time to avoid overheating the chip.
Interrupts
Interrupt capability is a nice feature since the MCU does not have to continuously poll the device looking for any change on the inputs.
Each of the two ports has a configurable interrupt output that can be used independently or the two interrupts can work together. Input pins can be set to interrupt the MCU upon a state change.
Another nice feature is that the interrupt outputs can be configurated as active LOW, active HIGH or OPEN-DRAIN.
Reset
The reset pin is active LOW and is pulled up to Vcc using a 10K resistor on the module. It can be be put under MCU control by connecting it to a digital output pin on the MCU. The pin is normally HIGH and momentarily driven LOW to reset the MCP23017.
Assembling The Module
The module ships with 3 strips of male headers for maximum flexibility. The headers can be mounted to the top or bottom of the board or a combination of both.
Since the module has the pins labeled on the bottom side, for solderless breadboard use it is easiest to use the board upside down so the labeling is facing up and visible when making connections.
The way we like to use the module is to solder the single row of header pins used for the MCU control signals to the top (IC side of the board) so that it can be inserted into a breadboard to hold it in position and make male jumper connections to the MCU. The two headers for the I/O ports can be soldered to the bottom of the board (which is now the top) and connections made using female to male jumpers.
Another option is to put one of the two I/O headers also on the IC side so it can be plugged into the breadboard which makes it very stable. One port can be accessed with male jumpers and one with female jumpers. We haven’t soldered the pins in the mockup, but they would need to be soldered before it is used.
The final option is to put all the headers on the same side of the board as shown below and use female jumpers for connections. Just remember that you cannot flip it over and plug the double headers into a solderless breadboard or the two I/O ports will be shorted together. For a permanent perf board installation, these headers could all be mounted on the other side of the board.
Our Evaluation Results:
These parts are very easy to use and have good library support on most MCU platforms.
The simple example shown here sets up one pin (A0) as an input to detect a button press. A second pin (A1) is setup as an output to light an LED while the button is being pressed.
Hookup of the module is straight forward.
- Vcc – Connect to 3.3V or 5V to match the MCU
- GND – Connect to ground
- SCL – Connect to I2C SCL on MCU
- SDA – Connect to I2C SDA on MCU
- A0- Connect one side of pushbutton, other side goes to ground
- A1 – Connect to LED cathode. Anode of the LED connects to Vcc through 220 to 470 ohm current limit resistor
The schematic to the right shows the basic setup as viewed from the chip perspective.
To use the program you will need to download the Adafruit MCP23017.h library using the Arduino IDE Library Manager. There are several other libraries also available.
Once the program is downloaded and running, pressing the pushbutton should cause the LED to light as long as the button is depressed.
An interesting exercise left up to the user is to modify this setup to use interrupts to notify the MCU that the button state has changed rather than constantly polling the MCP23017 to see what the current state is.
MCP23017 16-Bit I/O Expander Example Program
/* * MCP23017 Test Program * * Set one pin as input and detect a button push * Set one pin as output and turn on LED when button is pushed * * Vdd = 3.3V or 5V to match your microcontroller (Vcc) * * Connect pin #9 (Vdd) of the expander to Vcc (IC power) * Connect pin #10 (Vss) of the expander to ground (IC ground) * Connect pin #12 (SCK) of the expander to I2C Clock * Connect pin #13 (SDA) of the expander to I2C Data * Connect pins #15, 16, 17 (A0-2) of the expander to ground * Connect pin #18 (RESET) through a ~10kohm resistor to Vcc * Connect pin #21 (GPA0) to pushbutton, other side to ground * Connect pin #22 (GPA1) to LED cathode, other side to Vcc through 470ohm resistor */ #include <Wire.h> #include "Adafruit_MCP23017.h" Adafruit_MCP23017 mcp; // Uses default I2C address of 0x20 //=============================================================================== // Initialization //=============================================================================== void setup() { mcp.begin(); // use default address 0 mcp.pinMode(0, INPUT); // Switch input mcp.pullUp(0, HIGH); // turn on internal 100K pullup for switch mcp.pinMode(1, OUTPUT); // LED output } //=============================================================================== // Main //=============================================================================== void loop() { int buttonState = 0; buttonState = mcp.digitalRead(0); if (buttonState == 0) // Button is pressed mcp.digitalWrite(1, LOW); // Turn on LED else mcp.digitalWrite(1,HIGH); // Turn off LED delay(100); }
Notes:
- None
Technical Specifications
Operational Ratings | ||
Vcc | 1.8- 5.5V | |
Max I2C Clock Speed | Vcc = 3.3V | 400kHz |
Vcc = 5V | 1.7MHz | |
Output Current | Per I/O Pin | 25mA |
Total package output current | 150mA | |
Dimensions | Board L x W | 26 x 24mm (1 x 0.95″) |
Country of Origin | China | |
Datasheet | Microchip | MCP23017/MCP23S17 |