summary refs log tree commit diff
path: root/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'input.cpp')
-rw-r--r--input.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/input.cpp b/input.cpp
new file mode 100644
index 0000000..ec95b1e
--- /dev/null
+++ b/input.cpp
@@ -0,0 +1,74 @@
+#include "input.h"
+
+#define CLK_PIN 2
+#define DT_PIN 3
+#define SW_PIN 4
+
+Encoder encoder(CLK_PIN, DT_PIN);
+void setup_input() {
+  pinMode(SW_PIN, INPUT_PULLUP);
+}
+
+#define KNOB_DIR -1
+uint32_t read_knob() {
+  uint32_t rotate = KNOB_DIR * encoder.read() / 4;
+  if(rotate != 0) {
+    encoder.write(0);
+  }
+  return rotate;
+}
+
+// button physical state
+#define PRESSED 0
+#define RELEASED 1
+uint8_t pstate = RELEASED;
+#define DEBOUNCE_CYCLES 3
+uint8_t debounce;
+
+uint8_t debounced_read() {
+  byte read = digitalRead(SW_PIN);
+  if (read != pstate && ++debounce >= DEBOUNCE_CYCLES) {
+    pstate = read;
+    debounce = 0;
+  }
+  return pstate;
+}
+
+// button logical state
+#define DOWN 0
+#define UP 1
+#define LONGPRESS 2
+uint8_t lstate = UP;
+
+#define LONGPRESS_MS 500
+uint32_t pressed_at;
+
+uint8_t read_button() {
+  uint8_t read = debounced_read();
+
+  switch(lstate) {
+    case UP:
+      if(read == PRESSED) {
+        lstate = DOWN;
+        pressed_at = millis();
+      }
+      break;
+
+    case DOWN:
+      if(millis() - pressed_at >= LONGPRESS_MS) {
+        lstate = LONGPRESS;
+        return EVENT_HOLD;
+      }
+      if(read == RELEASED) {
+        lstate = UP;
+        return EVENT_CLICK;
+      }
+      break;
+
+    case LONGPRESS:
+      if(read == RELEASED) lstate = UP;
+      break;
+  }
+
+  return EVENT_NONE;
+}