volatile variable fix and multiple algorithm for encoder

This commit is contained in:
Renzo Mischianti 2020-11-23 22:39:24 +01:00
parent d3503ed393
commit 668fdcad25
6 changed files with 342 additions and 3638 deletions

File diff suppressed because it is too large Load Diff

View File

@ -369,24 +369,35 @@ bool PCF8574::checkProgression(byte oldValA, byte oldValB, byte newValA, byte ne
} }
#ifdef BASIC_ENCODER_ALGORITHM #ifdef BASIC_ENCODER_ALGORITHM
bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){ bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
PCF8574::detachInterrupt();
bool changed = false; 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 = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
DEBUG_PRINT(pinA);
DEBUG_PRINT(" TO --> ");
DEBUG_PRINT(encoderPinALast);
DEBUG_PRINT(encoderPinBLast);
DEBUG_PRINT(" - ");
DEBUG_PRINT(na);
DEBUG_PRINT(nb);
DEBUG_PRINTLN();
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) {
*encoderValue = *encoderValue - 1; *encoderValue = *encoderValue + (!reverseRotation?+1:-1);
changed = true; changed = true;
} else { } else {
*encoderValue = *encoderValue + 1; *encoderValue = *encoderValue + (!reverseRotation?-1:+1);
changed = true; changed = true;
} }
@ -401,21 +412,166 @@ bool PCF8574::checkProgression(byte oldValA, byte oldValB, byte newValA, byte ne
} }
encoderValues = (encoderPinALast!=na)?encoderValues ^ bit(pinA):encoderValues; this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):this->encoderValues;
encoderValues = (encoderPinBLast!=nb)?encoderValues ^ bit(pinB):encoderValues; this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):this->encoderValues;
PCF8574::attachInterrupt();
return changed; return changed;
} }
int8_t PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0;
PCF8574::readEncoderValue(pinA, pinB, &encoderValue);
return encoderValue;
}
#endif
#ifdef SEQUENCE_ENCODER_ALGORITHM
bool PCF8574::readEncoderValueSequence(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
PCF8574::detachInterrupt();
bool changed = false;
delay(100);
byte na = PCF8574::digitalRead(pinA, true);
byte nb = PCF8574::digitalRead(pinB, true);
byte encoderPinALast = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
DEBUG_PRINT(pinA);
DEBUG_PRINT(" TO --> ");
DEBUG_PRINT(encoderPinALast);
DEBUG_PRINT(encoderPinBLast);
DEBUG_PRINT(" - ");
DEBUG_PRINT(na);
DEBUG_PRINT(nb);
DEBUG_PRINT(" -- ");
int encoded = (na << 1) | nb; //converting the 2 pin value to single number
int lastEncoded = (encoderPinALast << 1) | encoderPinBLast;
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
DEBUG_PRINT("sum - ");
DEBUG_PRINT(sum, BIN);
DEBUG_PRINT(" enc - ");
DEBUG_PRINT( *encoderValue);
if(
sum == 0b1101
|| sum == 0b0100
|| sum == 0b0010
|| sum == 0b1011
){
// encoderValue ++;
*encoderValue = *encoderValue + (!reverseRotation?+1:-1);
changed = true;
}
if(
sum == 0b1110
|| sum == 0b0111
|| sum == 0b0001
|| sum == 0b1000
) {
*encoderValue = *encoderValue + (!reverseRotation?-1:+1);
changed = true;
// encoderValue --;
}
DEBUG_PRINT(" enc next - ");
DEBUG_PRINTLN( *encoderValue);
this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):this->encoderValues;
this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):this->encoderValues;
PCF8574::attachInterrupt();
return changed;
}
int8_t PCF8574::readEncoderValueSequence(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0;
PCF8574::readEncoderValueSequence(pinA, pinB, &encoderValue);
return encoderValue;
}
#endif
#ifdef SEQUENCE_ENCODER_ALGORITHM_REDUCED
bool PCF8574::readEncoderValueSequenceReduced(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
PCF8574::detachInterrupt();
bool changed = false;
delay(100);
byte na = PCF8574::digitalRead(pinA, true);
byte nb = PCF8574::digitalRead(pinB, true);
byte encoderPinALast = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
DEBUG_PRINT(pinA);
DEBUG_PRINT(" TO --> ");
DEBUG_PRINT(encoderPinALast);
DEBUG_PRINT(encoderPinBLast);
DEBUG_PRINT(" - ");
DEBUG_PRINT(na);
DEBUG_PRINT(nb);
DEBUG_PRINT(" -- ");
int encoded = (na << 1) | nb; //converting the 2 pin value to single number
int lastEncoded = (encoderPinALast << 1) | encoderPinBLast;
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
DEBUG_PRINT("sum - ");
DEBUG_PRINT(sum, BIN);
DEBUG_PRINT(" enc - ");
DEBUG_PRINT( *encoderValue);
if(
sum == 0b1101
// || sum == 0b0100
|| sum == 0b0010
// || sum == 0b1011
){
// encoderValue ++;
*encoderValue = *encoderValue + (!reverseRotation?+1:-1);
changed = true;
}
if(
sum == 0b1110
// || sum == 0b0111
|| sum == 0b0001
// || sum == 0b1000
) {
*encoderValue = *encoderValue + (!reverseRotation?-1:+1);
changed = true;
// encoderValue --;
}
DEBUG_PRINT(" enc next - ");
DEBUG_PRINTLN( *encoderValue);
this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):this->encoderValues;
this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):this->encoderValues;
PCF8574::attachInterrupt();
return changed;
}
int8_t PCF8574::readEncoderValueSequenceReduced(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0;
PCF8574::readEncoderValueSequenceReduced(pinA, pinB, &encoderValue);
return encoderValue;
}
#endif #endif
#ifdef MISCHIANTI_ENCODER_ALGORITHM #ifdef MISCHIANTI_ENCODER_ALGORITHM
bool PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue){ bool PCF8574::readEncoderValueMischianti(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
PCF8574::detachInterrupt();
bool changed = false; 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 = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (encoderValues & bit(pinB))>0?HIGH:LOW; byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
if ((encoderPinALast!=na || encoderPinBLast!=nb) && ((encoderPinALast == LOW) || encoderPinALast==encoderPinBLast) && (na == HIGH)) { if ((encoderPinALast!=na || encoderPinBLast!=nb) && ((encoderPinALast == LOW) || encoderPinALast==encoderPinBLast) && (na == HIGH)) {
DEBUG_PRINT("TO --> "); DEBUG_PRINT("TO --> ");
@ -427,27 +583,157 @@ bool PCF8574::checkProgression(byte oldValA, byte oldValB, byte newValA, byte ne
DEBUG_PRINTLN(); DEBUG_PRINTLN();
if (nb == LOW && nb!=na) { if (nb == LOW && nb!=na) {
*encoderValue = *encoderValue + 1; *encoderValue = *encoderValue + (!reverseRotation?+1:-1);
changed = true; changed = true;
} else if (nb==na && encoderPinALast==encoderPinBLast) { } else if (nb==na && encoderPinALast==encoderPinBLast) {
*encoderValue = *encoderValue - 1; *encoderValue = *encoderValue + (!reverseRotation?-1:+1);
changed = true;
}
}
// encoderValues = encoderValues & (~(bit(pinA) | bit(pinB)));
// if (na == HIGH){
// encoderValues = encoderValues | bit(pinA);
// }
// if (nb == HIGH){
// encoderValues = encoderValues | bit(pinA);
// }
if (encoderPinALast!=na || encoderPinBLast!=nb){
this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):this->encoderValues;
this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):this->encoderValues;
}
PCF8574::attachInterrupt();
return changed;
}
int8_t PCF8574::readEncoderValueMischianti(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0;
PCF8574::readEncoderValueMischianti(pinA, pinB, &encoderValue);
return encoderValue;
}
#endif
//#ifdef MISCHIANTI_ENCODER_ALGORITHM_EVOLVED
// bool PCF8574::readEncoderValueEvolved(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
// PCF8574::detachInterrupt();
// bool changed = false;
//
// byte na = PCF8574::digitalRead(pinA, true);
// byte nb = PCF8574::digitalRead(pinB, true);
//
// byte encoderPinALast = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
// byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
//
//// Serial.print(pinA);
//// Serial.print(" TO --> ");
//// Serial.print(encoderPinALast);
//// Serial.print(encoderPinBLast);
//// Serial.print(" - ");
//// Serial.print(na);
//// Serial.print(nb);
//
// if (
//
// ((encoderPinALast!=na || encoderPinBLast!=nb) && ((encoderPinALast == LOW) || encoderPinALast==encoderPinBLast) && (na == HIGH))
// || ((encoderPinALast!=na || encoderPinBLast!=nb) && ((encoderPinALast == HIGH) || encoderPinALast==encoderPinBLast) && (na == LOW))
// ){
// DEBUG_PRINT("TO --> ");
// DEBUG_PRINT(encoderPinALast);
// DEBUG_PRINT(encoderPinBLast);
// DEBUG_PRINT(" - ");
// DEBUG_PRINT(na);
// DEBUG_PRINT(nb);
// DEBUG_PRINTLN();
//
//// Serial.print (" <------ ");
//
// if (nb == LOW && nb!=na) {
// *encoderValue = *encoderValue + (!reverseRotation?+1:-1);
// changed = true;
// } else if (nb==na && encoderPinALast==encoderPinBLast) {
// *encoderValue = *encoderValue + (!reverseRotation?-1:+1);
// changed = true;
// }
// }
//// Serial.println();
//// encoderValues = encoderValues & (~(bit(pinA) | bit(pinB)));
//// if (na == HIGH){
//// encoderValues = encoderValues | bit(pinA);
//// }
//// if (nb == HIGH){
//// encoderValues = encoderValues | bit(pinA);
//// }
//
// if (encoderPinALast!=na || encoderPinBLast!=nb){
// this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):this->encoderValues;
// this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):this->encoderValues;
// }
//
// PCF8574::attachInterrupt();
// return changed;
// }
// int8_t PCF8574::readEncoderValueEvolved(uint8_t pinA, uint8_t pinB) {
// volatile long encoderValue = 0;
// PCF8574::readEncoderValueEvolved(pinA, pinB, &encoderValue);
// return encoderValue;
// }
//
//#endif
#ifdef POKI_ENCODER_ALGORITHM
bool PCF8574::readEncoderValuePoki(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation){
PCF8574::detachInterrupt();
bool changed = false;
byte na = PCF8574::digitalRead(pinA, true);
byte nb = PCF8574::digitalRead(pinB, true);
byte encoderPinALast = (this->encoderValues & bit(pinA))>0?HIGH:LOW;
byte encoderPinBLast = (this->encoderValues & bit(pinB))>0?HIGH:LOW;
DEBUG_PRINT("TO --> ");
DEBUG_PRINT(encoderPinALast);
DEBUG_PRINT(encoderPinBLast);
DEBUG_PRINT(" - ");
DEBUG_PRINT(na);
DEBUG_PRINT(nb);
DEBUG_PRINTLN();
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 (na && !nb) {
if (encoderPinBLast) {
*encoderValue = *encoderValue + (!reverseRotation?+1:-1);
} else {
*encoderValue = *encoderValue + (!reverseRotation?-1:+1);
}
changed = true; changed = true;
} }
} }
encoderValues = (encoderPinALast!=na)?encoderValues ^ bit(pinA):encoderValues; this->encoderValues = (encoderPinALast!=na)?this->encoderValues ^ bit(pinA):encoderValues;
encoderValues = (encoderPinBLast!=nb)?encoderValues ^ bit(pinB):encoderValues; this->encoderValues = (encoderPinBLast!=nb)?this->encoderValues ^ bit(pinB):encoderValues;
PCF8574::attachInterrupt();
return changed; return changed;
} }
#endif int8_t PCF8574::readEncoderValuePoki(uint8_t pinA, uint8_t pinB) {
int8_t PCF8574::readEncoderValue(uint8_t pinA, uint8_t pinB) {
volatile long encoderValue = 0; volatile long encoderValue = 0;
PCF8574::readEncoderValue(pinA, pinB, &encoderValue); PCF8574::readEncoderValue(pinA, pinB, &encoderValue);
return encoderValue; return encoderValue;
} }
#endif
/** /**
* Read value from i2c and bufferize it * Read value from i2c and bufferize it
* @param force * @param force

View File

@ -2,7 +2,7 @@
* PCF8574 GPIO Port Expand * PCF8574 GPIO Port Expand
* *
* AUTHOR: Renzo Mischianti * AUTHOR: Renzo Mischianti
* VERSION: 2.2.0 * VERSION: 2.2.2
* *
* https://www.mischianti.org/2019/01/02/pcf8574-i2c-digital-i-o-expander-fast-easy-usage/ * https://www.mischianti.org/2019/01/02/pcf8574-i2c-digital-i-o-expander-fast-easy-usage/
* *
@ -58,8 +58,11 @@
//#define PCF8574_SOFT_INITIALIZATION //#define PCF8574_SOFT_INITIALIZATION
// Select an algorithm to manage encoder progression // Select an algorithm to manage encoder progression
//#define BASIC_ENCODER_ALGORITHM #define BASIC_ENCODER_ALGORITHM
#define MISCHIANTI_ENCODER_ALGORITHM // #define MISCHIANTI_ENCODER_ALGORITHM
// #define SEQUENCE_ENCODER_ALGORITHM_REDUCED
// #define SEQUENCE_ENCODER_ALGORITHM
// #define POKI_ENCODER_ALGORITHM
// Define where debug output will be printed. // Define where debug output will be printed.
#define DEBUG_PRINTER Serial #define DEBUG_PRINTER Serial
@ -152,8 +155,30 @@ public:
#endif #endif
bool digitalWrite(uint8_t pin, uint8_t value); bool digitalWrite(uint8_t pin, uint8_t value);
bool readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue); #ifdef MISCHIANTI_ENCODER_ALGORITHM
bool readEncoderValueMischianti(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
int8_t readEncoderValueMischianti(uint8_t pinA, uint8_t pinB);
#endif
#ifdef POKI_ENCODER_ALGORITHM
bool readEncoderValuePoki(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
int8_t readEncoderValuePoki(uint8_t pinA, uint8_t pinB);
#endif
// bool readEncoderValueEvolved(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
// int8_t readEncoderValueEvolved(uint8_t pinA, uint8_t pinB);
#ifdef SEQUENCE_ENCODER_ALGORITHM
bool readEncoderValueSequence(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
int8_t readEncoderValueSequence(uint8_t pinA, uint8_t pinB);
#endif
#ifdef SEQUENCE_ENCODER_ALGORITHM_REDUCED
bool readEncoderValueSequenceReduced(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
int8_t readEncoderValueSequenceReduced(uint8_t pinA, uint8_t pinB);
#endif
#ifdef BASIC_ENCODER_ALGORITHM
bool readEncoderValue(uint8_t pinA, uint8_t pinB, volatile long *encoderValue, bool reverseRotation = false);
int8_t readEncoderValue(uint8_t pinA, uint8_t pinB); int8_t readEncoderValue(uint8_t pinA, uint8_t pinB);
#endif
int getLatency() const { int getLatency() const {
return latency; return latency;
@ -217,7 +242,7 @@ private:
byte writeByteBuffered = B00000000; byte writeByteBuffered = B00000000;
byte encoderValues = B00000000; volatile byte encoderValues = B00000000;
uint8_t prevNextCode = 0; uint8_t prevNextCode = 0;
uint16_t store=0; uint16_t store=0;

View File

@ -21,6 +21,9 @@ Tutorial:
To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder PCF8574. Check that the PCF8574 folder contains `PCF8574\\.cpp` and `PCF8574.h`. Place the DHT library folder your `<arduinosketchfolder>/libraries/` folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder PCF8574. Check that the PCF8574 folder contains `PCF8574\\.cpp` and `PCF8574.h`. Place the DHT library folder your `<arduinosketchfolder>/libraries/` folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.
## Changelog
23/11/2020: v2.2.2 Add multiple implementation for encoder management (you can enable by uncomment relative define)
# Reef complete PCF8574 PCF8574AP digital input and output expander with i2c bus. # Reef complete PCF8574 PCF8574AP digital input and output expander with i2c bus.
I try to simplify the use of this IC, with a minimal set of operation. I try to simplify the use of this IC, with a minimal set of operation.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
name=PCF8574 library name=PCF8574 library
version=2.2.1 version=2.2.2
author=Renzo Mischianti <renzo.mischianti@gmail.com> author=Renzo Mischianti <renzo.mischianti@gmail.com>
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