/*
KY-040 Schema:
Encoder GND to Arduino GND
Encoder + to Arduino 5V
Encoder SW (Switch) to Arduino digital pin 2
Encoder DT (Direction of Turn) to Arduino digital pin 3
Encoder CLK (Click) to Arduino digital pin 4
KY-040 has 30 positions per revolution
Comms at 115200 Bauds
*/
// Based on:
// https://docs.arduino.cc/built-in-examples/digital/Debounce
// https://create.arduino.cc/projecthub/vandenbrande/arduino-rotary-encoder-simple-example-ky-040-b78752
#define CLK 4
#define DT 3
#define SW 2
#define buttonDebounceDelay 50
#define baudRate 115200
int ignoreUntil = millis();
#define DEBUG 1
#ifdef DEBUG == 1
//#define debugTime if ((millis() - lastMillis) > 500) Serial.println(); Serial.print(millis()); lastMillis = millis();
#define debugTime Serial.print(millis()); Serial.print(F(" - "));
#define debug(x) Serial.print(x)
#define debugLn(x) Serial.println(x)
#define debugS(x) Serial.print(F(x))
#define debugSLn(x) Serial.println(F(x))
#else
#define debugTime
#define debug(x)
#define debugLn(x)
#define debugS(x)
#define debugSLn(x)
#endif
#define BIT(n,i) (n>>i&1)
int RotPosition = 0;
int currentSwitchState;
int lastSwitchState;
int lastRotationValue = -1;
int position = 0;
int lastCLK = 1;
int lastDT = 1;
boolean buttonDown;
boolean skipNextClick = true;
unsigned long lastButtonDebounceTime = 0;
unsigned long lastRotationalValueDebounceTime = 0;
void setup() {
Serial.begin(baudRate);
Serial.println("**** Starting");
DDRD = 0x011100000;
pinMode(SW, INPUT_PULLUP);
// Read the initial button state
int pinState = PIND;
lastSwitchState = BIT(pinState,SW);
buttonDown = lastSwitchState == LOW;
currentSwitchState = lastSwitchState;
lastRotationValue = BIT(pinState,CLK);
}
void loop() {
// Debounce & read push button
int portValue = PIND;
int instantSwitchState = BIT(portValue,SW);
if (instantSwitchState != lastSwitchState) {
lastButtonDebounceTime = millis();
}
if ((millis() - lastButtonDebounceTime) > buttonDebounceDelay) {
if (instantSwitchState != currentSwitchState) {
currentSwitchState = instantSwitchState;
buttonDown = currentSwitchState == LOW;
//debugSLn("");
debugLn(buttonDown ? "Button Down" : "Button Up");
}
}
lastSwitchState = instantSwitchState;
// Read rotary encoder
int clkValue = BIT(portValue,CLK);
int dtValue = BIT(portValue,DT);
if ((dtValue != lastDT) && (clkValue != lastCLK)) {
debugTime;
debugS("CLK ");
debug(clkValue);
debugS(" DT ");
debugLn(dtValue);
if ((clkValue != lastCLK) && (clkValue == 0)) {
debugLn((lastDT != clkValue) ? "Clockwise" : "Counterclockwise");
position += (lastDT != clkValue) ? 1 : -1;
debugS("Position: ");
debugLn(position);
}
lastCLK = clkValue;
lastDT = dtValue;
}
}