Skip to content

Commit

Permalink
Add select functions (#35)
Browse files Browse the repository at this point in the history
* add select() functions
* add example
  • Loading branch information
RobTillaart authored Jun 18, 2022
1 parent d60077e commit e130e62
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 26 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.5] - 2022-06-17

### Added
- add select(), selectN(), selectNone() and selectAll()
convenience wrappers


## [0.3.4] - 2022-04-11

### Added
- add CHANGELOG.md

### Changed

### Fixed
- **begin(int sda, int scl)** int parameters for ESP alike.
Expand Down
21 changes: 19 additions & 2 deletions PCF8574.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FILE: PCF8574.cpp
// AUTHOR: Rob Tillaart
// DATE: 02-febr-2013
// VERSION: 0.3.4
// VERSION: 0.3.5
// PURPOSE: Arduino library for PCF8574 - 8 channel I2C IO expander
// URL: https://github.com/RobTillaart/PCF8574
// http://forum.arduino.cc/index.php?topic=184800
Expand All @@ -27,7 +27,7 @@ PCF8574::PCF8574(const uint8_t deviceAddress, TwoWire *wire)
#if defined (ESP8266) || defined(ESP32)
bool PCF8574::begin(int dataPin, int clockPin, uint8_t value)
{
_wire = &Wire;
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
Expand Down Expand Up @@ -224,5 +224,22 @@ uint8_t PCF8574::readButton(const uint8_t pin)
}


void PCF8574::select(const uint8_t pin)
{
uint8_t n = 0x00;
if (pin < 8) n = 1 << pin;
write8(n);
};


void PCF8574::selectN(const uint8_t pin)
{
uint8_t n = 0xFF;
if (pin < 8) n = (2 << pin) - 1;
write8(n);
};



// -- END OF FILE --

23 changes: 13 additions & 10 deletions PCF8574.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@
// FILE: PCF8574.h
// AUTHOR: Rob Tillaart
// DATE: 02-febr-2013
// VERSION: 0.3.4
// VERSION: 0.3.5
// 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:
// see PCF8574.cpp file
//


#include "Arduino.h"
#include "Wire.h"


#define PCF8574_LIB_VERSION (F("0.3.4"))
#define PCF8574_LIB_VERSION (F("0.3.5"))

#ifndef PCF8574_INITIAL_VALUE
#define PCF8574_INITIAL_VALUE 0xFF
Expand Down Expand Up @@ -57,11 +54,11 @@ class PCF8574


//added 0.1.07/08 Septillion
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(const uint8_t mask) { _buttonMask = mask; };
uint8_t getButtonMask() { return _buttonMask; };
uint8_t readButton8() { return PCF8574::readButton8(_buttonMask); }
uint8_t readButton8(const uint8_t mask);
uint8_t readButton(const uint8_t pin);
void setButtonMask(const uint8_t mask) { _buttonMask = mask; };
uint8_t getButtonMask() { return _buttonMask; };


// rotate, shift, toggle, reverse expect all lines are output
Expand All @@ -74,6 +71,12 @@ class PCF8574
void reverse();


void select(const uint8_t pin);
void selectN(const uint8_t pin);
void selectNone() { write8(0x00); };
void selectAll() { write8(0xFF); };


int lastError();


Expand Down
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,27 @@ These chips are identical in behaviour although there are two distinct address r

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
128 + 64 = 192 IO lines. Be sure to have a well dimensioned power supply.
128 + 64 = 192 IO lines.
Be sure to have a well dimensioned power supply.

The library allows to read and write both single pins or 8 pins at once.
Furthermore some additional functions are implemented that are playful but useful.
Furthermore some additional functions are implemented that are playful and useful.


## I2C Clock

Tested on UNO with **PCF8574_performance** showed that the PCF8574 still works at 500 KHz and failed at 600 KHz.
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.

| clock speed | Read | Write | Notes |
|:-----------:|:------:|:-------:|:------------------|
| 100000 | 236 | 240 | spec datasheet |
| 200000 | 132 | 140 |
| 300000 | 104 | 108 |
| 400000 | 96 | 96 | max advised speed |
| 500000 | 92 | 92 | not recommended |
| 600000 | crash | crash |


## Interface
Expand Down Expand Up @@ -59,7 +76,7 @@ in the class this is faster than reread the pins.
- **void write8(const uint8_t value)** writes all 8 pins at once. This one does the actual writing.
- **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.
- **uint8_t valueOut()** returns the last written data.


### Button
Expand Down Expand Up @@ -90,12 +107,26 @@ Fills the higher lines with zero's.
Fills the lower lines with zero's.
- **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()** reverse the "bit pattern" of the lines, swapping pin 7 with 0, 6 with 1, 5 with 2 and 4 with 3.
- **void reverse()** reverse the "bit pattern" of the lines, swapping pin 7 with 0, 6 with 1, 5 with 2 etc.


### Select

Some convenience wrappers.

- **void select(const uint8_t pin)** sets a single pin to HIGH, all others are set to LOW.
If pin > 7 all pins are set to LOW.
Can be used to select one of n devices.
- **void selectN(const uint8_t pin)** sets pins 0..pin to HIGH, all others are set to LOW.
If pin > 7 all pins are set to LOW.
This can typical be used to implement a VU meter.
- **void selectNone()** sets all pins to LOW.
- **void selectAll()** sets all pins to HIGH.


### Misc
### Miscellaneous

- **int 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
Expand All @@ -109,13 +140,13 @@ Fills the lower lines with zero's.

## Operation

See examples
See examples.

It is advised to use pull-up or pull-down resistors so the lines have a defined state at startup.


## Future

-
-


3 changes: 1 addition & 2 deletions examples/PCF8574_performance/PCF8574_performance.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void setup()
PCF.begin();
Serial.println(PCF.isConnected());

for (long clk = 100000; clk < 500000; clk += 50000)
for (long clk = 100000; clk < 800000; clk += 100000)
{
Serial.println(clk);
Wire.setClock(clk);
Expand All @@ -49,4 +49,3 @@ void loop()


// -- END OF FILE --

19 changes: 19 additions & 0 deletions examples/PCF8574_performance/performance_0.3.5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
...\PCF8574_performance.ino
PCF8574_LIB_VERSION: 0.3.5
1
100000
Read: 236
Write: 240
200000
Read: 132
Write: 140
300000
Read: 104
Write: 108
400000
Read: 96
Write: 96
500000
Read: 92
Write: 92
600
64 changes: 64 additions & 0 deletions examples/PCF8574_select/PCF8574_select.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// FILE: PCF8574_select.ino
// AUTHOR: Rob Tillaart
// DATE: 2022-06-18
// PUPROSE: demo PCF8574 library select functions



#include "PCF8574.h"

PCF8574 PCF(0x38);

uint32_t start, stop;


void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("PCF8574_LIB_VERSION:\t");
Serial.println(PCF8574_LIB_VERSION);

PCF.begin();
Serial.println(PCF.isConnected());
Serial.println();

PCF.selectAll();
delay(1000);
PCF.selectNone();
delay(1000);

// VU meter up
for (int i = 0; i < 7; i++)
{
PCF.selectN(i);
delay(100);
}

// VU meter down
for (int i = 7; i >= 0; i--)
{
PCF.selectN(i);
delay(100);
}
}


void loop()
{
// night rider
for (int i = 0; i < 7; i++)
{
PCF.select(i);
delay(100);
}
for (int i = 7; i >= 0; i--)
{
PCF.select(i);
delay(100);
}
}


// -- END OF FILE --
8 changes: 7 additions & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ toggle KEYWORD2
toggleMask KEYWORD2
shiftRight KEYWORD2
shiftLeft KEYWORD2

rotateRight KEYWORD2
rotateLeft KEYWORD2
reverse KEYWORD2
lastError KEYWORD2

select KEYWORD2
selectN KEYWORD2
selectNone KEYWORD2
selectAll KEYWORD2


# Constants ( LITERAL1)
PCF8574_LIB_VERSION LITERAL1
PCF8574_INITIAL_VALUE LITERAL1
PCF8574_OK LITERAL1
PCF8574_PIN_ERROR LITERAL1
PCF8574_I2C_ERROR LITERAL1
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/PCF8574.git"
},
"version": "0.3.4",
"version": "0.3.5",
"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=PCF8574
version=0.3.4
version=0.3.5
author=Rob Tillaart <[email protected]>
maintainer=Rob Tillaart <[email protected]>
sentence=Arduino library for PCF8574 - 8 channel I2C IO expander
Expand Down

0 comments on commit e130e62

Please sign in to comment.