From 7dad68a928aa746122b0ed23dcbac74d24811eb6 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Fri, 9 Jul 2021 12:58:55 +0200 Subject: [PATCH] Develop (#11) * fix #10 add get/setAddress() --- PCF8575.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ PCF8575.h | 19 +++++++++++++++++-- README.md | 39 +++++++++++++++++++++++++++------------ keywords.txt | 6 ++++-- library.json | 2 +- library.properties | 2 +- 6 files changed, 88 insertions(+), 24 deletions(-) diff --git a/PCF8575.cpp b/PCF8575.cpp index 2d4e5c8..61aa887 100644 --- a/PCF8575.cpp +++ b/PCF8575.cpp @@ -2,16 +2,18 @@ // FILE: PCF8575.cpp // AUTHOR: Rob Tillaart // DATE: 2020-07-20 -// VERSION: 0.1.1 +// VERSION: 0.1.2 // PURPOSE: Arduino library for PCF8575 - 16 channel I2C IO expander // URL: https://github.com/RobTillaart/PCF8575 // // HISTORY: -// 0.0.1 2020-07-20 initial version -// 0.0.2 2020-07-21 fix reverse(); refactor; -// 0.0.3 2020-07-29 fix #5 reverse() + refactor. -// 0.1.0 2021-01-03 add Arduino-CI + unit tests -// 0.1.1 2021-04-23 fix for platformIO compatibility +// 0.0.1 2020-07-20 initial version +// 0.0.2 2020-07-21 fix reverse(); refactor; +// 0.0.3 2020-07-29 fix #5 reverse() + refactor. +// 0.1.0 2021-01-03 add Arduino-CI + unit tests +// 0.1.1 2021-04-23 fix for platformIO compatibility +// 0.1.2 2021-07-09 fix #10 add set/getAddress() function + #include "PCF8575.h" @@ -26,6 +28,7 @@ PCF8575::PCF8575(const uint8_t deviceAddress, TwoWire *wire) _error = PCF8575_OK; } + #if defined (ESP8266) || defined(ESP32) bool PCF8575::begin(uint8_t dataPin, uint8_t clockPin, uint16_t val) { @@ -51,12 +54,27 @@ bool PCF8575::begin(uint16_t val) return true; } + bool PCF8575::isConnected() { _wire->beginTransmission(_address); return ( _wire->endTransmission() == 0); } + +bool PCF8575::setAddress(const uint8_t deviceAddress) +{ + _address = deviceAddress; + return isConnected(); +} + + +uint8_t PCF8575::getAddress() +{ + return _address; +} + + uint16_t PCF8575::read16() { if (_wire->requestFrom(_address, (uint8_t)2) != 2) @@ -69,6 +87,7 @@ uint16_t PCF8575::read16() return _dataIn; } + void PCF8575::write16(const uint16_t value) { _dataOut = value; @@ -78,6 +97,7 @@ void PCF8575::write16(const uint16_t value) _error = _wire->endTransmission(); } + uint8_t PCF8575::read(const uint8_t pin) { if (pin > 15) @@ -89,6 +109,7 @@ uint8_t PCF8575::read(const uint8_t pin) return (_dataIn & (1 << pin)) > 0; } + void PCF8575::write(const uint8_t pin, const uint8_t value) { if (pin > 15) @@ -107,6 +128,7 @@ void PCF8575::write(const uint8_t pin, const uint8_t value) write16(_dataOut); } + void PCF8575::toggle(const uint8_t pin) { if (pin > 15) @@ -117,12 +139,14 @@ void PCF8575::toggle(const uint8_t pin) toggleMask(1 << pin); } + void PCF8575::toggleMask(const uint16_t mask) { _dataOut ^= mask; PCF8575::write16(_dataOut); } + void PCF8575::shiftRight(const uint8_t n) { if ((n == 0) || (_dataOut == 0)) return; @@ -131,6 +155,7 @@ void PCF8575::shiftRight(const uint8_t n) PCF8575::write16(_dataOut); } + void PCF8575::shiftLeft(const uint8_t n) { if ((n == 0) || (_dataOut == 0)) return; @@ -139,6 +164,7 @@ void PCF8575::shiftLeft(const uint8_t n) PCF8575::write16(_dataOut); } + int PCF8575::lastError() { int e = _error; @@ -146,6 +172,7 @@ int PCF8575::lastError() return e; } + void PCF8575::rotateRight(const uint8_t n) { uint8_t r = n & 15; @@ -154,11 +181,13 @@ void PCF8575::rotateRight(const uint8_t n) PCF8575::write16(_dataOut); } + void PCF8575::rotateLeft(const uint8_t n) { rotateRight(16 - (n & 15)); } + void PCF8575::reverse() // quite fast { // 1 char === 1 bit uint16_t x = _dataOut; // x = 0123456789ABCDEF @@ -169,6 +198,7 @@ void PCF8575::reverse() // quite fast PCF8575::write16(x); } + //added 0.1.07/08 Septillion uint16_t PCF8575::readButton16(const uint16_t mask) { @@ -179,6 +209,7 @@ uint16_t PCF8575::readButton16(const uint16_t mask) return _dataIn; } + //added 0.1.07 Septillion uint8_t PCF8575::readButton(const uint8_t pin) { @@ -194,4 +225,5 @@ uint8_t PCF8575::readButton(const uint8_t pin) return rtn; } + // -- END OF FILE -- diff --git a/PCF8575.h b/PCF8575.h index d0ee2e3..7d43b0b 100644 --- a/PCF8575.h +++ b/PCF8575.h @@ -3,7 +3,7 @@ // FILE: PCF8575.h // AUTHOR: Rob Tillaart // DATE: 2020-07-20 -// VERSION: 0.1.1 +// VERSION: 0.1.2 // PURPOSE: Arduino library for PCF8575 - 16 channel I2C IO expander // URL: https://github.com/RobTillaart/PCF8575 // @@ -11,10 +11,13 @@ // see PCF8575.cpp file // + #include "Arduino.h" #include "Wire.h" -#define PCF8575_LIB_VERSION (F("0.1.1")) + +#define PCF8575_LIB_VERSION (F("0.1.2")) + #ifndef PCF8575_INITIAL_VALUE #define PCF8575_INITIAL_VALUE 0xFFFF @@ -37,20 +40,30 @@ class PCF8575 bool begin(uint16_t val = PCF8575_INITIAL_VALUE); bool isConnected(); + + // note: setting the address corrupt internal buffer values + // a read8() / write8() call updates them. + bool setAddress(const uint8_t deviceAddress); + uint8_t getAddress(); + + uint16_t read16(); uint8_t read(uint8_t pin); uint16_t value() const { return _dataIn; }; + void write16(const uint16_t value); void write(const uint8_t pin, const uint8_t value); uint16_t valueOut() const { return _dataOut; } + // added 0.1.07/08 Septillion uint16_t readButton16() { return readButton16(_buttonMask); } uint16_t readButton16(const uint16_t mask); uint8_t readButton(const uint8_t pin); void setButtonMask(uint16_t mask) { _buttonMask = mask; }; + // rotate, shift, toggle, reverse expect all lines are output void toggle(const uint8_t pin); void toggleMask(const uint16_t mask = 0xFFFF); // default invertAll() @@ -60,6 +73,7 @@ class PCF8575 void rotateLeft(const uint8_t n = 1); void reverse(); + int lastError(); private: @@ -72,4 +86,5 @@ class PCF8575 TwoWire* _wire; }; + // -- END OF FILE -- diff --git a/README.md b/README.md index b3ce0a5..3a4ceca 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Arduino library for PCF8575 - 16 channel I2C IO expander + ## Description Related to the PCF8574 8 channel IO expander library https://github.com/RobTillaart/PCF8574 @@ -16,10 +17,11 @@ The library gives easy control over the 16 pins of the PCF8575 chips. Base address = 0x20 + 0..7 depending on address pins A0..A2 -| TYPE | ADDRESS-RANGE | notes | -|:----|:----:|:----:| -|PCF8575 | 0x20 to 0x27 | same range as PCF8574 !! | -| | | | +| TYPE | ADDRESS-RANGE | notes | +|:---------|:-------------:|:------------------------:| +|PCF8575 | 0x20 to 0x27 | same range as PCF8574 !! | +| | | | + So you can connect up to 8 PCF8575 on one I2C bus, giving access to 8 x 16 = 128 IO lines. @@ -29,20 +31,23 @@ Be sure to have a well dimensioned power supply. The library allows to read and write both single pins or 16 pins at once. Furthermore some additional functions are implemented that are -playfull but useful. +playful but useful. + ## I2C Clock Testing showed that the PCF8575 still works at 600 KHz and failed at 800 KHz. -These values are outside the specs of the datasheet so they are not recommendend. +These values are outside the specs of the datasheet so they are not recommended. However when performance is needed you can try to overclock the chip. + ## Interface **PCF8575_INITIAL_VALUE** is a define that can be set compile time or before the include of "pcf8575.h" to overrule the default value used with the **begin()** call. + ### Constructor - **PCF8575(deviceAddress, TwoWire \*wire = &Wire)** Constructor with I2C device address, @@ -51,7 +56,12 @@ and optional the Wire interface as parameter. - **begin(sda, scl, val = PCF8575_INITIAL_VALUE)** 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. -- **isConnected()** checks if the address is visable on the I2C bus +- **isConnected()** checks if the address is visible on the I2C bus +- **bool setAddress(const uint8_t deviceAddress)** sets the device address after construction. +Can be used to switch between PCF8575 modules runtime. Note this corrupts internal buffered values, +so one might need to call **read16()** and/or **write16()**. Returns true if address can be found on I2C bus. +- **uint8_t getAddress()** returns the device address. + ### Read and Write @@ -63,6 +73,7 @@ in the class this is faster than reread the pins. - **write(pin, value)** writes a single pin; pin = 0..15; value is HIGH(1) or LOW (0) - **valueOut()** returns the last written data. + ### Button - **setButtonMask(mask)** @@ -70,6 +81,7 @@ in the class this is faster than reread the pins. - **readButton16(mask)** - **readButton(pin)** + ### Special - **toggle(pin)** toggles a single pin @@ -83,17 +95,20 @@ Fills the lower lines with zero's. - **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. + ### Misc - **lastError()** returns the last error from the lib. (see .h file) + ## Error codes -| name | value | description | -|:------|:----:|:----| -| PCF8574_OK | 0x00 | no error -| PCF8574_PIN_ERROR | 0x81 | pin number out of range | -| PCF8574_I2C_ERROR | 0x82 | I2C communication error | +| name | value | description | +|:-------------------|:-----:|:------------------------| +| PCF8574_OK | 0x00 | no error | +| PCF8574_PIN_ERROR | 0x81 | pin number out of range | +| PCF8574_I2C_ERROR | 0x82 | I2C communication error | + ## Testing diff --git a/keywords.txt b/keywords.txt index 8223b8b..c7346d4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,11 +1,13 @@ -# Syntax Coloring Map For PCF8575 +# Syntax Colouring Map For PCF8575 -# Datatypes (KEYWORD1) +# Data types (KEYWORD1) PCF8575 KEYWORD1 # Methods and Functions (KEYWORD2) begin KEYWORD2 isConnected KEYWORD2 +setAddress KEYWORD2 +getAddress KEYWORD2 read16 KEYWORD2 read KEYWORD2 diff --git a/library.json b/library.json index b8679fa..4c5bfb4 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "type": "git", "url": "https://github.com/RobTillaart/PCF8575.git" }, - "version":"0.1.1", + "version": "0.1.2", "license": "MIT", "frameworks": "arduino", "platforms": "*" diff --git a/library.properties b/library.properties index e7cc09f..5b51a11 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=PCF8575 -version=0.1.1 +version=0.1.2 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for PCF8575 - 16 channel I2C IO expander