Adafruit MCP23017 Arduino Library

repository·master·Indexed 18 days ago

https://github.com/adafruit/adafruit-mcp23017-arduino-library

An Arduino-compatible interface for controlling MCP23xxx series I/O expanders via I2C or SPI. The library abstracts register-level operations into familiar functions such as pinMode, digitalRead, and digitalWrite. It provides specific classes for 8-bit variants (Adafruit_MCP23X08) and 16-bit variants (Adafruit_MCP23X17), supporting bulk GPIO access, hardware addressing for MCP23Sxx devices, and interrupt-on-change configuration.

Tokens
2.4K
Snippets
9
Records
14
Agent score
57%

What's inside Adafruit MCP23017 Arduino Library

  1. Understand Pin Addressing for MCP23x08 and MCP23x17

    master

    When performing single pin operations such as pinMode(pinId, dir), digitalRead(pinId), or digitalWrite(pinId, val), you must use the specific pinId assigned to that pin.

    Note: The MCP23008 and MCP23S08 chips only have GPAx pins (IDs 0-7). The MCP23x17 chips include GPBx pins (IDs 8-15).

    Pin NameMCP23x08 Pin #MCP23x17 Pin #Pin ID
    GPA010210
    GPA111221
    GPA212232
    GPA313243
    GPA414254
    GPA515265
    GPA616276
    GPA717287
    GPB0--18
    GPB1--29
    GPB2--310
    GPB3--411
    GPB4--512
    GPB5--613
    GPB6--714
    GPB7--815
  2. Initialize the MCP23XXX via I2C or SPI

    master

    To use an MCP23xxx port expander, you must first initialize the communication interface using one of the begin methods. This library supports both I2C and SPI.

    I2C Initialization

    Use begin_I2C(i2c_addr, wire) to initialize via I2C.

    • i2c_addr: The I2C address of the device (defaults to MCP23XXX_ADDR which is 0x20).
    • wire: A pointer to the TwoWire instance (defaults to &Wire).

    SPI Initialization

    You can initialize via SPI in two ways:

    1. Standard SPI: begin_SPI(cs_pin, theSPI, _hw_addr)
      • cs_pin: The Chip Select pin.
      • theSPI: A pointer to the SPIClass instance (defaults to &SPI).
      • _hw_addr: The hardware address matching the A2/A1/A0 pins (defaults to 0x00).
    2. Custom SPI Pins: begin_SPI(cs_pin, sck_pin, miso_pin, mosi_pin, _hw_addr)
      • Allows specifying custom pins for SCK, MISO, and MOSI.
    // I2C Example
    if (!mcp.begin_I2C(0x20)) {
      Serial.println("Could not find MCP23xxx");
    }
    
    // SPI Example
    if (!mcp.begin_SPI(10)) {
      Serial.println("Could not find MCP23xxx");
    }
  3. Configure SPI hardware addressing for MCP23Sxx

    master

    The library supports hardware pin addressing (A2, A1, A0 for S17 and A1, A0 for S08) for MCP23Sxx devices.

    To use hardware addressing, call begin_SPI(CS, SPI, HW_ADDR). This ensures each SPI message contains the correct chip address.

    Important Requirements:

    1. You must call enableAddrPins() to enable hardware address recognition.
      • Warning: Calling enableAddrPins() will enable the IOCON.HAEN bit for all active (CS low) devices on the SPI bus.
    2. MCP23S17 Silicon Errata: Due to a hardware bug in the MCP23S17 chip, if you are using a device with A2 = high and are not using addressing, you must still initialize the chip with a 0b1XX address (e.g., 0b100).
    // Example: Initialize MCP23S17 with CS pin 10, SPI interface, and HW address 0b101
    mcp.begin_SPI(10, &SPI, 0b101);
  4. Configure and manage interrupts

    master

    The MCP23xxx series supports interrupt-on-change functionality. Use the following methods to manage interrupts:

    • setupInterrupts(bool mirroring, bool openDrain, uint8_t polarity): Configures the interrupt behavior, including whether interrupts are mirrored across ports, if the interrupt pin is open-drain, and the polarity.
    • setupInterruptPin(uint8_t pin, uint8_t mode = CHANGE): Configures a specific pin to trigger an interrupt.
    • disableInterruptPin(uint8_t pin): Disables interrupt triggering on a specific pin.
    • clearInterrupts(): Clears the interrupt flags.
    • getLastInterruptPin(): Returns the pin that triggered the last interrupt.
    • getCapturedInterrupt(): Returns the captured state of the pins when the interrupt occurred.
    mcp.setupInterrupts(true, false, 0);
    mcp.setupInterruptPin(2, CHANGE);
    
    // In your loop or ISR
    if (mcp.getLastInterruptPin() != MCP23XXX_INT_ERR) {
      uint16_t captured = mcp.getCapturedInterrupt();
      mcp.clearInterrupts();
    }
  5. Use Arduino-compatible GPIO methods

    master

    The library provides standard Arduino API methods to control the GPIO pins on the MCP23xxx expander, making it easy to integrate into existing sketches.

    • pinMode(uint8_t pin, uint8_t mode): Configures the specified pin to a mode (e.g., INPUT, OUTPUT, INPUT_PULLUP).
    • digitalRead(uint8_t pin): Reads the state of the specified pin.
    • digitalWrite(uint8_t pin, uint8_t value): Writes a high or low value to the specified pin.
    mcp.pinMode(0, OUTPUT);
    mcp.digitalWrite(0, HIGH);
    
    uint8_t val = mcp.digitalRead(1);
  6. Perform bulk GPIO access

    master

    For efficiency, you can read or write the state of an entire port at once rather than individual pins.

    • readGPIO(uint8_t port = 0): Reads the current state of all pins on the specified port (0 or 1).
    • writeGPIO(uint8_t value, uint8_t port = 0): Writes a bitmask value to all pins on the specified port.
    // Read all pins on port 0
    uint8_t portValue = mcp.readGPIO(0);
    
    // Write 0b10101010 to port 1
    mcp.writeGPIO(0xAA, 1);
  7. Use the Adafruit_MCP23X17 class for I2C and SPI port expanders

    master

    The Adafruit_MCP23X17 class is the primary interface for controlling MCP23017 (I2C) and MCP23S17 (SPI) port expanders. It inherits from Adafruit_MCP23XXX and provides methods to read and write to the GPIO ports (Port A and Port B) as individual 8-bit registers or as a combined 16-bit value.

    Adafruit_MCP23X17 mcp;
    
    // Example usage of port access
    mcp.writeGPIOA(0xFF);
    uint8_t portBValue = mcp.readGPIOB();
    uint16_t allPorts = mcp.readGPIOAB();
  8. Read and write GPIO ports with Adafruit_MCP23X17

    master

    The Adafruit_MCP23X17 class provides the following methods for interacting with the device's pins:

    Port A (8-bit)

    • uint8_t readGPIOA(): Reads the current state of all pins on Port A.
    • void writeGPIOA(uint8_t value): Sets the state of all pins on Port A to the specified 8-bit value.

    Port B (8-bit)

    • uint8_t readGPIOB(): Reads the current state of all pins on Port B.
    • void writeGPIOB(uint8_t value): Sets the state of all pins on Port B to the specified 8-bit value.

    Combined Ports (16-bit)

    • uint16_t readGPIOAB(): Reads the state of both Port A and Port B as a single 16-bit integer.
    • void writeGPIOAB(uint16_t value): Sets the state of both Port A and Port B using a single 16-bit integer.
  9. Use the Adafruit_MCP23X08 class for MCP23008 and MCP23S08

    master

    The Adafruit_MCP23X08 class provides an interface for controlling MCP23008 (I2C) and MCP23S08 (SPI) port expanders. It inherits from Adafruit_MCP23XXX, meaning it shares the common API for pin manipulation and configuration found in the broader MCP23XXX family. Use this class when working specifically with the 8-bit variants of these expanders.

    Adafruit_MCP23X08 mcp;
    // Use standard Adafruit_MCP23XXX methods inherited from the base class
    // such as begin(), pinMode(), digitalWrite(), etc.