From 663b723ddb45f61598135989aaed2a348398813e Mon Sep 17 00:00:00 2001 From: Oleksiy Date: Sun, 4 May 2025 23:01:40 +0300 Subject: [PATCH] Some (unsuccessfull) encoder tests --- .../EncoderPinChangeInterruptTest.ino | 116 ++++++++++++++++++ .../Interactions.ino | 29 +++++ Extra/EncoderPinChangeInterruptTest/UI.ino | 13 ++ .../EncoderPollingTest/EncoderPollingTest.ino | 100 +++++++++++++++ Extra/EncoderPollingTest/Interactions.ino | 33 +++++ Extra/EncoderPollingTest/UI.ino | 13 ++ 6 files changed, 304 insertions(+) create mode 100644 Extra/EncoderPinChangeInterruptTest/EncoderPinChangeInterruptTest.ino create mode 100644 Extra/EncoderPinChangeInterruptTest/Interactions.ino create mode 100644 Extra/EncoderPinChangeInterruptTest/UI.ino create mode 100644 Extra/EncoderPollingTest/EncoderPollingTest.ino create mode 100644 Extra/EncoderPollingTest/Interactions.ino create mode 100644 Extra/EncoderPollingTest/UI.ino diff --git a/Extra/EncoderPinChangeInterruptTest/EncoderPinChangeInterruptTest.ino b/Extra/EncoderPinChangeInterruptTest/EncoderPinChangeInterruptTest.ino new file mode 100644 index 0000000..ffec28a --- /dev/null +++ b/Extra/EncoderPinChangeInterruptTest/EncoderPinChangeInterruptTest.ino @@ -0,0 +1,116 @@ +#include +#include + +#define SCREEN_ADDRESS 0x3C + +// Rev 2+ Config +#define ENC_BTN_PIN 14 +#define ENC_D1_PIN 17 +#define ENC_D2_PIN 4 +#define START_STOP_BTN_PIN 5 +#define SHIFT_BTN_PIN 12 +#define EXT_INPUT_PIN 2 //needs to be an interrupt pin +#define ANALOGUE_INPUT_1_PIN A7 +#define ANALOGUE_INPUT_2_PIN A6 +const byte outsPins[6] = { 7, 8, 10, 6, 9, 11 }; +const byte clockOutPin = 3; +bool rotateScreen = false; +bool reverseEnc = false; +// + +/* Rev 1 Config +#define ENC_BTN_PIN 14 +#define ENC_D1_PIN 17 +#define ENC_D2_PIN 4 +#define START_STOP_BTN_PIN 5 +#define SHIFT_BTN_PIN 100 + +#define EXT_INPUT_PIN 2 //needs to be an interrupt pin +#define ANALOGUE_INPUT_1_PIN A2 +#define ANALOGUE_INPUT_2_PIN A1 + +const byte clockOutPin = 13; +const byte outsPins[6] = {6, 11, 7, 10, 8, 9}; +bool rotateScreen = true; +*/ + +U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R2, SCL, SDA, U8X8_PIN_NONE); + +int16_t counter = 0; + +void setup() { + + pinMode(clockOutPin, OUTPUT); + + pinMode(ENC_D1_PIN, INPUT_PULLUP); + pinMode(ENC_D2_PIN, INPUT_PULLUP); + + //Enabling PinChange Interrupts for the encoder + //pins 17 (PC3/PCINT11) and 4 (PD4/PCINT20), ports C and D + PCICR |= 0b00000110; + PCMSK1 |= 0b00001000; + PCMSK2 |= 0b00010000; + + u8g2.begin(); + updateScreen(); +} + +void loop() { + checkInputs(); +} + +//Encoder interrupts +ISR (PCINT1_vect) { + checkEncoderStatus(); +} +ISR (PCINT2_vect) { + checkEncoderStatus(); +} + +uint8_t encoderStatus; +uint32_t encoderCheckTime = 0; +uint32_t encoderTimeBetweenPulses = 0; +bool encoderDirectionOld; //0 = -, 1 = +, Old because current direction can be determined by encoderChange +int8_t encoderChange = 0; +//uint8_t encoderBurstCount = 0; + +void checkEncoderStatus() { + //noInterrupts(); + uint8_t newStatus = (digitalRead(ENC_D1_PIN) << 1) | digitalRead(ENC_D2_PIN); + switch(encoderStatus) { + case 0b00: + if (newStatus == 0b01) { + encoderChange++; + } else if (newStatus == 0b10) { + encoderChange--; + } + break; + case 0b01: + if (newStatus == 0b11) { + encoderChange++; + } else if (newStatus == 0b00) { + encoderChange--; + } + break; + case 0b11: + if (newStatus == 0b10) { + encoderChange++; + } else if (newStatus == 0b01) { + encoderChange--; + } + break; + case 0b10: + if (newStatus == 0b00) { + encoderChange++; + } else if (newStatus == 0b11) { + encoderChange--; + } + break; + } + encoderStatus = newStatus; + + uint32_t currentTime = millis(); + encoderTimeBetweenPulses = currentTime - encoderCheckTime; + encoderCheckTime = currentTime; + //interrupts(); +} \ No newline at end of file diff --git a/Extra/EncoderPinChangeInterruptTest/Interactions.ino b/Extra/EncoderPinChangeInterruptTest/Interactions.ino new file mode 100644 index 0000000..f856d9f --- /dev/null +++ b/Extra/EncoderPinChangeInterruptTest/Interactions.ino @@ -0,0 +1,29 @@ +void checkInputs() { + + //encoder + if (encoderChange != 0) { + if (!reverseEnc) { + encoderChange = encoderChange * -1; + } + counter += encoderChange; + + /*if (((encoderChange > 0) != encoderDirectionOld) && encoderTimeBetweenPulses < 60) { //filter out encoder "jumps". + encoderChange = 0; //Comented out because it seems like sometimes it was preventing normal scroll + } //if it works ok without it delete encoderDirectionOld var altogether + encoderDirectionOld = (encoderChange > 0);*/ + + //encoder acceleration + /*if (encoderTimeBetweenPulses < 15) { // <-- + encoderBurstCount++; + } else { + encoderBurstCount = 0; + } + if (encoderBurstCount > 3) { // <-- + encoderChange = encoderChange * 3; // <-- The three params need to be finetuned to feel natural + }*/ + + updateScreen(); + //encPositionOld = encPosition; + encoderChange = 0; + } +} \ No newline at end of file diff --git a/Extra/EncoderPinChangeInterruptTest/UI.ino b/Extra/EncoderPinChangeInterruptTest/UI.ino new file mode 100644 index 0000000..87e9a2e --- /dev/null +++ b/Extra/EncoderPinChangeInterruptTest/UI.ino @@ -0,0 +1,13 @@ +void updateScreen() { + + u8g2.firstPage(); + do { + String valueStr; + u8g2.setDrawColor(1); + + valueStr = String(counter); + u8g2.setFont(u8g2_font_ncenB14_tr); + u8g2.drawStr(0,15,valueStr.c_str()); + + } while ( u8g2.nextPage() ); +} \ No newline at end of file diff --git a/Extra/EncoderPollingTest/EncoderPollingTest.ino b/Extra/EncoderPollingTest/EncoderPollingTest.ino new file mode 100644 index 0000000..e9f5487 --- /dev/null +++ b/Extra/EncoderPollingTest/EncoderPollingTest.ino @@ -0,0 +1,100 @@ +#include +#include + +#define SCREEN_ADDRESS 0x3C + +// Rev 2+ Config +#define ENC_BTN_PIN 14 +#define ENC_D1_PIN 17 +#define ENC_D2_PIN 4 +#define START_STOP_BTN_PIN 5 +#define SHIFT_BTN_PIN 12 +#define EXT_INPUT_PIN 2 //needs to be an interrupt pin +#define ANALOGUE_INPUT_1_PIN A7 +#define ANALOGUE_INPUT_2_PIN A6 +const byte outsPins[6] = { 7, 8, 10, 6, 9, 11 }; +const byte clockOutPin = 3; +bool rotateScreen = false; +bool reverseEnc = false; +// + +/* Rev 1 Config +#define ENC_BTN_PIN 14 +#define ENC_D1_PIN 17 +#define ENC_D2_PIN 4 +#define START_STOP_BTN_PIN 5 +#define SHIFT_BTN_PIN 100 + +#define EXT_INPUT_PIN 2 //needs to be an interrupt pin +#define ANALOGUE_INPUT_1_PIN A2 +#define ANALOGUE_INPUT_2_PIN A1 + +const byte clockOutPin = 13; +const byte outsPins[6] = {6, 11, 7, 10, 8, 9}; +bool rotateScreen = true; +*/ + +U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R2, SCL, SDA, U8X8_PIN_NONE); + +int16_t counter = 0; + +void setup() { + + pinMode(clockOutPin, OUTPUT); + + pinMode(ENC_D1_PIN, INPUT_PULLUP); + pinMode(ENC_D2_PIN, INPUT_PULLUP); + + u8g2.begin(); + updateScreen(); +} + +void loop() { + checkInputs(); +} + +uint8_t encoderStatus; +uint32_t encoderCheckTime = 0; +uint32_t encoderTimeBetweenPulses = 0; +bool encoderDirectionOld; //0 = -, 1 = +, Old because current direction can be determined by encoderChange +int8_t encoderChange = 0; +//uint8_t encoderBurstCount = 0; + +void checkEncoderStatus() { + uint8_t newStatus = (digitalRead(ENC_D1_PIN) << 1) | digitalRead(ENC_D2_PIN); + switch(encoderStatus) { + case 0b00: + if (newStatus == 0b01) { + encoderChange++; + } else if (newStatus == 0b10) { + encoderChange--; + } + break; + case 0b01: + if (newStatus == 0b11) { + encoderChange++; + } else if (newStatus == 0b00) { + encoderChange--; + } + break; + case 0b11: + if (newStatus == 0b10) { + encoderChange++; + } else if (newStatus == 0b01) { + encoderChange--; + } + break; + case 0b10: + if (newStatus == 0b00) { + encoderChange++; + } else if (newStatus == 0b11) { + encoderChange--; + } + break; + } + encoderStatus = newStatus; + + uint32_t currentTime = millis(); + encoderTimeBetweenPulses = currentTime - encoderCheckTime; + encoderCheckTime = currentTime; +} \ No newline at end of file diff --git a/Extra/EncoderPollingTest/Interactions.ino b/Extra/EncoderPollingTest/Interactions.ino new file mode 100644 index 0000000..561f50d --- /dev/null +++ b/Extra/EncoderPollingTest/Interactions.ino @@ -0,0 +1,33 @@ +void checkInputs() { + + //encoder + if (millis() > encoderCheckTime + 20) { //debouncing. this approach doesn't work. very noisy + checkEncoderStatus(); + } + + if (encoderChange != 0) { + if (!reverseEnc) { + encoderChange = encoderChange * -1; + } + counter += encoderChange; + + /*if (((encoderChange > 0) != encoderDirectionOld) && encoderTimeBetweenPulses < 60) { //filter out encoder "jumps". + encoderChange = 0; //Comented out because it seems like sometimes it was preventing normal scroll + } //if it works ok without it delete encoderDirectionOld var altogether + encoderDirectionOld = (encoderChange > 0);*/ + + //encoder acceleration + /*if (encoderTimeBetweenPulses < 15) { // <-- + encoderBurstCount++; + } else { + encoderBurstCount = 0; + } + if (encoderBurstCount > 3) { // <-- + encoderChange = encoderChange * 3; // <-- The three params need to be finetuned to feel natural + }*/ + + updateScreen(); + //encPositionOld = encPosition; + encoderChange = 0; + } +} \ No newline at end of file diff --git a/Extra/EncoderPollingTest/UI.ino b/Extra/EncoderPollingTest/UI.ino new file mode 100644 index 0000000..87e9a2e --- /dev/null +++ b/Extra/EncoderPollingTest/UI.ino @@ -0,0 +1,13 @@ +void updateScreen() { + + u8g2.firstPage(); + do { + String valueStr; + u8g2.setDrawColor(1); + + valueStr = String(counter); + u8g2.setFont(u8g2_font_ncenB14_tr); + u8g2.drawStr(0,15,valueStr.c_str()); + + } while ( u8g2.nextPage() ); +} \ No newline at end of file