Skip to content

Commit

Permalink
Update readme.md (interrupts) + examples (#49)
Browse files Browse the repository at this point in the history
- Update readme with advanced interrupts insights
  - kudos to ddowling for testing.
  - add example
- fix URL examples
- add Wire1 example (ESP32 + RP2040)
  • Loading branch information
RobTillaart authored Jan 8, 2024
1 parent b89253b commit bb15c05
Show file tree
Hide file tree
Showing 22 changed files with 465 additions and 176 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.4.1] - 2023-09-23
- Update readme with advanced interrupts insights
- kudos to ddowling for testing.
- add example
- fix URL examples
- add Wire1 example (ESP32 + RP2040)


## [0.4.0] - 2023-09-23
- refactor API, begin()
- update readme.md
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2013-2023 Rob Tillaart
Copyright (c) 2013-2024 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion 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.4.0
// VERSION: 0.4.1
// 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 Down
6 changes: 3 additions & 3 deletions PCF8574.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// FILE: PCF8574.h
// AUTHOR: Rob Tillaart
// DATE: 02-febr-2013
// VERSION: 0.4.0
// VERSION: 0.4.1
// 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 @@ -13,7 +13,7 @@
#include "Wire.h"


#define PCF8574_LIB_VERSION (F("0.4.0"))
#define PCF8574_LIB_VERSION (F("0.4.1"))

#ifndef PCF8574_INITIAL_VALUE
#define PCF8574_INITIAL_VALUE 0xFF
Expand Down Expand Up @@ -50,7 +50,7 @@ class PCF8574


// added 0.1.07/08 Septillion
uint8_t readButton8() { return PCF8574::readButton8(_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; };
Expand Down
51 changes: 44 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# PCF8574

Arduino library for PCF8574 - 8 channel I2C IO expander
Arduino library for PCF8574 - 8 channel I2C IO expander.


## Description
Expand All @@ -36,17 +36,52 @@ The library allows to read and write both single pins or 8 pins at once.
Furthermore some additional functions are implemented that are playful and useful.


#### Interrupts
#### Interrupts intro

The PCF8574 has an interrupt output line (INT) to notify an MCU that one of the input lines has changed.
This can be used to prevent active polling of the PCF8574, which can be more efficient.

From the datasheet:

_An interrupt is generated by any rising or falling edge of the port inputs in the input mode.
After time, (Tiv), INT is valid. Resetting and reactivating the interrupt circuit is achieved
when data on the port is **changed to the original setting** or data is **read from**, or
**written to**, the port that generated the interrupt.
Resetting occurs in the read mode at the acknowledge bit after the rising edge of the SCL signal,
or in the write mode at the acknowledge bit after the high-to-low transition of the SCL signal._

So there are three scenarios how the INT is reset.

1. pins revert to original state (lesser known).
2. read from the device (well known)
3. write to the device (well known)

This implies that polling the PCF8574 can miss an INT in scenario 1. (see #48)
In practice if you have faster polling than your signals changes this would not
be a problem. E.g. tactile switches and a polling frequency > 100 Hz will work.


#### Interrupts library

The library cannot handle the PCF8574 interrupts as it has no code for it.
The user should catch the interrupt in his own code and can use the library to see which line has changed.
The user should catch the interrupt in his own code to set a flag and can use
the library to see which line has changed.

There are two examples to show how interrupts can be used:
- PCF8574_interrupt.ino
- PCF8574_rotaryEncoder.ino
There are two examples to show how interrupts can be handled:

- **PCF8574_interrupt.ino**
- **PCF8574_rotaryEncoder.ino**

A more advanced interrupt handler would not set a boolean flag in the interrupt
routine but increase a counter (uint8_t or larger).
Then it would be possible to see that:

1. an interrupt occurred. (counter > 0)
2. if one or more interrupts are not handled (counter > 1)

A minimal example that shows catching missed interrupts:

- **PCF8574_interrupt_advanced.ino**


#### 0.4.0 Breaking change
Expand Down Expand Up @@ -194,7 +229,8 @@ It is advised to use pull-up or pull-down resistors so the lines have a defined

#### Must

- keep in sync with PCF8575
- update documentation.
- keep in sync with PCF8575 (as far as meaningful)

#### Should

Expand All @@ -214,3 +250,4 @@ donate through PayPal or GitHub sponsors.

Thank you,


27 changes: 27 additions & 0 deletions examples/PCF8574_Wire1/.arduino-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:

packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# - uno
# - due
# - zero
# - leonardo
# - m4
- esp32
# - esp8266
# - mega2560
- rpipico
81 changes: 81 additions & 0 deletions examples/PCF8574_Wire1/PCF8574_Wire1.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// FILE: PCF8574_Wire1.ino
// AUTHOR: Rob Tillaart
// DATE: 2016-04-30
// PURPOSE: demo
// URL: https://github.com/RobTillaart/PCF8574


#include "PCF8574.h"

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


void doHigh()
{
PCF.write(4, HIGH);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


void doLow()
{
PCF.write(4, LOW);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


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


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

Wire1.begin();

if (!PCF.begin())
{
Serial.println("could not initialize...");
}
if (!PCF.isConnected())
{
Serial.println("=> not connected");
while(1);
}

int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
delay(1000);
}


void loop()
{
Serial.println("HLT");
while (Serial.available() == 0);
switch (Serial.read())
{
case 'H': doHigh(); break;
case 'L': doLow(); break;
case 'T': doToggle(); break;
}
}


// -- END OF FILE --
24 changes: 21 additions & 3 deletions examples/PCF8574_Wire2/.arduino-ci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:

packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# example made for Teensy a.o.
#
# - uno
# - leonardo
# - due
# - zero
# - leonardo
# - m4
# - esp32
# - esp8266
# - mega2560
# - rpipico
60 changes: 30 additions & 30 deletions examples/PCF8574_Wire2/PCF8574_Wire2.ino
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
//
//
// FILE: PCF8574_Wire2.ino
// AUTHOR: Rob Tillaart
// DATE: 2016-04-30
// PURPOSE: demo
// URL: https://github.com/RobTillaart/PCF8574


#include "PCF8574.h"

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


void doHigh()
{
PCF.write(4, HIGH);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


void doLow()
{
PCF.write(4, LOW);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


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


void setup()
Expand Down Expand Up @@ -50,32 +78,4 @@ void loop()
}


void doHigh()
{
PCF.write(4, HIGH);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


void doLow()
{
PCF.write(4, LOW);
int x = PCF.read8();
Serial.print("Read ");
Serial.println(x, HEX);
}


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


// -- END OF FILE --

1 change: 1 addition & 0 deletions examples/PCF8574_interrupt/PCF8574_interrupt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// AUTHOR: Rob Tillaart
// DATE: 2020-12-07
// PURPOSE: test PCF8574 library
// URL: https://github.com/RobTillaart/PCF8574
//
// TEST SETUP
// Connect INT pin of the PCF8574 to UNO pin 2
Expand Down
Loading

0 comments on commit bb15c05

Please sign in to comment.