Arduino and PCF8574 IO Expander – Binary Counter and I2C Bus Read / Write

Abstract

In Embedded system design, whenever shortage of digital IO pins for connecting the sensors, relays, then IO expander are used for providing more digital IOs to the system. This article, discuss about connecting an IO expander to the Arduino and Read / Write operation of that device.

Parts and components

Arduino Uno board

PCF8574 IO expander = 2 Nos

330 Ohm resistor = 12 Nos

10K Ohm resistor = 6

Nos LEDs = 12 Nos

4 way DIP switch = 1 No

Step 1: Schematic

PCF8574 is the Input / Output (I/O) expander, which will be connected to the Arduino I2C bus.

I2C data pin (SDA) is connected to ADC4 and clock pin (SCL) is connected to ADC5.

The PCF8574 device provides general-purpose remote I/O expansion. The device features an 8-bit quasi-bidirectional I/O port (P0–P7), including latched outputs with high current drive capability for directly driving LEDs.

Each quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal.

The Address range of PCF8574 is 0x20 to 0x27 (7 bit address mode).

The least significant bit of address is used for Write (0) or Read (1) operation selection.

Eight PCF8574 can be connected to the I2C bus, with hardwire address selection on each device.

The 8 LED’s are connected to the PCF8574 Group1 device IO pins through 330 ohm current limiting resistors.

DIP switches are manual electrical switches arranged and packed in Dual Inline Package. Can be directly solder into PCB. Commonly used to select the operating modes of an electronic device for specific situations.

A 4 way DIP switch is connected to the lower nibble of PCF8574 Group2 device IO pins through 10K ohm pullup resistors.

And 4 LEDs are connected to the upper nibble of PCF8574 Group2 device IO pins through 330 ohm current limiting resistors.

Step 2: Software

The included Wire library allows to communicate to the I2C/TWI bus of Arduino.

The binary counter is incremented by every 300 mS and writes it to the Group 1 IO expander, where LEDs are connected and configured as digital output pins.

Lower nibble of Group 2 IO expander is read and displayed at upper nibble of the same IO expander.

Lower nibble is configured as inputs, and connected with 4 way dip switch.

Upper nibble is configured as output and connected with 4 LEDs.

The project is successfully simulated by using the Proteus.

/// Experiment of PCF8574 IO expander
// Name:- M.Pugazhendi // Date:- 27thJul2016 // Version:- V0.1 // e-mail:- muthuswamy.pugazhendi@gmail.com

//Include Wire library #include <Wire.h>

#define DEVICE_1 B0100000 #define DEVICE_2 B0100001

void setup() { Wire.begin(); IOexpanderWrite(DEVICE_2, 0x0F); }

void loop() { byte k; for(byte i = 0; i<255; i++) { IOexpanderWrite(DEVICE_1, i); delay(50); k = IOexpanderRead(DEVICE_2); delay(50); IOexpanderWrite(DEVICE_2, (k<<4)|0x0F); delay(200); } }

//Write a byte to the IO expander

void IOexpanderWrite(byte address, byte _data ) { Wire.beginTransmission(address); Wire.write(_data); Wire.endTransmission(); }

//Read a byte from the IO expander

byte IOexpanderRead(int address) { byte _data; Wire.requestFrom(address, 1); if(Wire.available()) { _data = Wire.read(); } return _data; }

Share

    Recommendations

    • Sensors Contest

      Sensors Contest
    • Planter Challenge

      Planter Challenge
    • Paint Challenge

      Paint Challenge

    4 Discussions

    0
    None
    zeevon

    1 year ago on Step 1

    The recommended LED connection is wrong. PCF8574 output is design to sink not source. I've tested according to the connection and it fail. After troubleshooting for 2 days and finally I found out from the datasheet that the source current is only 300uA and the sink current is 10-25mA. I'm very unlucky that I'm using old LEDs to experiment that the intensity is very low and that is why i can't manage to see the circuit works.

    After I connected the LED in sink mode, (LED anode connected to +ve 5V and LED cathode connected tp PCF8574 ouput, it works fine.

    The software has to be inverted. I just add reserveLogic = i ^ 0xff; to invert the i then IOexpanderWrite(DEVICE_1, reverseLogic);

    pcf8574 electrical spec.JPGPCF8574 recommended connection.JPG
    3 replies
    0
    None
    MatthewM156zeevon

    Reply 11 days ago

    My understanding is that these can drive 7 segment (plus dot) displays directly, and that 330 Ohm resistors are not necessary? i.e. it is meant to directly drive LEDS @ 15-20mA.

    0
    None
    PugazhMzeevon

    Reply 10 months ago

    Thanks Zeevon. I used simulator. That's Why I could not come across the problem.

    0
    None
    PugazhMzeevon

    Reply 10 months ago

    Thanks Zeevon. I used simulator. That's Why I could not come across the problem.