PCF8574 I/O expander

Eight more pins over two wires, on a small blue board. Aliases: I2C expander, port expander, PCF8574A, IO expansion board.

It is the chip on the back of every I2C LCD backpack, and on its own the easiest way to add buttons or LEDs to a board that has run out of pins.

Pins

Pin What it does
GND, VCC Supply, 2.5 to 6 V.
SDA, SCL I2C. The module carries the pull-ups.
INT Open drain, low when an input has changed. Needs a pull-up.
P0 to P7 The eight port pins.

Properties

address is 0x20 to 0x27 for a PCF8574 and 0x38 to 0x3F for a PCF8574A: the board's three jumpers set the low three bits and the chip sets the rest.

No registers at all

There is nothing to configure. After the address, every byte written lands on the eight pins, P0 in bit 0, and every byte read is their levels. Wire.h is the whole driver:

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(0x20);
  Wire.write(0b11111110);           // P0 low, the rest high (inputs)
  Wire.endTransmission();
}

void loop() {
  Wire.requestFrom(0x20, 1);
  byte pins = Wire.read();
  Serial.println(pins, BIN);
  delay(500);
}

Write a 1 to read a pin

A pin is never set to be an input. A 0 pulls it hard to ground, strong enough to sink an LED's current; a 1 lets it go, with only a weak pull-up of about 100 µA. Anything outside can pull a 1 down, and that is how a pin becomes an input: write it 1, wire a button from it to ground, and read. A pin written 0 reads 0 whatever is on it.

That weak pull-up is also why an LED goes from VCC through a resistor into the pin, lit when the bit is 0. Wired the Arduino way, from the pin to ground, it glows at 100 µA, which is to say not at all.

What the model gets right

The port, both ways, as above; power-up with every pin high. INT goes low when a pin's level stops matching what it was at the last read or write, and a read or write lets it go, which is the datasheet's rule. A write's own pins settling do not raise it.

What it does not model

The brief strong pull-up a real chip gives a pin as it is written from 0 to 1. The weak pull-up is a 50 kΩ resistor here rather than a current source. The 25 mA sink limit: a pin pulled low sinks whatever the circuit asks.

Common mistakes

Wiring LEDs from the pin to ground and seeing nothing. Writing 0 to a pin and then wondering why its button always reads pressed. Mixing up the PCF8574 and PCF8574A address ranges.