PCF8574A Remote 8-BIT I/O Expander For I2C Bus
Datasheet: http://mirror-sg.icy.com.au/datasheets/ti/pcf8574a.pdf
Store: Buy PCF8574AN
What can I use it for?
This chip lets you use two communication pins on a micro-controller to give you an extra 8 pins of general purpose input and output. Furthermore, each pin can sink over 100mA per pin, so it also acts as a buffer or driver IC for output. This is particularly useful for driving LEDs, or other lighting, small motors, etc. directly from this chip.
How does it work?
This IC communicates over the TWI or I2C bus, which are often found as the two pins labelled SDA (data) and SCL (clock) on a micro-controller. It acts as a "slave device", where your micro-controller would be a master that sends or asks it for data. This particular method of communication allows you to share these two pins with many TWI/I2C devices. This means if you have 5 of these ICs, you can use two micro-controller pins to control 40 input/output pins. The micro-controller knows which device it is talking to, by identifying each I2C device by an address. This address can be set by connecting three of the pins on this IC to Vcc (+) or Gnd (-). This gives 8 combinations, allowing 8 different addresses (thus 8 of these ICs can be connected to the one I2C bus).
What else do I need to know?
The I2C/TWI bus requires two pull-up resistors connecting the SDA and SCL lines to Vcc. For a 5V device, something around the 4.7K value works well. Some micro-controllers have built-in pullups that can be enabled. If these don't work (they might not pull up enough, or pull up too much) then you can attach external resistors to the two lines.
There is also an interrupt line on this IC that outputs a value back to the micro-controller when the value of one of its pins changes. This lets the master know when something's changed, without the need for this IC to become a master (it can stay slave).
Can I use it with Arduino or AVR Microcontrollers?
Yes. Arduino comes with the "Wire" library specifically for this purpose. The datasheet for this chip tells us that if we connect all the address pins to Gnd, then its address will be 56 (decimal) or 0x38 (hexidecimal). SDA on arduino is Analog Port, Pin 4 and SCL is Analog Port, Pin 5. These connect to SDA and SCL on the ICs (with pull-up resistors, if required).
The following Arduino code will turn on (output high) on each pin of the IC in turn, and then read the input value of all 8 pins:
1 #include <Wire.h>
2
3 void setup( ) {
4 Serial.begin( 9600 );
5 Wire.begin( ); // initialise TWI as a master
6 }
7
8 void loop( ) {
9 char portData;
10
11 // set each pin in turn
12 for ( int i = 0; i != 8; ++i ) {
13 // send a byte where only the i'th bit is set
14 // each bit represents a pin on the 8-pin port
15 portData = 0;
16 bitSet( portData, i ); // set the i'th bit on the port
17 Wire.beginTransmission( 0x38 ); // the address assigned to the extender IC
18 Wire.send( portData );
19 Wire.endTransmission( );
20
21 delay( 500 );
22 }
23
24 Wire.requestFrom( 0x38, 1 ); // request 1 byte from device at address 0x38
25 if ( Wire.available( ) > 0 ) {
26 portData = Wire.receive( );
27 }
28
29 // print:
30 // P0=0 or 1 (depending on whether this pin is low or high)
31 // P1=0 or 1, etc.
32 for ( int i = 0; i != 8; ++i ) {
33 Serial.print( "P" );
34 Serial.print( i );
35 Serial.print( "=" );
36 Serial.println( bitRead( portData, i ) );
37 }
38
39 Serial.write()
40 }
For other AVR micro-controllers, here are some links to I2C/TWI libraries and code:
Troubleshooting
- I have connected LEDs to the IC's 'P' pins, but they are very dim.
This IC sinks a lot of current, but cannot source very much. Make sure that the LED is connected from Vcc through the appropriate resistor and into the positive lead of the LED, and the negative lead is grounded by the IC's 'P' pin. With this configuration, a set bit will make the pin source voltage (high), turning the LED off and a cleared bit will make the pin sink (low), allowing current to flow and turning the LED on.
- I have enabled internal pullups on the master for SDA and SCL, but the code isn't working.
- Sometimes the internal pullups aren't enough, especially if there is voltage protection circuitry on the pin as well. Adding external pullup resistors may solve the problem.
- If using an AVR library, or the AVR TWI registers directly, make sure sei(); is set, to enable interrupts
- I plugged in SDA and SCL, but it's not working.
- The IC also requires a voltage source plugged into the Vcc pin and Gnd pins: it works with any voltage from about 2.5V to 6V.
- The address pins on the IC need to be connected to either Vcc or Gnd to configure the address this IC will respond to.
- Try disconnecting the power to the IC momentarily (resetting it). Sometimes a faulty connection on start-up can make the IC unresponsive.
- Make sure your connections are secure, loose connections can cause noise and bounce that interfere with the I2C/TWI protocol.
- What do I do with the interrupt pin?
- This is an output for the IC, and can be connected to a micro-controller logic input, or external interrupt input. This pin changes when the logic pins on the IC change value.
- If you don't need to know when the input changes, this pin can be left disconnected.
![icy [labs]](/moin_static171/common/wikilogo.png)