#include <Wire.h>
#define SDA_PIN 2 // your wiring
#define SCL_PIN 4 // your wiring
#define MCP23017_ADDR 0x20
// MCP23017 register addresses (BANK=0)
#define IODIRA 0x00
#define IODIRB 0x01
#define GPIOA 0x12
#define GPIOB 0x13
#define OLATA 0x14
#define OLATB 0x15
void mcpWriteRegister(uint8_t reg, uint8_t value) {
Wire.beginTransmission(MCP23017_ADDR);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t mcpReadRegister(uint8_t reg) {
Wire.beginTransmission(MCP23017_ADDR);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDR, (uint8_t)1);
if (Wire.available()) {
return Wire.read();
}
return 0;
}
void mcpSetAllOutputs() {
// 0 = output, 1 = input
mcpWriteRegister(IODIRA, 0x00); // GPA0..7 outputs
mcpWriteRegister(IODIRB, 0x00); // GPB0..7 outputs
}
void mcpSetAllLeds(bool on) {
// For sinking config: LOW = LED on, HIGH = LED off
uint8_t val = on ? 0x00 : 0xFF;
mcpWriteRegister(OLATA, val);
mcpWriteRegister(OLATB, val);
}
void mcpChasePattern(uint16_t delayMs) {
// Run a single "dot" from GPA0..7 then GPB0..7
for (int i = 0; i < 16; i++) {
uint8_t valA = 0xFF; // all off (HIGH) in sinking config
uint8_t valB = 0xFF;
if (i < 8) {
// Turn ON one LED on port A by pulling that bit LOW
valA &= ~(1 << i);
} else {
// Turn ON one LED on port B
int j = i - 8;
valB &= ~(1 << j);
}
mcpWriteRegister(OLATA, valA);
mcpWriteRegister(OLATB, valB);
delay(delayMs);
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("Starting MCP23017 test...");
// Init I2C on your chosen pins
Wire.begin(SDA_PIN, SCL_PIN);
// Optional: slow down a bit for debugging, if needed
// Wire.setClock(100000); // 100kHz
// Set all pins as outputs
mcpSetAllOutputs();
// Turn all LEDs OFF first
mcpSetAllLeds(false);
delay(500);
// Blink all LEDs a few times
for (int i = 0; i < 3; i++) {
Serial.println("Blink ON");
mcpSetAllLeds(true);
delay(500);
Serial.println("Blink OFF");
mcpSetAllLeds(false);
delay(500);
}
Serial.println("Entering chase pattern...");
}
void loop() {
// Chase the LEDs forever
mcpChasePattern(150);
}