First, you will need to activate the I2C port on your Raspberry Pi. There are several tutorials showing how to do this and I covered a couple links in my article about Adafruit's I2C LED matrix. You also have to find the address of your device. If it's a PCF8574A the address will be different.
The three least significant bits of the 7-bits address are A2, A1, and A0. These three bits are set on the pins of the chip that have the same name. That means that you could have a maximum of 8 PCF8574 connected to your Pi without having address conflict. This means you can have up to 64 more IO. If you use 8 PCF8574 and 8 PCF8574A you can double this number :)
On my breadboard, I wired 8 orange leds to the PCF8574 using 220 Ohms resistors. I plugged to chip on the 5V line to have a little bit more current on the LEDs than on the 3.3V line. A2, A1, and A0 are shorted to ground. The address of the device is then 0x38 (0111000). At first I did not understand it was this address because of the picture above, where we see a 0 next to A0. But A0 is really the least significant bit. An I2C address is always 7-bit.
On the rev2 Raspberry Pi, the I2C port is #1 and on rev1 it is #0. This little detail is important to know when we initialize the I2C device. Once everything is wired up and I2C is enabled, we can issue a detect command :
In the command i2cdetect -y 1 we specify that we are using port #1 for the rev2 Pi. There is also a really useful command we can use :
i2cset -y 1 0xADDRESS 0xDATA
For example, if I want to turn on all the LEDs directly on the command line, I can issue this command :
i2cset -y 1 0x38 0xFF
It's easy as that!!!
This demo would not be complete without some LED chasing and a demo Python program. In the sample below, LED1 through LED8 are the bit position of each LED in hexadecimal. I used the cycle function from the itertools library to create an infinite array that cycle from LED1 to LED8, and back to LED1, etc... Without pausing between each iteration, the Raspberry Pi would do that sequence really fast, so I'm adding a 100ms delay so we can see what is happening.
from smbus import SMBus from itertools import cycle from time import sleep LED1 = 0x01 LED2 = 0x02 LED3 = 0x04 LED4 = 0x08 LED5 = 0x10 LED6 = 0x20 LED7 = 0x40 LED8 = 0x80 PATTERN = (LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8, LED7, LED6, LED5, LED4, LED3, LED2) bus = SMBus(1) # Port 1 used on REV2 for LED in cycle(PATTERN): bus.write_byte(0x38, LED) sleep(0.1)