Interrupt management

This commit is contained in:
Renzo Mischianti 2020-04-11 16:40:51 +02:00
parent c3b5ad65a1
commit 64772d744f
5 changed files with 128 additions and 40 deletions

View File

@ -151,6 +151,34 @@ PCF8574::PCF8574(uint8_t address, uint8_t interruptPin, void (*interruptFunctio
_usingInterrupt = true; _usingInterrupt = true;
}; };
#endif #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 * wake up i2c controller
@ -184,15 +212,19 @@ void PCF8574::begin(){
_wire->endTransmission(); _wire->endTransmission();
} }
// If using interrupt set interrupt value to pin // // If using interrupt set interrupt value to pin
if (_usingInterrupt){ // 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)"); // DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)");
// ::pinMode(_interruptPin, INPUT_PULLUP); // ::pinMode(_interruptPin, INPUT_PULLUP);
// attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING ); // ::attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING );
DEBUG_PRINTLN("Using interrupt pin (not all pin is interrupted)"); // }
::pinMode(_interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(_interruptPin), (*_interruptFunction), FALLING );
}
PCF8574::attachInterrupt();
// inizialize last read // inizialize last read
lastReadMillis = millis(); 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){ void PCF8574::encoder(uint8_t pinA, uint8_t pinB){
PCF8574::pinMode(pinA, INPUT_PULLUP); PCF8574::pinMode(pinA, INPUT_PULLUP);
PCF8574::pinMode(pinB, INPUT_PULLUP); PCF8574::pinMode(pinB, INPUT_PULLUP);
encoderPins[pinA] = true;
encoderPins[pinB] = true;
} }
byte getBit(byte n, byte position) 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)) ); 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){ #ifdef BASIC_ENCODER_ALGORITHM
bool changed = false; bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){
bool changed = false;
byte na = PCF8574::digitalRead(pinA, true); byte na = PCF8574::digitalRead(pinA, true);
byte nb = PCF8574::digitalRead(pinB, true); byte nb = PCF8574::digitalRead(pinB, true);
byte encoderPinALast = (encoderValues & bit(pinA))>0?HIGH:LOW; byte encoderPinALast = (encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW;
if ((encoderPinALast!=na || encoderPinBLast!=nb) && (encoderPinALast == LOW) && (na == HIGH)) { if ((encoderPinALast!=na || encoderPinBLast!=nb) && (encoderPinALast == LOW) && (na == HIGH)) {
bool vCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCW); bool vCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCW);
bool vCCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCCW); bool vCCW = checkProgression(encoderPinALast, encoderPinBLast, na, nb, validCCW);
if (nb == LOW) { if (nb == LOW) {
// checkCW(encoderPinALast, encoderPinBLast, na, nb); *encoderValue = *encoderValue - 1;
*encoderValue = *encoderValue - 1; changed = true;
changed = true; } else {
} else { *encoderValue = *encoderValue + 1;
*encoderValue = *encoderValue + 1; changed = true;
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 && 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) { int8_t PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0; volatile long encoderValue = 0;

View File

@ -48,6 +48,10 @@
// Uncomment for low memory usage this prevent use of complex DigitalInput structure and free 7byte of memory // Uncomment for low memory usage this prevent use of complex DigitalInput structure and free 7byte of memory
// #define PCF8574_LOW_LATENCY // #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 where debug output will be printed.
#define DEBUG_PRINTER Serial #define DEBUG_PRINTER Serial
@ -112,6 +116,9 @@ public:
void encoder(uint8_t pinA, uint8_t pinB); void encoder(uint8_t pinA, uint8_t pinB);
void attachInterrupt();
void detachInterrupt();
void readBuffer(bool force = true); void readBuffer(bool force = true);
uint8_t digitalRead(uint8_t pin, bool forceReadNow = false); uint8_t digitalRead(uint8_t pin, bool forceReadNow = false);
#ifndef PCF8574_LOW_MEMORY #ifndef PCF8574_LOW_MEMORY
@ -189,6 +196,7 @@ private:
// byte validCCW = B01001011; // byte validCCW = B01001011;
byte validCW = B01001011; byte validCW = B01001011;
byte validCCW = B11100001; byte validCCW = B11100001;
}; };
#endif #endif

View File

@ -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. ### 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). Library to use i2c analog IC with arduino and esp8266. Can read and write digital value with only 2 wire (perfect for ESP-01).

View File

@ -14,8 +14,16 @@ PCF8574 KEYWORD1
begin KEYWORD2 begin KEYWORD2
pinMode KEYWORD2 pinMode KEYWORD2
encoder KEYWORD2
readBuffer KEYWORD2 attachInterrupt KEYWORD2
detachInterrupt KEYWORD2
readBuffer KEYWORD2
digitalRead KEYWORD2 digitalRead KEYWORD2
digitalReadAll KEYWORD2 digitalReadAll KEYWORD2
digitalWrite KEYWORD2 digitalWrite KEYWORD2
readEncoderValue KEYWORD2
getLatency KEYWORD2
setLatency KEYWORD2

View File

@ -1,5 +1,5 @@
name=PCF8574 library name=PCF8574 library
version=2.0.0 version=2.2.0
author=Reef author=Reef
maintainer=Renzo Mischianti <renzo.mischianti@gmail.com> maintainer=Renzo Mischianti <renzo.mischianti@gmail.com>
sentence=Arduino/ESP8266 library for PCF8574 sentence=Arduino/ESP8266 library for PCF8574