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;
};
#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,7 +359,8 @@ 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){
#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);
@ -337,21 +374,21 @@ bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encode
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 && vCW) {
// // checkCW(encoderPinALast, encoderPinBLast, na, nb);
// *encoderValue = *encoderValue - 1;
// changed = true;
// } else if (vCCW) {
// *encoderValue = *encoderValue + 1;
// changed = true;
// }
}
@ -359,7 +396,42 @@ bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encode
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;

View File

@ -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

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.
### 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).

View File

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

View File

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