/*
Forum: https://forum.arduino.cc/t/codeproblem-arduino-leonardo-als-tastatur/1160391/3
Wokwi: https://wokwi.com/projects/374338338816616449
Keyboard matrix for 20 buttons
uses 4 pins for the rows
and 5 pins for the columns
*/
//Keyboard Matrix
//int keyrow[] = {3,4,5,6,7,8};
//int keycol[] = {2,14,15,16};
int keycol[] = {0,1,2,3};
int keyrow[] = {9,10,11,12,13};
int col_scan;
bool simulate = true;
int last_scan = -1;
// Single Pin
const int buttonPin = A3; // input pin for pushbutton
int previousButtonState = HIGH; // for checking the state of a pushButton
constexpr int noOfRows = sizeof(keyrow) / sizeof(keyrow[0]);
constexpr int noOfColumns = sizeof(keycol) / sizeof(keycol[0]);
// Define a structure to hold input pin and action
struct ToggleInputAction {
int pin; // Analog pin number (A0, A1, A2, etc.)
bool prev;
void (*action)(); // Pointer to the function to be executed when the input is pressed
};
struct ButtonInputAction {
int col;
int row;
void (*action)(); // Pointer to the function to be executed when the input is pressed
};
// Example actions
void actionA0() {
Serial.println("A0 pressed!");
}
void actionA1() {
Serial.println("A1 pressed!");
}
void actionA2() {
Serial.println("A2 pressed!");
}
void actionA3() {
Serial.println("A3 pressed!");
}
void actionL1() {
Serial.println("L1");
//pressKey(KEY_LEFT_CTRL,'1');
}
void actionL2() {
Serial.println("L2");
//pressKey(KEY_LEFT_CTRL,'2');
}
void actionL3() {
Serial.println("L3");
// pressKey(KEY_LEFT_CTRL,'3');
}
void actionL4() {
Serial.println("L4");
// pressKey(KEY_LEFT_CTRL,'4');
}
void actionL5() {
Serial.println("L5");
//pressKey(KEY_LEFT_CTRL,'5');
}
void actionR1() {
Serial.println("R1");
// pressKey(KEY_RIGHT_CTRL,'1');
}
void actionR2() {
Serial.println("R2");
// pressKey(KEY_RIGHT_CTRL,'2');
}
void actionR3() {
Serial.println("R3");
// pressKey(KEY_RIGHT_CTRL,'3');
}
void actionR4() {
Serial.println("R4");
//pressKey(KEY_RIGHT_CTRL,'4');
}
void actionR5() {
Serial.println("R5");
// pressKey(KEY_RIGHT_CTRL,'5');
}
void actionMMS() {
Serial.println("MMS");
//pressKey(KEY_LEFT_CTRL, 'm');
}
void actionMMSMode() {
Serial.println("MMS Mode");
//pressKey(KEY_RIGHT_CTRL, 'm');
}
void actionMMSPointTrack() {
Serial.println("MMS Point Track");
//pressKey(KEY_RIGHT_CTRL, 't');
}
void actionMMSAreaTrack() {
Serial.println("MMS Area Track");
//pressKey(KEY_RIGHT_CTRL, 'a');
}
void actionWpnDown() {
Serial.println("WPN Down");
//pressKey(KEY_RIGHT_CTRL, 'd');
}
void actionWpnRight() {
Serial.println("WPN Right");
//pressKey(KEY_RIGHT_CTRL, 'r');
}
void actionWpnLeft() {
Serial.println("WPN Left");
// pressKey(KEY_RIGHT_CTRL, 'l');
}
ToggleInputAction inputActions[] = {
{A0, false, actionA0},
{A1, false, actionA1},
{A2, false, actionA2},
{A3, false, actionA3}
};
void checkToggles(ToggleInputAction inputs[], int numInputs) {
for (int i = 0; i < numInputs; i++) {
if (digitalRead(inputs[i].pin) == LOW) {
if (!inputs[i].prev) {
inputs[i].action();
inputs[i].prev = true;
}
} else if (inputs[i].prev) {
inputs[i].prev = false;
}
}
}
void setup()
{
//Keyboard.begin();
Serial.begin(9600);
Serial.print("## Setup starts");
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH); // Make button condition HIGH
pinMode(A1, OUTPUT);
digitalWrite(A1, HIGH); // Make button condition HIGH
pinMode(A2, OUTPUT);
digitalWrite(A2, HIGH); // Make button condition HIGH
pinMode(A3, OUTPUT);
digitalWrite(A3, HIGH); // Make button condition HIGH
for (int i = 0; i < noOfRows; i++)
{
//Init rows
pinMode(keyrow[i], OUTPUT);
}
for (int i = 0; i < noOfColumns; i++)
{
//Init columns
pinMode(keycol[i], INPUT);
digitalWrite(keycol[i], HIGH);
}
}
int actRow;
int actCol;
void loop()
{
if (buttonPressed(actRow, actCol)) {
takeAction(actRow, actCol);
}
// Number of inputs
int numInputs = sizeof(inputActions) / sizeof(inputActions[0]);
// Periodically check the inputs in the loop
checkToggles(inputActions, numInputs);
}
boolean buttonPressed(int &aRow, int &aCol) {
//Suche nach gedrücktem Knopf
static boolean keyPressed = false;
static unsigned long lastPressTime = 0;
if (keyPressed && millis() - lastPressTime < 300) {
// 300 msec as a simple way of debouncing
// and to slow down repetition of the same action
return false;
}
keyPressed = false;
for (int i = 0; i < noOfRows; i++)
{
if (keyPressed) break;
for (int j = 0; j < noOfRows; j++) {
digitalWrite(keyrow[j], HIGH);
}
digitalWrite(keyrow[i], LOW);
for (int j = 0; j < noOfColumns; j++)
{
col_scan = digitalRead(keycol[j]);
if (col_scan == LOW)
{
lastPressTime = millis();
keyPressed = true;
aRow = i;
aCol = j;
break;
}
}
}
return keyPressed;
}
void pressKey(uint8_t m, char c) {
//Keyboard.press(m);
//Keyboard.write(c);
//Keyboard.releaseAll();
}
ButtonInputAction buttonActions[] = {
{3, 0, actionL1},
{3, 1, actionL2},
{3, 2, actionL3},
{3, 4, actionL4},
{3, 5, actionL5},
{1, 0, actionR1},
{1, 2, actionR2},
{1, 3, actionR3},
{1, 4, actionR4},
{1, 5, actionR5},
{0, 0, actionMMS},
{0, 1, actionMMSMode},
{0, 2, actionMMSPointTrack},
{0, 3, actionMMSAreaTrack},
{2, 0, actionWpnDown},
{2, 1, actionWpnRight},
{2, 2, actionWpnLeft}
};
void takeAction(int r, int c)
{
int keyNo = r * noOfColumns + c + 1;
// This is a nice place for switch(keyNo){case 1: ...;} etc.
Serial.print("Key ");
Serial.print(keyNo);
Serial.print(" R.C: ");
Serial.print(r);
Serial.print(".");
Serial.print(c);
Serial.print(" -> ");
bool found;
int numInputs = sizeof(buttonActions) / sizeof(buttonActions[0]);
for (int x = 0; x < numInputs; x++) {
if (buttonActions[x].row == r && buttonActions[x].col == c) {
found = true;
buttonActions[x].action();
}
}
if (!found) {
Serial.println("Dunno");
}
}