/************************************************************************
16 Buttons on 9 Pins - dlloydev
===============================
⦿ Built-in debounce for all buttons.
⦿ Multiple pressed button detection up to 8 per row (use keyboard and mouse).
⦿ Uses one clock pin to provide 3 input states and for debounce sample period.
⦿ No pullup or pulldown resistors required for buttons.
⦿ One pulsed pin current limiting resistor required per button pair (column).
⦿ Can be scaled for more or fewer buttons.
⦿ No external GPIO expander ICs required.
***********************************************************************/
const char label1[9] = "ABCDEFGH";
const char label2[9] = "IJKLMNOP";
const byte pin[] = {4, 5, 6, 7, 16, 17, 18, 19};
byte row1[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte row2[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte status1 = 0, status2 = 0;
byte prevStatus1 = 0, prevStatus2 = 0;
bool readyToRead;
void setup() {
Serial.begin(115200);
pinMode(3, OUTPUT);
}
void loop() {
sampleTimer(5000); //5000μs sample period
checkButtons();
}
void sampleTimer(unsigned long us) {
volatile unsigned long prevUs, now;
volatile bool pulseState;
now = micros();
if ((now - prevUs) >= us >> 1) {
digitalWrite(3, pulseState);
pulseState = !pulseState;
prevUs = now;
for (int i = 0; i < 8; i++) { //prepare for next reading
row1[i] <<= 1;
row2[i] <<= 1;
}
readyToRead = true;
}
}
void checkButtons() {
if (readyToRead) {
prevStatus1 = status1;
prevStatus2 = status2;
for (int i = 0; i < 8; i++) {
if (digitalRead(pin[i])) row1[i] |= 1;
else row2[i] |= 1;
if (!((row1[i] & 0xE0) == 0xE0)) bitWrite(status1, i, 0); // top row button just released
if ((row1[i] & 0x07) == 0x07) bitWrite(status1, i, 1); // top row button just pressed
if (!((row2[i] & 0xE0) == 0xE0)) bitWrite(status2, i, 0); // bottom row button just released
if ((row2[i] & 0x07) == 0x07) bitWrite(status2, i, 1); // bottom row button just pressed
}
if (prevStatus1 != status1 || prevStatus2 != status2) {
if (!status1 && !status2) Serial.println(F("All released"));
else {
Serial.print(F("Pressed "));
for (int i = 0; i < 8; i++) {
if (status1 & 1 << i) Serial.print(label1[i]);
if (status2 & 1 << i) Serial.print(label2[i]);
}
Serial.println();
}
}
readyToRead = false;
}
}