0.3.2 PCF8574

This commit is contained in:
rob tillaart 2021-07-05 10:01:35 +02:00
parent 0cf57331ac
commit 43cb9320d0
7 changed files with 101 additions and 41 deletions

View File

@ -2,12 +2,13 @@
// FILE: PCF8574.cpp
// AUTHOR: Rob Tillaart
// DATE: 02-febr-2013
// VERSION: 0.3.1
// VERSION: 0.3.2
// PURPOSE: Arduino library for PCF8574 - 8 channel I2C IO expander
// URL: https://github.com/RobTillaart/PCF8574
// http://forum.arduino.cc/index.php?topic=184800
//
// HISTORY:
// 0.3.2 2021-07-04 fix #25 add setAddress()
// 0.3.1 2021-04-23 Fix for platformIO compatibility
// 0.3.0 2021-01-03 multiWire support - inspirated by mattbue - issue #14
// 0.2.4 2020-12-17 fix #6 tag problem 0.2.3
@ -90,6 +91,19 @@ bool PCF8574::isConnected()
}
bool PCF8574::setAddress(const uint8_t deviceAddress)
{
_address = deviceAddress;
return isConnected();
}
uint8_t PCF8574::getAddress()
{
return _address;
}
// removed _wire->beginTransmission(addr);
// with @100KHz -> 265 micros()
// without @100KHz -> 132 micros()
@ -106,6 +120,7 @@ uint8_t PCF8574::read8()
return _dataIn;
}
void PCF8574::write8(const uint8_t value)
{
_dataOut = value;
@ -114,6 +129,7 @@ void PCF8574::write8(const uint8_t value)
_error = _wire->endTransmission();
}
uint8_t PCF8574::read(const uint8_t pin)
{
if (pin > 7)
@ -125,6 +141,7 @@ uint8_t PCF8574::read(const uint8_t pin)
return (_dataIn & (1 << pin)) > 0;
}
void PCF8574::write(const uint8_t pin, const uint8_t value)
{
if (pin > 7)
@ -143,6 +160,7 @@ void PCF8574::write(const uint8_t pin, const uint8_t value)
write8(_dataOut);
}
void PCF8574::toggle(const uint8_t pin)
{
if (pin > 7)
@ -153,12 +171,14 @@ void PCF8574::toggle(const uint8_t pin)
toggleMask(1 << pin);
}
void PCF8574::toggleMask(const uint8_t mask)
{
_dataOut ^= mask;
PCF8574::write8(_dataOut);
}
void PCF8574::shiftRight(const uint8_t n)
{
if ((n == 0) || (_dataOut == 0)) return;
@ -167,6 +187,7 @@ void PCF8574::shiftRight(const uint8_t n)
PCF8574::write8(_dataOut);
}
void PCF8574::shiftLeft(const uint8_t n)
{
if ((n == 0) || (_dataOut == 0)) return;
@ -175,6 +196,7 @@ void PCF8574::shiftLeft(const uint8_t n)
PCF8574::write8(_dataOut);
}
int PCF8574::lastError()
{
int e = _error;
@ -182,6 +204,7 @@ int PCF8574::lastError()
return e;
}
void PCF8574::rotateRight(const uint8_t n)
{
uint8_t r = n & 7;
@ -190,11 +213,13 @@ void PCF8574::rotateRight(const uint8_t n)
PCF8574::write8(_dataOut);
}
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;
@ -204,6 +229,7 @@ void PCF8574::reverse() // quite fast: 14 shifts, 3 or, 3 assignment.
PCF8574::write8(x);
}
//added 0.1.07/08 Septillion
uint8_t PCF8574::readButton8(const uint8_t mask)
{
@ -214,6 +240,7 @@ uint8_t PCF8574::readButton8(const uint8_t mask)
return _dataIn;
}
//added 0.1.07 Septillion
uint8_t PCF8574::readButton(const uint8_t pin)
{
@ -230,4 +257,5 @@ uint8_t PCF8574::readButton(const uint8_t pin)
return rtn;
}
// -- END OF FILE --

View File

@ -3,7 +3,7 @@
// FILE: PCF8574.H
// AUTHOR: Rob Tillaart
// DATE: 02-febr-2013
// VERSION: 0.3.1
// VERSION: 0.3.2
// PURPOSE: Arduino library for PCF8574 - 8 channel I2C IO expander
// URL: https://github.com/RobTillaart/PCF8574
// http://forum.arduino.cc/index.php?topic=184800
@ -12,10 +12,12 @@
// see PCF8574.cpp file
//
#include "Arduino.h"
#include "Wire.h"
#define PCF8574_LIB_VERSION (F("0.3.1"))
#define PCF8574_LIB_VERSION (F("0.3.2"))
#ifndef PCF8574_INITIAL_VALUE
#define PCF8574_INITIAL_VALUE 0xFF
@ -37,8 +39,13 @@ public:
bool begin(uint8_t val = PCF8574_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();
uint8_t read8();
uint8_t read(uint8_t pin);
uint8_t read(const uint8_t pin);
uint8_t value() const { return _dataIn; };
void write8(const uint8_t value);
@ -49,7 +56,7 @@ public:
inline uint8_t readButton8() { return PCF8574::readButton8(_buttonMask); }
uint8_t readButton8(const uint8_t mask);
uint8_t readButton(const uint8_t pin);
inline void setButtonMask(uint8_t mask) { _buttonMask = mask; };
inline void setButtonMask(const uint8_t mask) { _buttonMask = mask; };
// rotate, shift, toggle, reverse expect all lines are output
void toggle(const uint8_t pin);
@ -72,4 +79,5 @@ private:
TwoWire* _wire;
};
// -- END OF FILE --

View File

@ -7,6 +7,7 @@
Arduino library for PCF8574 - 8 channel I2C IO expander
## Description
Related to the PCF8575 16 channel IO expander library https://github.com/RobTillaart/PCF8575
@ -14,10 +15,10 @@ Related to the PCF8575 16 channel IO expander library https://github.com/RobTil
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 | notes |
|:----|:----:|:----:|
|PCF8574 | 0x20 to 0x27 | same range as PCF8575 !! |
|PCF8574A | 0x38 to 0x3F |
| TYPE | ADDRESS-RANGE | notes |
|:---------|:-------------:|:------------------------:|
|PCF8574 | 0x20 to 0x27 | same range as PCF8575 !! |
|PCF8574A | 0x38 to 0x3F | |
So you can connect up to 16 PCF8574 on one I2C bus, giving access
to 16 x 8 = 128 IO lines. To maximize IO lines combine 8 x PCF8575 + 8 x PCF8574A giving
@ -25,7 +26,7 @@ to 16 x 8 = 128 IO lines. To maximize IO lines combine 8 x PCF8575 + 8 x PCF8574
The library allows to read and write both single pins or 8 pins at once.
Furthermore some additional functions are implemented that are
playfull but useful.
playful but useful.
## Interface
@ -34,57 +35,63 @@ playfull but useful.
the include of "pcf8574.h" to overrule the default value used with the
**begin()** call.
### Constructor
- **PCF8574(deviceAddress, TwoWire \*wire = &Wire)** Constructor with device address,
and optional the Wire interface as parameter.
- **begin(val = PCF8574_INITIAL_VALUE)** set the initial value for the pins and masks.
- **begin(sda, scl, val = PCF8574_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
- **bool begin(val = PCF8574_INITIAL_VALUE)** set the initial value for the pins and masks.
- **bool begin(sda, scl, val = PCF8574_INITIAL_VALUE)** idem, for the ESP32 where one can choose the I2C pins.
- **bool isConnected()** checks if the address set in the constructor or by **setAddress()** is visible on the I2C bus.
- **bool setAddress(const uint8_t deviceAddress)** sets the device address after construction. Can be used to switch between PCF8574 modules runtime. Note this corrupts internal buffered values, so one might need to call **read8()** and/or **write8()**. Returns true if address can be found on I2C bus.
- **uint8_t getAddress()** returns the device address.
### Read and Write
- **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
- **uint8_t read8()** reads all 8 pins at once. This one does the actual reading.
- **uint8_t read(uint8_t pin)** reads a single pin; pin = 0..7
- **uint8_t 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)
- **void write8(const uint8_t value)** writes all 8 pins at once. This one does the actual reading.
- **uint8_t write(const uint8_t pin, const uint8_t value)** writes a single pin; pin = 0..7; value is HIGH(1) or LOW (0)
- **valueOut()** returns the last written data.
### Button
- **setButtonMask(mask)**
- **readButton8()**
- **readButton8(mask)**
- **readButton(pin)**
- **void setButtonMask(const uint8_t mask)**
- **uint8_t readButton8()**
- **uint8_t readButton8(const uint8_t mask)**
- **uint8_t readButton(const uint8_t pin)**
### Special
- **toggle(pin)** toggles a single pin
- **toggleMask(mask)** toggles a selection of pins,
- **void toggle(const uint8_t pin)** toggles a single pin
- **void toggleMask(const uint8_t mask = 0xFF)** toggles a selection of pins,
if you want to invert all pins use 0xFF (default value).
- **shiftRight(n = 1)** shifts output channels n pins (default 1) pins right (e.g. leds ).
- **void shiftRight(const uint8_t 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 ).
- **void shiftLeft(const uint8_t 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.
- **void rotateRight(const uint8_t n = 1)** rotates output channels to right, moving lowest line to highest line.
- **void rotateLeft(const uint8_t n = 1)** rotates output channels to left, moving highest line to lowest line.
- **void 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)
- **int 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 |
## Operation

View File

@ -1,13 +1,16 @@
# Syntax Coloring Map for PCF8574
# Syntax Colouring Map for PCF8574
# Datatypes (KEYWORD1)
# Data types (KEYWORD1)
PCF8574 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
setAddress KEYWORD2
getAddress KEYWORD2
read8 KEYWORD2
read KEYWORD2
value KEYWORD2

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/PCF8574.git"
},
"version":"0.3.1",
"version": "0.3.2",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"

View File

@ -1,5 +1,5 @@
name=PCF8574
version=0.3.1
version=0.3.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for PCF8574 - 8 channel I2C IO expander

View File

@ -87,6 +87,20 @@ unittest(test_read)
}
unittest(test_address)
{
PCF8574 PCF(0x38);
// incorrect in test environment.
assertTrue(PCF.begin());
assertTrue(PCF.isConnected());
assertEqual(0x38, PCF.getAddress());
assertTrue(PCF.setAddress(0x20));
assertEqual(0x20, PCF.getAddress());
}
unittest_main()
// --------