/* simulate one scan of a key martix, on open-drain active-low I/O expander BREADBOARD SETUP ******************************* Teensy LC connected to MCP23018 I/O expander via I2C 4.7k Ohm pullup resistors on SDA and SCL use volt meter to measure pin voltages MCP23018 has open-drain outputs (open-drain can only sink current) MCP23018 PIN DIAGRAM *************************** write port B read port A GND VSS 1 28 NC NC 2 27 GPA7 jumper0 GPB0 3 26 GPA6 GPB1 4 25 GPA5 GPB2 5 24 GPA4 jumper4 GPB3 6 23 GPA3 jumper4 GPB4 7 22 GPA2 GPB5 8 21 GPA1 GPB6 9 20 GPA0 jumper0 GPB7 10 19 INTA power VDD 11 18 INTB SCL SCL 12 17 NC SDA SDA 13 16 RESET power NC 14 15 ADDR GND */ #include "Wire.h" const uint8_t ADDR = 0x20; //MCP23018 I2C address with ADDR pin grounded void setup() { delay(1000); //time for Serial print to work // ================= configure ================ Serial.print("config "); Wire.begin(); Wire.beginTransmission(ADDR); Wire.write(0x01); //IODIRB Configure Wire.write(0); //as output Wire.endTransmission(); Wire.beginTransmission(ADDR); Wire.write(0x00); //IODIRA Configuration Wire.write(~0); //as input Wire.endTransmission(); Wire.beginTransmission(ADDR); Wire.write(0x0C); //GPPUA pull-up Wire.write(~0); //pull-up enabled Wire.endTransmission(); // =================== scan =================== Serial.println("scan"); Wire.beginTransmission(ADDR); Wire.write(0x13); //GPIOB output Wire.write(B00001111); //pins 0-3 off, pins 4-7 sink on (strobe, LED on) Wire.endTransmission(); Wire.beginTransmission(ADDR); Wire.write(0x12); //GPIOA (immediately before requestFrom) Wire.endTransmission(); Wire.requestFrom(ADDR, static_cast(1)); //request one byte from GPIOA read Serial.print("portA="); Serial.println(Wire.read(), BIN); //prints portA=11101111 } void loop() { }