summary refs log tree commit diff
path: root/input.cpp
blob: ec95b1ed2889a8c99c67a1fbe3a1cd4f79509e4a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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;
}