#include #include "pins.h" class Button { protected: unsigned int m_mask; unsigned int m_debounceTime; bool m_debouncing; unsigned long m_debounceEnd; bool m_pressed; void startDebounce() { m_debouncing = true; m_debounceEnd = millis() + m_debounceTime; } public: static unsigned int state; 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 buttons[] = { Button(0), Button(1), Button(2), Button(3), Button(4), Button(5), Button(6), Button(7), Button(8), Button(9), Button(10), Button(11), }; /* pin bitmask order: xxxx 1234 5678 9*0# */ unsigned int ReadPins() { 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); return 0 | (row1_buttons << 9) | (row2_buttons << 6) | (row3_buttons << 3) | (row4_buttons << 0); } 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); Serial.begin(115200); } void PrintPin(unsigned int pins, int index, const char *msg) { if (pins & (1 << index)) { Serial.print(msg); } } void loop() { unsigned int pins = ReadPins(); for (int i=0; i<12; i++) { buttons[i].update(pins); } if (Button::state != 0) { Serial.print("buttons: "); PrintPin(Button::state, 11, "1"); PrintPin(Button::state, 10, "2"); PrintPin(Button::state, 9, "3"); PrintPin(Button::state, 8, "4"); PrintPin(Button::state, 7, "5"); PrintPin(Button::state, 6, "6"); PrintPin(Button::state, 5, "7"); PrintPin(Button::state, 4, "8"); PrintPin(Button::state, 3, "9"); PrintPin(Button::state, 2, "*"); PrintPin(Button::state, 1, "0"); PrintPin(Button::state, 0, "#"); Serial.println(); Button::state = 0; } }