Control Surface main
MIDI Control Surface library for Arduino
ButtonMatrix.ipp
Go to the documentation of this file.
1#include "ButtonMatrix.hpp"
4#include <string.h>
5
7
8template <class Derived, uint8_t NumRows, uint8_t NumCols>
10 const PinList<NumRows> &rowPins, const PinList<NumCols> &colPins)
11 : rowPins(rowPins), colPins(colPins) {
12 memset(prevStates, 0xFF, sizeof(prevStates));
13}
14
15template <class Derived, uint8_t NumRows, uint8_t NumCols>
17 unsigned long now = millis();
18 // only update 25 ms after previous change (crude software debounce).
19 // Edit this in Settings/Settings.hpp
20 if (now - prevRefresh < debounceTime)
21 return;
22
23 for (size_t row = 0; row < NumRows; row++) { // scan through all rows
24 pinMode(rowPins[row], OUTPUT); // make the current row Lo-Z 0V
25#if !defined(__AVR__) && defined(ARDUINO)
26 delayMicroseconds(SELECT_LINE_DELAY);
27#endif
28 for (size_t col = 0; col < NumCols; col++) { // scan through all columns
29 bool state = digitalRead(colPins[col]); // read the state
30 if (state != getPrevState(col, row)) {
31 // if the state changed since last time
32 // execute the handler
33 CRTP(Derived).onButtonChanged(row, col, state);
34 setPrevState(col, row, state); // remember the state
35 prevRefresh = now;
36 }
37 }
38 pinMode(rowPins[row], INPUT); // make the current row Hi-Z again
39 }
40}
41
42template <class Derived, uint8_t NumRows, uint8_t NumCols>
44 // make all columns input pins and enable
45 // the internal pull-up resistors
46 for (const pin_t &colPin : colPins)
47 pinMode(colPin, INPUT_PULLUP);
48 // make all rows Hi-Z
49 for (const pin_t &rowPin : rowPins)
50 pinMode(rowPin, INPUT);
51}
52
53template <class Derived, uint8_t NumRows, uint8_t NumCols>
54inline uint8_t
56 uint8_t row) {
57 // map from a 2D array of bits to a flat array of bits
58 return col * NumRows + row;
59}
60
61template <class Derived, uint8_t NumRows, uint8_t NumCols>
62inline uint8_t
64 return bits >> 3; // bits / 8
65}
66
67template <class Derived, uint8_t NumRows, uint8_t NumCols>
68inline uint8_t
70 return 1 << (bits & 7); // bits % 8
71}
72
73template <class Derived, uint8_t NumRows, uint8_t NumCols>
75 uint8_t row) {
76 uint8_t bits = positionToBits(col, row);
77 return !!(prevStates[bitsToIndex(bits)] & bitsToBitmask(bits));
78}
79
80template <class Derived, uint8_t NumRows, uint8_t NumCols>
82 uint8_t row,
83 bool state) {
84 uint8_t bits = positionToBits(col, row);
85 if (state)
86 prevStates[bitsToIndex(bits)] |= bitsToBitmask(bits);
87 else
88 prevStates[bitsToIndex(bits)] &= ~bitsToBitmask(bits);
89}
90
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
constexpr PinMode_t INPUT
constexpr PinMode_t INPUT_PULLUP
constexpr PinMode_t OUTPUT
#define CRTP(Derived)
Helper for the Curiously Recurring Template Pattern.
Definition: CRTP.hpp:4
A class that reads the states of a button matrix.
static uint8_t bitsToBitmask(uint8_t bits)
void setPrevState(uint8_t col, uint8_t row, bool state)
bool getPrevState(uint8_t col, uint8_t row)
Get the state of the button in the given column and row.
uint8_t prevStates[(NumCols *NumRows+7)/8]
void begin()
Initialize (enable internal pull-up resistors on column pins).
void update()
Scan the matrix, read all button states, and call the onButtonChanged callback.
static uint8_t bitsToIndex(uint8_t bits)
static uint8_t positionToBits(uint8_t col, uint8_t row)
void pinMode(pin_t pin, PinMode_t mode)
An ExtIO version of the Arduino function.
PinStatus_t digitalRead(pin_t pin)
An ExtIO version of the Arduino function.
constexpr unsigned long SELECT_LINE_DELAY
The time in microseconds to wait for lines of multiplexers and scanning matrices to settle before rea...
uint16_t pin_t
The type for Arduino pins (and ExtendedIOElement pins).