From 64772d744ffab206012230dc9ebd10c2bf2d6daf Mon Sep 17 00:00:00 2001 From: Renzo Mischianti Date: Sat, 11 Apr 2020 16:40:51 +0200 Subject: [PATCH] Interrupt management --- PCF8574.cpp | 146 +++++++++++++++++++++++++++++++++------------ PCF8574.h | 8 +++ README.md | 2 +- keywords.txt | 10 +++- library.properties | 2 +- 5 files changed, 128 insertions(+), 40 deletions(-) diff --git a/PCF8574.cpp b/PCF8574.cpp index 7b4aa6d..36f816c 100644 --- a/PCF8574.cpp +++ b/PCF8574.cpp @@ -151,6 +151,34 @@ PCF8574::PCF8574(uint8_t address, uint8_t interruptPin, void (*interruptFunctio _usingInterrupt = true; }; #endif + bool encoderPins[8]; + + void PCF8574::attachInterrupt(){ + // If using interrupt set interrupt value to pin + if (_usingInterrupt){ + for (int i = 0; i < 8;i++){ + if (encoderPins[i]) PCF8574::digitalRead(i); + } +// PCF8574::digitalReadAll(); +// (*_interruptFunction)(); + + // DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); + // ::pinMode(_interruptPin, INPUT_PULLUP); + // attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); + DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); + ::pinMode(_interruptPin, INPUT_PULLUP); + ::attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); + } + + } + void PCF8574::detachInterrupt(){ + // If using interrupt set interrupt value to pin + if (_usingInterrupt){ + ::detachInterrupt(digitalPinToInterrupt(_interruptPin)); + DEBUG_PRINTLN("Detach interrupt pin"); + } + + } /** * wake up i2c controller @@ -184,15 +212,19 @@ void PCF8574::begin(){ _wire->endTransmission(); } - // If using interrupt set interrupt value to pin - if (_usingInterrupt){ +// // If using interrupt set interrupt value to pin +// if (_usingInterrupt){ +//// DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); +//// ::pinMode(_interruptPin, INPUT_PULLUP); +//// attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); // DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); // ::pinMode(_interruptPin, INPUT_PULLUP); -// attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); - DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); - ::pinMode(_interruptPin, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); - } +// ::attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); +// } + + + + PCF8574::attachInterrupt(); // inizialize last read lastReadMillis = millis(); @@ -268,9 +300,13 @@ void PCF8574::pinMode(uint8_t pin, uint8_t mode, uint8_t output_start){ } }; + void PCF8574::encoder(uint8_t pinA, uint8_t pinB){ PCF8574::pinMode(pinA, INPUT_PULLUP); PCF8574::pinMode(pinB, INPUT_PULLUP); + + encoderPins[pinA] = true; + encoderPins[pinB] = true; } byte getBit(byte n, byte position) @@ -323,43 +359,79 @@ bool PCF8574::checkProgression(byte oldValA, byte oldValB, byte newValA, byte ne return ((newValB == ((validProgression & bit(posFinded+1))>0?HIGH:LOW)) && (newValA == ((validProgression & bit(posFinded+0))>0?HIGH:LOW)) ); } -bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){ - bool changed = false; +#ifdef BASIC_ENCODER_ALGORITHM + bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){ + bool changed = false; - byte na = PCF8574::digitalRead(pinA, true); - byte nb = PCF8574::digitalRead(pinB, true); + byte na = PCF8574::digitalRead(pinA, true); + byte nb = PCF8574::digitalRead(pinB, true); - byte encoderPinALast = (encoderValues & bit(pinA))>0?HIGH:LOW; - byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; + byte encoderPinALast = (encoderValues & bit(pinA))>0?HIGH:LOW; + byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; - if ((encoderPinALast!=na || encoderPinBLast!=nb) && (encoderPinALast == LOW) && (na == HIGH)) { - bool vCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCW); - bool vCCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCCW); + if ((encoderPinALast!=na || encoderPinBLast!=nb) && (encoderPinALast == LOW) && (na == HIGH)) { + bool vCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCW); + bool vCCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCCW); - if (nb == LOW) { - // checkCW(encoderPinALast, encoderPinBLast, na, nb); - *encoderValue = *encoderValue - 1; - changed = true; - } else { - *encoderValue = *encoderValue + 1; - changed = true; - } -// if (nb == LOW && vCW) { -// // checkCW(encoderPinALast, encoderPinBLast, na, nb); -// *encoderValue = *encoderValue - 1; -// changed = true; -// } else if (vCCW) { -// *encoderValue = *encoderValue + 1; -// changed = true; -// } + if (nb == LOW) { + *encoderValue = *encoderValue - 1; + changed = true; + } else { + *encoderValue = *encoderValue + 1; + changed = true; + } - } + // if (nb == LOW && vCW) { + // // checkCW(encoderPinALast, encoderPinBLast, na, nb); + // *encoderValue = *encoderValue - 1; + // changed = true; + // } else if (vCCW) { + // *encoderValue = *encoderValue + 1; + // changed = true; + // } - encoderValues = (encoderPinALast!=na)?encoderValues ^ bit(pinA):encoderValues; - encoderValues = (encoderPinBLast!=nb)?encoderValues ^ bit(pinB):encoderValues; + } - return changed; -} + encoderValues = (encoderPinALast!=na)?encoderValues ^ bit(pinA):encoderValues; + encoderValues = (encoderPinBLast!=nb)?encoderValues ^ bit(pinB):encoderValues; + + return changed; + } +#endif +#ifdef MISCHIANTI_ENCODER_ALGORITHM + bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){ + bool changed = false; + + byte na = PCF8574::digitalRead(pinA, true); + byte nb = PCF8574::digitalRead(pinB, true); + + byte encoderPinALast = (encoderValues & bit(pinA))>0?HIGH:LOW; + byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; + + if ((encoderPinALast!=na || encoderPinBLast!=nb) && ((encoderPinALast == LOW) || encoderPinALast==encoderPinBLast) && (na == HIGH)) { + DEBUG_PRINT("TO --> "); + DEBUG_PRINT(encoderPinALast); + DEBUG_PRINT(encoderPinBLast); + DEBUG_PRINT(" - "); + DEBUG_PRINT(na); + DEBUG_PRINT(nb); + DEBUG_PRINTLN(); + + if (nb == LOW && nb!=na) { + *encoderValue = *encoderValue + 1; + changed = true; + } else if (nb==na && encoderPinALast==encoderPinBLast) { + *encoderValue = *encoderValue - 1; + changed = true; + } + } + + encoderValues = (encoderPinALast!=na)?encoderValues ^ bit(pinA):encoderValues; + encoderValues = (encoderPinBLast!=nb)?encoderValues ^ bit(pinB):encoderValues; + + return changed; + } +#endif int8_t PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB) { volatile long encoderValue = 0; diff --git a/PCF8574.h b/PCF8574.h index 73f703f..5157a45 100644 --- a/PCF8574.h +++ b/PCF8574.h @@ -48,6 +48,10 @@ // Uncomment for low memory usage this prevent use of complex DigitalInput structure and free 7byte of memory // #define PCF8574_LOW_LATENCY +// Select an algorithm to manage encoder progression +//#define BASIC_ENCODER_ALGORITHM +#define MISCHIANTI_ENCODER_ALGORITHM + // Define where debug output will be printed. #define DEBUG_PRINTER Serial @@ -112,6 +116,9 @@ public: void encoder(uint8_t pinA, uint8_t pinB); + void attachInterrupt(); + void detachInterrupt(); + void readBuffer(bool force = true); uint8_t digitalRead(uint8_t pin, bool forceReadNow = false); #ifndef PCF8574_LOW_MEMORY @@ -189,6 +196,7 @@ private: // byte validCCW = B01001011; byte validCW = B01001011; byte validCCW = B11100001; + }; #endif diff --git a/README.md b/README.md index 58de443..79fca0a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ### If you need more pins [here](https://www.mischianti.org/2019/07/22/pcf8575-i2c-16-bit-digital-i-o-expander/) you can find pcf8575 16bit version of the IC. -### Version 2.0 +### Version 2.2 Library to use i2c analog IC with arduino and esp8266. Can read and write digital value with only 2 wire (perfect for ESP-01). diff --git a/keywords.txt b/keywords.txt index cb0d7e2..3751428 100644 --- a/keywords.txt +++ b/keywords.txt @@ -14,8 +14,16 @@ PCF8574 KEYWORD1 begin KEYWORD2 pinMode KEYWORD2 +encoder KEYWORD2 -readBuffer KEYWORD2 +attachInterrupt KEYWORD2 +detachInterrupt KEYWORD2 + +readBuffer KEYWORD2 digitalRead KEYWORD2 digitalReadAll KEYWORD2 digitalWrite KEYWORD2 + +readEncoderValue KEYWORD2 +getLatency KEYWORD2 +setLatency KEYWORD2 \ No newline at end of file diff --git a/library.properties b/library.properties index 862bae6..53be8ee 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=PCF8574 library -version=2.0.0 +version=2.2.0 author=Reef maintainer=Renzo Mischianti sentence=Arduino/ESP8266 library for PCF8574