diff options
Diffstat (limited to '12key-arduino/Button.h')
-rw-r--r-- | 12key-arduino/Button.h | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/12key-arduino/Button.h b/12key-arduino/Button.h new file mode 100644 index 0000000..c67086b --- /dev/null +++ b/12key-arduino/Button.h @@ -0,0 +1,123 @@ +#pragma once + +#include <Arduino.h> +#include "pins.h" + +class Button { + protected: + unsigned int m_mask; + unsigned int m_debounceTime; + bool m_debouncing; + unsigned long m_debounceEnd; + bool m_pressed; + + static buttons[12]; + + void startDebounce() { + m_debouncing = true; + m_debounceEnd = millis() + m_debounceTime; + } + + public: + static unsigned int state; + static void Setup() { + pinMode(COL_1, INPUT_PULLUP); + pinMode(COL_2, INPUT_PULLUP); + pinMode(COL_3, INPUT_PULLUP); + + pinMode(ROW_1, INPUT_PULLUP); + pinMode(ROW_2, INPUT_PULLUP); + pinMode(ROW_3, INPUT_PULLUP); + pinMode(ROW_4, INPUT_PULLUP); + } + + static void UpdateAll() { + byte col1 = 1 - digitalRead(COL_1); + byte col2 = 1 - digitalRead(COL_2); + byte col3 = 1 - digitalRead(COL_3); + + byte row1 = 1 - digitalRead(ROW_1); + byte row2 = 1 - digitalRead(ROW_2); + byte row3 = 1 - digitalRead(ROW_3); + byte row4 = 1 - digitalRead(ROW_4); + + #define BUILD_ROW(row, c1, c2, c3) \ + ( ((row & c1) << 2) | ((row & c2) << 1) | (row & c3) ) + + byte row1_buttons = BUILD_ROW(row1, col1, col2, col3); + byte row2_buttons = BUILD_ROW(row2, col1, col2, col3); + byte row3_buttons = BUILD_ROW(row3, col1, col2, col3); + byte row4_buttons = BUILD_ROW(row4, col1, col2, col3); + + unsigned int pins = 0 | + (row1_buttons << 9) | + (row2_buttons << 6) | + (row3_buttons << 3) | + (row4_buttons << 0); + + for (int i=0; i<12; i++) { + buttons[i].update(pins); + } + } + + Button(unsigned int index, unsigned int debounceTime=4) { + m_mask = 1 << index; + m_debounceTime = debounceTime; + m_debouncing = false; + m_pressed = false; + } + + void update(unsigned int pins) { + if (m_debouncing) { + if (millis() > m_debounceEnd) { + /* done debouncing, continue */ + m_debouncing = false; + } + else { + /* still debouncing, ignore changes */ + return; + } + } + + if ((m_mask & pins)) { + /* pressed */ + if (m_pressed) { + /* already marked */ + } + else { + /* update state */ + m_pressed = true; + state = state | m_mask; + startDebounce(); + } + } + else { + /* released */ + if (!m_pressed) { + /* already marked, ignore */ + } + else { + /* update state */ + m_pressed = false; + state = state & ~m_mask; + startDebounce(); + } + } + } +}; +unsigned int Button::state = 0; + +Button Button::buttons[12] = { + Button(0), + Button(1), + Button(2), + Button(3), + Button(4), + Button(5), + Button(6), + Button(7), + Button(8), + Button(9), + Button(10), + Button(11), +}; |