Skip to content

Commit

Permalink
Develop (#11)
Browse files Browse the repository at this point in the history
* fix #10 add get/setAddress()
  • Loading branch information
RobTillaart authored Jul 9, 2021
1 parent e78a6bc commit 7dad68a
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 24 deletions.
44 changes: 38 additions & 6 deletions PCF8575.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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)
{
Expand All @@ -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)
Expand All @@ -69,6 +87,7 @@ uint16_t PCF8575::read16()
return _dataIn;
}


void PCF8575::write16(const uint16_t value)
{
_dataOut = value;
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -139,13 +164,15 @@ void PCF8575::shiftLeft(const uint8_t n)
PCF8575::write16(_dataOut);
}


int PCF8575::lastError()
{
int e = _error;
_error = PCF8575_OK; // reset error after read, is this wise?
return e;
}


void PCF8575::rotateRight(const uint8_t n)
{
uint8_t r = n & 15;
Expand All @@ -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
Expand All @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -194,4 +225,5 @@ uint8_t PCF8575::readButton(const uint8_t pin)
return rtn;
}


// -- END OF FILE --
19 changes: 17 additions & 2 deletions PCF8575.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
// 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
//
// HISTORY:
// 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
Expand All @@ -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()
Expand All @@ -60,6 +73,7 @@ class PCF8575
void rotateLeft(const uint8_t n = 1);
void reverse();


int lastError();

private:
Expand All @@ -72,4 +86,5 @@ class PCF8575
TwoWire* _wire;
};


// -- END OF FILE --
39 changes: 27 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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

Expand All @@ -63,13 +73,15 @@ 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)**
- **readButton16()**
- **readButton16(mask)**
- **readButton(pin)**


### Special

- **toggle(pin)** toggles a single pin
Expand All @@ -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

Expand Down
6 changes: 4 additions & 2 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "*"
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=PCF8575
version=0.1.1
version=0.1.2
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for PCF8575 - 16 channel I2C IO expander
Expand Down

0 comments on commit 7dad68a

Please sign in to comment.