Skip to content

Commit

Permalink
update documentation (#30)
Browse files Browse the repository at this point in the history
* fix #9 documentation 
* add getButtonMask()
* refactor examples a bit
  • Loading branch information
RobTillaart authored Nov 30, 2021
1 parent 767140a commit 8f67e26
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 51 deletions.
5 changes: 3 additions & 2 deletions PCF8574.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
// 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.3.0 2021-01-03 multiWire support - inspired by mattbue - issue #14
// 0.2.4 2020-12-17 fix #6 tag problem 0.2.3
// 0.2.3 2020-12-14 fix #6 readButton8 ambiguity
// 0.2.2 2020-12-07 add Arduino-ci + start unit test + _wire->h in PCF8574.h
Expand All @@ -36,7 +37,7 @@
// 0.1.05 2016-04-30 refactor, +toggleMask, +rotLeft, +rotRight
// 0.1.04 2015-05-09 removed ambiguity in read8()
// 0.1.03 2015-03-02 address int -> uint8_t
// 0.1.02 replaced ints with uint8_t to reduce footprint;
// 0.1.02 replaced integers with uint8_t to reduce footprint;
// added default value for shiftLeft() and shiftRight()
// renamed status() to lastError();
// 0.1.01 added value(); returns last read 8 bit value (cached);
Expand Down
8 changes: 8 additions & 0 deletions PCF8574.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,30 @@ class PCF8574
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(const 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);
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);
uint8_t readButton(const uint8_t pin);
inline void setButtonMask(const uint8_t mask) { _buttonMask = mask; };
uint8_t getButtonMask() { return _buttonMask; };


// rotate, shift, toggle, reverse expect all lines are output
void toggle(const uint8_t pin);
Expand All @@ -67,8 +73,10 @@ class PCF8574
void rotateLeft(const uint8_t n = 1);
void reverse();


int lastError();


private:
uint8_t _address;
uint8_t _dataIn;
Expand Down
46 changes: 30 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Arduino library for PCF8574 - 8 channel I2C IO expander
Related to the PCF8575 16 channel IO expander library https://github.com/RobTillaart/PCF8575

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.
These chips are identical in behaviour although there are two distinct address ranges.

| TYPE | ADDRESS-RANGE | notes |
|:---------|:-------------:|:------------------------:|
Expand All @@ -28,15 +28,13 @@ to 16 x 8 = 128 IO lines. To maximize IO lines combine 8 x PCF8575 + 8 x PCF8574
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 but useful.


## Interface

**PCF8574_INITIAL_VALUE** is a define that can be set compile time or before
the include of "pcf8574.h" to overrule the default value used with the
**begin()** call.
the include of "pcf8574.h" to overrule the default value used with the **begin()** call.


### Constructor
Expand All @@ -46,7 +44,9 @@ and optional the Wire interface as parameter.
- **bool begin(uint8_t val = PCF8574_INITIAL_VALUE)** set the initial value for the pins and masks.
- **bool begin(uint8_t sda, uint8_t scl, uint8_t 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.
- **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.


Expand All @@ -56,31 +56,41 @@ and optional the Wire interface as parameter.
- **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.
- **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)
- **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.


### Button

- **void setButtonMask(const uint8_t mask)**
- **uint8_t readButton8()**
- **uint8_t readButton8(const uint8_t mask)**
- **uint8_t readButton(const uint8_t pin)**
The **"button"** functions are to be used when you mix input and output on one IC.
It does not change / affect the pins used for output by masking these.
Typical usage is to call **setButtonMask()** once in setup as pins do not (often) change
during program execution.

- **void setButtonMask(const uint8_t mask)** sets the (bit) mask which lines are input.
- **uint8_t getButtonMask()** returns the set buttonMask.
- **uint8_t readButton8()** use the mask set by setButtonMask to select specific input pins.
- **uint8_t readButton8(const uint8_t mask)** use a specific mask to select specific input pins.
Note this can be a subset of the pins set with **setButtonMask()** if one wants to process not all.
- **uint8_t readButton(const uint8_t pin)** read a singe input pin.

Background - https://github.com/RobTillaart/Arduino/issues/38


### Special

- **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).
- **void shiftRight(const uint8_t 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.
- **void shiftLeft(const uint8_t 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.
- **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, high to low and vice versa.
- **void reverse()** reverse the "bit pattern" of the lines, swapping pin 7 with 0, 6 with 1, 5 with 2 and 4 with 3.


### Misc
Expand All @@ -101,7 +111,11 @@ Fills the lower lines with zero's.

See examples

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


## Future

-
- update documentation
- link to related libraries.

8 changes: 7 additions & 1 deletion examples/PCF8574_Wire2/PCF8574_Wire2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
// FILE: PCF8574_Wire2.ino
// AUTHOR: Rob Tillaart
// DATE: 2016-04-30
//
// PUPROSE: demo
//


#include "PCF8574.h"

// adjust addresses if needed
PCF8574 PCF(0x39, &Wire2);


void setup()
{
Serial.begin(115200);
Expand All @@ -34,6 +35,7 @@ void setup()
delay(1000);
}


void loop()
{
Serial.println("HLT");
Expand All @@ -46,6 +48,7 @@ void loop()
}
}


void doHigh()
{
PCF.write(4, HIGH);
Expand All @@ -54,6 +57,7 @@ void doHigh()
Serial.println(x, HEX);
}


void doLow()
{
PCF.write(4, LOW);
Expand All @@ -62,6 +66,7 @@ void doLow()
Serial.println(x, HEX);
}


void doToggle()
{
PCF.toggle(4);
Expand All @@ -72,3 +77,4 @@ void doToggle()


// -- END OF FILE --

6 changes: 5 additions & 1 deletion examples/PCF8574_interrupt/PCF8574_interrupt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
// Place a pull up resistor 4K7 between pin and 5V
// Place a capacitor 10-400pF between pin and GND


#include "PCF8574.h"

PCF8574 PCF(0x38);


////////////////////////////////////
//
// INTERRUPT ROUTINE + FLAG
Expand Down Expand Up @@ -47,6 +49,7 @@ void setup()
attachInterrupt(digitalPinToInterrupt(IRQPIN), pcf_irq, FALLING);
}


void loop()
{
uint32_t now = millis();
Expand All @@ -60,8 +63,9 @@ void loop()
Serial.print('\t');
Serial.println(x, HEX);
}
// do other things here
// do other things here
delay(10);
}


// -- END OF FILE --
7 changes: 5 additions & 2 deletions examples/PCF8574_isConnected/PCF8574_isConnected.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
// FILE: PCF8574_isConnected.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-01-03
// PUPROSE: demo isConnected function
//
// PUPROSE: demo
//


#include "PCF8574.h"

// adjust addresses if needed
PCF8574 PCF_39(0x39);


void setup()
{
Serial.begin(115200);
Expand All @@ -32,8 +33,10 @@ void setup()
}
}


void loop()
{
}


// -- END OF FILE --
12 changes: 8 additions & 4 deletions examples/PCF8574_performance/PCF8574_performance.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
// FILE: PCF8574_performance.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-01-24
//
// PUPROSE: test PCF8574 library
// PUPROSE: test PCF8574 library at different I2C speeds.


#include "PCF8574.h"

PCF8574 PCF(0x38);

uint32_t start, stop;


void setup()
{
Serial.begin(115200);
Expand Down Expand Up @@ -39,10 +40,13 @@ void setup()
Serial.println(stop - start);
delay(1000);
}

}


void loop()
{

}


// -- END OF FILE --

5 changes: 4 additions & 1 deletion examples/PCF8574_rotaryEncoder/PCF8574_rotaryEncoder.ino
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ uint8_t lastpos[4] = {0, 0, 0, 0};
int32_t encoder[4] = {0, 0, 0, 0};
volatile bool flag = false;


// IRQ routine
void moved()
{
flag = true;
Expand All @@ -50,7 +52,8 @@ void setup()
Wire.begin();
if (decoder.begin() == false)
{
Serial.println("\nERROR: cannot communicate to keypad.\nPlease reboot / adjust address.\n");
Serial.println("\nERROR: cannot communicate to PCF8574.");
Serial.println("Please reboot / adjust address.\n");
while (1);
}
Wire.setClock(600000);
Expand Down
11 changes: 10 additions & 1 deletion examples/PCF8574_test/PCF8574_test.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
// FILE: PCF8574_test.ino
// AUTHOR: Rob Tillaart
// DATE: 7-febr-2013
//
// PUPROSE: test PCF8574 library
//


#include "PCF8574.h"

PCF8574 PCF_01(0x38);


void setup()
{
Serial.begin(115200);
Expand All @@ -26,6 +27,7 @@ void setup()
delay(1000);
}


void loop()
{
Serial.println("HLT");
Expand All @@ -38,6 +40,7 @@ void loop()
}
}


void doHigh()
{
PCF_01.write(4, HIGH);
Expand All @@ -46,6 +49,7 @@ void doHigh()
Serial.println(x, HEX);
}


void doLow()
{
PCF_01.write(4, LOW);
Expand All @@ -54,10 +58,15 @@ void doLow()
Serial.println(x, HEX);
}


void doToggle()
{
PCF_01.toggle(4);
int x = PCF_01.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


// -- END OF FILE --

Loading

0 comments on commit 8f67e26

Please sign in to comment.