diff --git a/libraries/PCF8574/LICENSE b/libraries/PCF8574/LICENSE new file mode 100644 index 00000000..2fc1cc50 --- /dev/null +++ b/libraries/PCF8574/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2020 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/PCF8574/PCF8574.cpp b/libraries/PCF8574/PCF8574.cpp index 55b579ed..510709ea 100644 --- a/libraries/PCF8574/PCF8574.cpp +++ b/libraries/PCF8574/PCF8574.cpp @@ -2,12 +2,18 @@ // FILE: PCF8574.cpp // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 -// VERSION: 0.1.9 -// PURPOSE: I2C PCF8574 library for Arduino -// URL: http://forum.arduino.cc/index.php?topic=184800 +// VERSION: 0.2.0 +// PURPOSE: Arduino library for PCF8574 - I2C IO expander +// URL: https://github.com/RobTillaart/PCF8574 +// http://forum.arduino.cc/index.php?topic=184800 // // HISTORY: -// 0.1.9 fix warning about return in readButton8() +// 0.2.0 2020-05-22 #pragma once; refactor; +// removed pre 1.0 support +// added begin(dsa, scl) for ESP32 +// added reverse() +// +// 0.1.9 2017-02-27 fix warning about return in readButton8() // 0.1.08 2016-05-20 Merged work of Septillion // Fix/refactor ButtonRead8() - see https://github.com/RobTillaart/Arduino/issues/38 // missing begin() => mask parameter @@ -35,6 +41,7 @@ #include + PCF8574::PCF8574(const uint8_t deviceAddress) { _address = deviceAddress; @@ -44,6 +51,14 @@ PCF8574::PCF8574(const uint8_t deviceAddress) _error = PCF8574_OK; } +#if defined (ESP8266) || defined(ESP32) +void PCF8574::begin(uint8_t sda, uint8_t scl, uint8_t val) +{ + Wire.begin(sda, scl); + PCF8574::write8(val); +} +#endif + void PCF8574::begin(uint8_t val) { Wire.begin(); @@ -62,11 +77,7 @@ uint8_t PCF8574::read8() _error = PCF8574_I2C_ERROR; return _dataIn; // last value } -#if (ARDUINO < 100) - _dataIn = Wire.receive(); -#else _dataIn = Wire.read(); -#endif return _dataIn; } @@ -125,15 +136,17 @@ void PCF8574::toggleMask(const uint8_t mask) void PCF8574::shiftRight(const uint8_t n) { - if (n == 0 || n > 7) return; - _dataOut >>= n; + if ((n == 0) || (_dataOut == 0)) return; + if (n > 7) _dataOut = 0; // shift 8++ clears all, valid... + if (_dataOut != 0) _dataOut >>= n; PCF8574::write8(_dataOut); } void PCF8574::shiftLeft(const uint8_t n) { - if (n == 0 || n > 7) return; - _dataOut <<= n; + if ((n == 0) || (_dataOut == 0)) return; + if (n > 7) _dataOut = 0; // shift 8++ clears all, valid... + if (_dataOut != 0) _dataOut <<= n; // only shift if there are bits set PCF8574::write8(_dataOut); } @@ -146,8 +159,9 @@ int PCF8574::lastError() void PCF8574::rotateRight(const uint8_t n) { + if ((n % 8) == 0) return; uint8_t r = n & 7; - _dataOut = (_dataOut >> r) | (_dataOut << (8-r)); + _dataOut = (_dataOut >> r) | (_dataOut << (8 - r)); PCF8574::write8(_dataOut); } @@ -156,6 +170,15 @@ void PCF8574::rotateLeft(const uint8_t n) rotateRight(8- (n & 7)); } +void PCF8574::reverse() // quite fast: 14 shifts, 3 or, 3 assignment. +{ + uint8_t x = _dataOut; + x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1)); + x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2)); + x = ((x >> 4) | (x << 4)); + PCF8574::write8(x); +} + //added 0.1.07/08 Septillion uint8_t PCF8574::readButton8(const uint8_t mask) { @@ -181,11 +204,4 @@ uint8_t PCF8574::readButton(const uint8_t pin) return rtn; } -//added 0.1.08 Septillion -void PCF8574::setButtonMask(uint8_t mask){ - _buttonMask = mask; -} - -// -// END OF FILE -// \ No newline at end of file +// -- END OF FILE -- diff --git a/libraries/PCF8574/PCF8574.h b/libraries/PCF8574/PCF8574.h index 4c33b119..7f38180b 100644 --- a/libraries/PCF8574/PCF8574.h +++ b/libraries/PCF8574/PCF8574.h @@ -1,25 +1,20 @@ +#pragma once // // FILE: PCF8574.H // AUTHOR: Rob Tillaart // DATE: 02-febr-2013 -// VERSION: 0.1.9 -// PURPOSE: I2C PCF8574 library for Arduino -// URL: http://forum.arduino.cc/index.php?topic=184800 +// VERSION: 0.2.0 +// PURPOSE: Arduino library for PCF8574 - I2C IO expander +// URL: https://github.com/RobTillaart/PCF8574 +// http://forum.arduino.cc/index.php?topic=184800 // // 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.9" +#define PCF8574_LIB_VERSION "0.2.0" #define PCF8574_OK 0x00 #define PCF8574_PIN_ERROR 0x81 @@ -31,29 +26,33 @@ class PCF8574 public: explicit PCF8574(const uint8_t deviceAddress); - void begin(uint8_t val=0xFF); +#if defined (ESP8266) || defined(ESP32) + void begin(uint8_t sda, uint8_t scl, uint8_t val = 0xFF); +#endif + void begin(uint8_t val = 0xFF); uint8_t read8(); uint8_t read(uint8_t pin); uint8_t value() const { return _dataIn; }; - void write8(const uint8_t value); - void write(const uint8_t pin, const uint8_t value); + void write8(const uint8_t value); + void write(const uint8_t pin, const uint8_t value); uint8_t valueOut() const { return _dataOut; } //added 0.1.07/08 Septillion - inline uint8_t readButton8(){ return PCF8574::readButton8(_buttonMask);} - uint8_t readButton8(const uint8_t mask=0xFF); - uint8_t readButton(const uint8_t pin); - void setButtonMask(uint8_t mask); + inline uint8_t readButton8() { return PCF8574::readButton8(_buttonMask); } + uint8_t readButton8(const uint8_t mask = 0xFF); + uint8_t readButton(const uint8_t pin); + inline void setButtonMask(uint8_t mask) { _buttonMask = mask; }; - // rotate, shift, toggle expect all lines are output - void toggle(const uint8_t pin); - void toggleMask(const uint8_t mask); // invertAll() = toggleMask(0xFF) - void shiftRight(const uint8_t n=1); - void shiftLeft(const uint8_t n=1); - void rotateRight(const uint8_t n=1); - void rotateLeft(const uint8_t n=1); + // rotate, shift, toggle, reverse expect all lines are output + void toggle(const uint8_t pin); + void toggleMask(const uint8_t mask = 0xFF); // default 0xFF ==> invertAll() + void shiftRight(const uint8_t n = 1); + void shiftLeft(const uint8_t n = 1); + void rotateRight(const uint8_t n = 1); + void rotateLeft(const uint8_t n = 1); + void reverse(); int lastError(); @@ -62,10 +61,8 @@ private: uint8_t _dataIn; uint8_t _dataOut; uint8_t _buttonMask; - int _error; + int _error; }; -#endif -// -// END OF FILE -// \ No newline at end of file + +// -- END OF FILE -- diff --git a/libraries/PCF8574/README.md b/libraries/PCF8574/README.md new file mode 100644 index 00000000..577f0a0b --- /dev/null +++ b/libraries/PCF8574/README.md @@ -0,0 +1,81 @@ +# PCF8574 + +Arduino library for PCF8574 - I2C IO expander + +# Description + +This library gives easy control over the 8 pins of a PCF8574 and PCF8574A chip. +These chips are identical in behavior although there are two distinct address ranges. + +| TYPE | ADDRESS-RANGE | +|:----|:----:| +|PCF8574 | 0x20 to 0x27 | +|PCF8574A | 0x38 to 0x3F | + +THe library allows to read and write both single pins or 8 pins at once. +Furthermore some additional functions are implemented that are a little more +playfull but still are useful. + + +### Interface + +**PCF8574(deviceAddress)** Constructor with device address as parameter. + +**begin(val = 0xFF)** set the initial value for the pins and masks. + +**begin(sda, scl, val = 0xFF)** idem, for the ESP32 where one can choose the I2C pins + +What needs to be added in the future is a parameter to choose another Wire interface +as some processors have multiple hardware Wire interfaces. + +---- + +**read8()** reads all 8 pins at once. This one does the actual reading. + +**read(pin)** reads a single pin; pin = 0..7 + +**value()** returns the last read inputs again, as this information is buffered +in the class this is faster than reread the pins. + +---- + +**write8(value)** writes all 8 pins at once. This one does the actual reading. + +**write(pin, value)** writes a single pin; pin = 0..7; value is HIGH(1) or LOW (0) + +**valueOut()** returns the last written data. + +---- + +TODO + +**setButtonMask(mask)** + +**readButton8()** + +**readButton8(mask = 0xFF)** + +**readButton(pin)** + +---- + +**toggle(pin)** toggles a single pin + +**toggleMask(mask)** toggles a selection of pins, if you want to invert all pins use 0xFF. + +**shiftRight(n = 1)** shifts output channels n pins (default 1) pins right (e.g. leds ). +Fills the higher lines with zero's. + +**shiftLeft(n = 1)** shifts output channels n pins (default 1) pins left (e.g. leds ). +Fills the lower lines with zero's. + + +**rotateRight(n = 1)** rotates output channels to right, moving lowest line to highest line. + +**rotateLeft(n = 1)** rotates output channels to left, moving highest line to lowest line. + +**reverse()** revers the "bit pattern" of the lines, high to low and vice versa. + +# Operation + +See examples diff --git a/libraries/PCF8574/examples/PCF8574_test2/PCF8574_test2.ino b/libraries/PCF8574/examples/PCF8574_test2/PCF8574_test2.ino index e50bc82f..1e453dde 100644 --- a/libraries/PCF8574/examples/PCF8574_test2/PCF8574_test2.ino +++ b/libraries/PCF8574/examples/PCF8574_test2/PCF8574_test2.ino @@ -14,42 +14,51 @@ PCF8574 PCF_39(0x39); // add leds to lines (used as output) void setup() { - Serial.begin(115200); - Serial.print("\npcf8574_test2.ino\nlib version: "); - Serial.println(PCF8574_LIB_VERSION); - - PCF_39.begin(); + Serial.begin(115200); + Serial.print("\npcf8574_test2.ino\nlib version: "); + Serial.println(PCF8574_LIB_VERSION); - PCF_39.write(0, 1); - for (int i=0; i<7; i++) - { - PCF_39.rotateLeft(); - delay(100); - } + PCF_39.begin(); - for (int i=0; i<7; i++) - { - PCF_39.rotateRight(); - delay(100); - } + PCF_39.write(0, 1); + for (int i = 0; i < 7; i++) + { + PCF_39.rotateLeft(); + delay(100); + } - for (int i=0; i<7; i++) - { - PCF_39.rotateLeft(3); - delay(100); - } + for (int i = 0; i < 7; i++) + { + PCF_39.rotateRight(); + delay(100); + } - for (int i=0; i<7; i++) - { - PCF_39.rotateRight(2); - delay(100); - } + for (int i = 0; i < 7; i++) + { + PCF_39.rotateLeft(3); + delay(100); + } - for (int i=0; i<255; i++) - { - PCF_39.toggleMask(i); - delay(100); - } + for (int i = 0; i < 7; i++) + { + PCF_39.rotateRight(2); + delay(100); + } + + for (int i = 0; i < 255; i++) + { + PCF_39.toggleMask(i); + delay(100); + } + + // 0010 0111 -> 0x27 + // 1110 0100 + PCF_39.write8(0x27); + for (int i = 0; i < 255; i++) + { + PCF_39.reverse(); + delay(100); + } } void loop() diff --git a/libraries/PCF8574/library.json b/libraries/PCF8574/library.json index b31ef504..16a4b7ec 100644 --- a/libraries/PCF8574/library.json +++ b/libraries/PCF8574/library.json @@ -1,7 +1,7 @@ { "name": "PCF8574", - "keywords": "I2C,PCF8574,IO,I/O,shift,rotate", - "description": "Library PCF8574 library for Arduino, implements shift rotate.", + "keywords": "I2C, PCF8574, PCF8574A, IO, I/O, shift, rotate", + "description": "Arduino library for PCF8574 - I2C IO expander, implements shift rotate.", "authors": [ { @@ -13,12 +13,12 @@ "repository": { "type": "git", - "url": "https://github.com/RobTillaart/Arduino.git" + "url": "https://github.com/RobTillaart/PCF8574.git" }, - "version":"0.1.9", + "version":"0.2.0", "frameworks": "arduino", "platforms": "*", "export": { - "include": "libraries/PCF8574" + "include": "*" } } diff --git a/libraries/PCF8574/library.properties b/libraries/PCF8574/library.properties index 5183fb82..ee2b4c69 100644 --- a/libraries/PCF8574/library.properties +++ b/libraries/PCF8574/library.properties @@ -2,8 +2,10 @@ name=PCF8574 version=0.1.9 author=Rob Tillaart maintainer=Rob Tillaart -sentence=Library PCF8574 library for Arduino. -paragraph=Implements shift rotate. +sentence=Arduino library for PCF8574 - I2C IO expander +paragraph=Implements shift rotate and toggle. category=Signal Input/Output -url=https://github.com/RobTillaart/Arduino/tree/master/libraries/ -architectures=* \ No newline at end of file +url=https://github.com/RobTillaart/PCF8574.git +architectures=* +includes=PCF8574.h +depends=