- Introduction
- PCAL6408A Features
- MicroPython Interface
- Complete Example
- C/C++ Interface
- Hardware Connection
- Troubleshooting
- Register Map
The IO Expander interface provides access to the PCAL6408A 8-bit I2C GPIO expander available on SGW3501-F1-StarterKit boards. This component extends the available GPIO pins and provides interrupt-capable I/O expansion.
The IO expander implementation uses MicroPython I2C Bridge architecture for ESP-IDF v5.4+ compatibility:
- Driver: PCAL6408A 8-bit I2C GPIO expander
- Bridge:
mp_i2c_bridgecomponent provides C interface to MicroPython I2C - Benefits: Unified I2C management, modern ESP-IDF compatibility, future-proof
- Device Address: 0x20 (7-bit I2C address)
- I2C Pins: SCL=20, SDA=21 (configurable)
- Frequency: 100kHz I2C bus frequency
- Integration: Uses
ioexp_mp.cwith I2C bridge for MicroPython builds
- 8-bit I2C-bus GPIO with interrupt and weak pull-up
- 5V tolerant inputs
- Polarity inversion register
- Low current consumption
- Interrupt output for pin change detection
- Compatible with standard GPIO operations
import ioexp
# Initialize the IO expander
ioexp.init()# Set pin direction (1 = input, 0 = output)
ioexp.set_direction(pin_number, direction)
# Example: Set pin 0 as output, pin 1 as input
ioexp.set_direction(0, 0) # Output
ioexp.set_direction(1, 1) # Input# Write to output pin
ioexp.write_pin(pin_number, value)
# Example: Set pin 0 high
ioexp.write_pin(0, 1)
# Read from input pin
value = ioexp.read_pin(pin_number)
# Example: Read pin 1 state
state = ioexp.read_pin(1)
print(f"Pin 1 state: {state}")# Write entire 8-bit port at once
ioexp.write_port(0b10101010) # Set pins 1,3,5,7 high
# Read entire port
port_state = ioexp.read_port()
print(f"Port state: 0x{port_state:02X}")# Enable/disable weak pull-up resistors
ioexp.set_pullup(pin_number, enable)
# Example: Enable pull-up on pin 2
ioexp.set_pullup(2, 1)# Configure polarity inversion
ioexp.set_polarity(pin_number, inverted)
# Example: Invert polarity on pin 3
ioexp.set_polarity(3, 1)import ioexp
import time
# Initialize the IO expander
ioexp.init()
# Configure pins: 0-3 as outputs, 4-7 as inputs with pull-ups
for pin in range(4):
ioexp.set_direction(pin, 0) # Output
for pin in range(4, 8):
ioexp.set_direction(pin, 1) # Input
ioexp.set_pullup(pin, 1) # Enable pull-up
# Blink LEDs on output pins
while True:
# Set outputs high
for pin in range(4):
ioexp.write_pin(pin, 1)
# Read and display input states
for pin in range(4, 8):
state = ioexp.read_pin(pin)
print(f"Input pin {pin}: {state}")
time.sleep(0.5)
# Set outputs low
for pin in range(4):
ioexp.write_pin(pin, 0)
time.sleep(0.5)For native C/C++ applications, the same functionality is available through the header interface:
#include "ioexp.h"
// Initialize
esp_err_t err = ioexp_init();
// Configure pin direction
ioexp_set_direction(0, IOEXP_OUTPUT);
ioexp_set_direction(4, IOEXP_INPUT);
// Digital operations
ioexp_write_pin(0, 1); // Set pin 0 high
int state = ioexp_read_pin(4); // Read pin 4The PCAL6408A is typically connected as follows on SGW3501-F1-StarterKit:
- VCC: 3.3V power supply
- GND: Ground
- SCL: I2C clock line (GPIO 20)
- SDA: I2C data line (GPIO 21)
- INT: Interrupt output (optional, board-dependent)
- ADDR: Address select pin (determines I2C address)
-
I2C Communication Errors
- Verify I2C connections (SCL, SDA, power, ground)
- Check I2C address (0x20 default)
- Ensure proper pull-up resistors on I2C lines
-
Pin State Issues
- Verify pin direction configuration
- Check for polarity inversion settings
- Ensure proper voltage levels (5V tolerance)
-
Initialization Failures
- Confirm device presence with I2C scan
- Verify power supply stability
- Check for I2C bus conflicts
# Test I2C communication
import machine
i2c = machine.I2C(0, scl=20, sda=21)
devices = i2c.scan()
print(f"I2C devices found: {[hex(d) for d in devices]}")
# Expected output should include 0x20 for PCAL6408AFor advanced users, the PCAL6408A register map:
| Register | Address | Function |
|---|---|---|
| Input Port | 0x00 | Read input levels |
| Output Port | 0x01 | Write output levels |
| Polarity Inversion | 0x02 | Configure input polarity |
| Configuration | 0x03 | Set pin direction |
| Output Drive Strength | 0x40 | Configure drive strength |
| Input Latch | 0x42 | Input latch control |
| Pull-up/Pull-down Enable | 0x43 | Pull resistor enable |
| Pull-up/Pull-down Select | 0x44 | Pull resistor direction |
| Interrupt Mask | 0x45 | Interrupt enable |
| Interrupt Status | 0x46 | Interrupt status |
| Output Port Configuration | 0x4F | Output port configuration |