Last Modified: | November 05, 2017, at 03:58 AM |
By: | pert |
The I2C bus can be used to extend the number of IO lines. A frequently used chip for this is the PCF8574 which offers 8 IO lines. The PCF8474 has multiple address lines so the I2C address can be changed.
The library supports
The PCF8574 library on GitHub: https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
To use the library, make a folder in your SKETCHBOOKPATH\libraries with the name PCF8574 and put the .h and .cpp there.
A sketch shows how the library can be used ---
// // FILE: pcf8574_test.ino // AUTHOR: Rob Tillaart // DATE: 27-08-2013 // // PURPOSE: demo // #include "PCF8574.h" #include <Wire.h> // adjust addresses if needed PCF8574 PCF_38(0x38); // add switches to lines (used as input) PCF8574 PCF_39(0x39); // add LEDs to lines (used as output) void setup() { Serial.begin(115200); Serial.println("\nTEST PCF8574\n"); uint8_t value = PCF_38.read8(); Serial.print("#38:\t"); Serial.println(value); for (int i=0; i<255; i++) { PCF_39.write8(i); delay(100); } PCF_39.write(0, 1); for (int i=0; i<7; i++) { PCF_39.shiftLeft(); delay(100); } for (int i=0; i<7; i++) { PCF_39.shiftRight(); delay(100); } for (int i=0; i<8; i++) { PCF_39.write(i, 1); delay(100); PCF_39.write(i, 0); delay(100); } for (int i=0; i<8; i++) { PCF_39.toggle(i); delay(100); PCF_39.toggle(i); delay(100); } } void loop() { // echos the lines uint8_t value = PCF_38.read8(); PCF_39.write8(value); delay(100); } // // END OF FILE //
Another example using the IRQ pin of the chip (not tested yet) - http://forum.arduino.cc/index.php?topic=204596.msg1506639#msg1506639 -
Enjoy tinkering,
rob.tillaart@removethisgmail.com
// // FILE: PCF8574.H // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 // VERSION: 0.1.02 // PURPOSE: I2C PCF8574 library for Arduino // URL: // // HISTORY: // see PCF8574.cpp file // #ifndef _PCF8574_H #define _PCF8574_H #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #define PCF8574_LIB_VERSION "0.1.02" class PCF8574 { public: PCF8574(int address); uint8_t read8(); uint8_t read(uint8_t pin); uint8_t value(); void write8(uint8_t value); void write(uint8_t pin, uint8_t value); void toggle(uint8_t pin); void shiftRight(uint8_t n=1); void shiftLeft(uint8_t n=1); int lastError(); private: int _address; uint8_t _data; int _error; }; #endif // // END OF FILE //
// // FILE: PCF8574.cpp // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 // VERSION: 0.1.02 // PURPOSE: I2C PCF8574 library for Arduino // URL: // // HISTORY: // 0.1.02 replaced ints with uint8_t to reduce footprint; // added default value for shiftLeft() and shiftRight() // renamed status() to lastError(); // 0.1.01 added value(); returns last read 8 bit value (cached); // value() does not always reflect the latest state of the pins! // 0.1.00 initial version // #include "PCF8574.h" #include <Wire.h> PCF8574::PCF8574(int address) { _address = address; Wire.begin(); } uint8_t PCF8574::read8() { Wire.beginTransmission(_address); Wire.requestFrom(_address, 1); #if (ARDUINO < 100) _data = Wire.receive(); #else _data = Wire.read(); #endif _error = Wire.endTransmission(); return _data; } uint8_t PCF8574::value() { return _data; } void PCF8574::write8(uint8_t value) { Wire.beginTransmission(_address); _data = value; Wire.write(_data); _error = Wire.endTransmission(); } uint8_t PCF8574::read(uint8_t pin) { PCF8574::read8(); return (_data & (1<<pin)) > 0; } void PCF8574::write(uint8_t pin, uint8_t value) { PCF8574::read8(); if (value == LOW) { _data &= ~(1<<pin); } else { _data |= (1<<pin); } PCF8574::write8(_data); } void PCF8574::toggle(uint8_t pin) { PCF8574::read8(); _data ^= (1 << pin); PCF8574::write8(_data); } void PCF8574::shiftRight(uint8_t n) { if (n == 0 || n > 7 ) return; PCF8574::read8(); _data >>= n; PCF8574::write8(_data); } void PCF8574::shiftLeft(uint8_t n) { if (n == 0 || n > 7) return; PCF8574::read8(); _data <<= n; PCF8574::write8(_data); } int PCF8574::lastError() { int e = _error; _error = 0; return e; } // // END OF FILE //