diff --git a/Software/Gravity/Gravity.ino b/Software/Gravity/Gravity.ino index 8be2ce4..d2b353c 100644 --- a/Software/Gravity/Gravity.ino +++ b/Software/Gravity/Gravity.ino @@ -1,12 +1,12 @@ #include -#include +//#include #include #include #include #include #include -#define VERSION "V:1.1.2" +#define VERSION "V:1.1.3B" byte memCode = 'D'; //Change to different letter if you changed the data structure @@ -151,7 +151,7 @@ int extTriggerCount; //unsigned long lastInteractionTime; // used for display timeout U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R2, SCL, SDA, U8X8_PIN_NONE); -RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03); +//RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03); //Font const PROGMEM uint8_t velvetscreen[437] U8G2_FONT_SECTION("velvetscreen") = @@ -218,9 +218,18 @@ void setup() { calculateCycles(); calculateBPMTiming(); + checkEncoderStatus(); resetClocks(); + 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; + FlexiTimer2::set(1, 1.0 / 10000, clock); // 1.0/1000 = 1ms period. If other than 1ms calculateBPMTiming() might need tweaking FlexiTimer2::start(); } @@ -232,6 +241,62 @@ 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; +void checkEncoderStatus() { + bool pin1Status = digitalRead(ENC_D1_PIN); + bool pin2Status = digitalRead(ENC_D2_PIN); + uint8_t newStatus = (pin1Status << 1) | pin2Status; + switch(encoderStatus) { // encoderStatus & 0b00000011 - to check only 2 last bits + 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 = (encoderStatus << 2); //previous status is now stored in bits 2 and 3 + encoderStatus = bitWrite(encoderStatus, 1, pin1Status); + encoderStatus = bitWrite(encoderStatus, 0, pin2Status); //This can probably be more optimizied with bit logic + + uint32_t currentTime = millis(); + encoderTimeBetweenPulses = currentTime - encoderCheckTime; + encoderCheckTime = currentTime; +} + void sendMIDIClock() { NeoSerial.write(0xF8); } diff --git a/Software/Gravity/Interactions.ino b/Software/Gravity/Interactions.ino index 45afd84..5e3dd13 100644 --- a/Software/Gravity/Interactions.ino +++ b/Software/Gravity/Interactions.ino @@ -87,24 +87,30 @@ void checkInputs() { updateScreen(); } - //encoder - encoder.tick(); - int encPosition = encoder.getPosition(); - int encDirection = (int)(encoder.getDirection()); - if (encPositionOld != encPosition) { - int change = encPositionOld - encPosition; - if (reverseEnc) { + //encoder + // things to try: + // 1 - make checkInputs one if-else chain and move the encoder part to the first condition + // 2 - count "burst" changes and apply acceleration + // 3 - pinchange interrupts? https://github.com/mathertel/RotaryEncoder/blob/master/examples/InterruptRotator/InterruptRotator.ino + //encoder.tick(); + //int encPosition = 0;//encoder.getPosition(); + //int8_t encDirection = 0;//(int)(encoder.getDirection()); + if (encoderChange != 0) { + int change = encoderChange; + if (!reverseEnc) { change = change * -1; } - unsigned long ms = encoder.getMillisBetweenRotations(); - /*if (encDirectionOld == encDirection && ms < 20) { //encoder acceleration + /*unsigned long ms = 0;//encoder.getMillisBetweenRotations(); + + if (encDirectionOld == encDirection && ms < 18) { //encoder acceleration change = change * 5; - } else if (encDirectionOld == encDirection && ms < 80) { + } /* else if (encDirectionOld == encDirection && ms < 80) { change = change * 2; - } else */ if (encDirectionOld != encDirection && ms < 200) { //filter out encoder "jumps" + } else */ + if (((encoderChange > 0) != encoderDirectionOld) && encoderTimeBetweenPulses < 200) { //filter out encoder "jumps" change = 0; } - encDirectionOld = encDirection; + encoderDirectionOld = (encoderChange > 0); if (displayScreen == 0) { byte channelCV; if (!insideTab && !shiftBtnPushed) { //Change tab @@ -364,7 +370,8 @@ void checkInputs() { } updateScreen(); - encPositionOld = encPosition; + //encPositionOld = encPosition; + encoderChange = 0; } //play button