Hey!
I am working on a project which is a 61 key keyboard.
Arduino pro micro is being used to multiplex 61 switch and communicate with a computer.
I found a code online and edited it a lot to suit my needs.
Here is a simplified version of it:
#include "Keyboard.h"
byte cols[] = {12, 11, 10, 9, 8, 7, 6, 5, 4, 3, A3, A2, A1, A0};
const int colCount = sizeof(cols) / sizeof(cols[0]);
byte rows[] = {2, 0, 1, A4, A5};
const int rowCount = sizeof(rows) / sizeof(rows[0]);
char layout[14][5] = {
{KEY_BACKSPACE, '\\', KEY_RETURN, KEY_RIGHT_SHIFT, KEY_RIGHT_CTRL},
{'=', ']'},
{'-', '[', '\'', '/'},
{'0', 'p', ';', '.', KEY_RIGHT_ALT},
{'9', 'o', 'l', ','},
{'8', 'i', 'k', 'm'},
{'7', 'u', 'j', 'n'},
{'6', 'y', 'h', 'b', ' '},
{'5', 't', 'g', 'v'},
{'4', 'r', 'f', 'c'},
{'3', 'e', 'd', 'x'},
{'2', 'w', 's', 'z', KEY_LEFT_ALT},
{'1', 'q', 'a', 0, KEY_LEFT_GUI},
{KEY_ESC, KEY_TAB, KEY_CAPS_LOCK, KEY_LEFT_SHIFT, KEY_LEFT_CTRL},
};
void setup() {
Keyboard.begin();
for (int i = 0; i < rowCount; i++) {
pinMode(rows[i], OUTPUT);
digitalWrite(rows[i], HIGH);
}
for (int i = 0; i < colCount; i++) {
pinMode(cols[i], INPUT_PULLUP);
}
}
void loop() {
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
digitalWrite(rows[i], LOW);
bool buttonState = digitalRead(cols[j]);
if (buttonState == LOW) {
Keyboard.press(layout[j][i]);
} else if (buttonState == HIGH) {
Keyboard.release(layout[j][i]);
}
digitalWrite(rows[i], HIGH);
}
}
}
The problem is that the code runs too slow and keys are sometimes not recognized when I press them too quickly. I figured out that commands like Keyboard.press/release slow down the loop quite a bit.
The code runs inefficiently because, for example, if I am not pressing key "A", the code is going to use Keyboard.release each time "A" is being scanned in a matrix even though it is not necessary, because "A" has already been released.
Then I modified the code and made a small scale test where the last state of specific key is being stored and Keyboard.press/release is being used only if the state changes.
#include "Keyboard.h"
byte cols[] = {12, 11, 10, 9, 8, 7, 6, 5, 4, 3, A3, A2, A1, A0};
const int colCount = sizeof(cols) / sizeof(cols[0]);
byte rows[] = {2, 0, 1, A4, A5};
const int rowCount = sizeof(rows) / sizeof(rows[0]);
char layout[14][5] = {
{KEY_BACKSPACE, '\\', KEY_RETURN, KEY_RIGHT_SHIFT, KEY_RIGHT_CTRL},
{'=', ']'},
{'-', '[', '\'', '/'},
{'0', 'p', ';', '.', KEY_RIGHT_ALT},
{'9', 'o', 'l', ','},
{'8', 'i', 'k', 'm'},
{'7', 'u', 'j', 'n'},
{'6', 'y', 'h', 'b', ' '},
{'5', 't', 'g', 'v'},
{'4', 'r', 'f', 'c'},
{'3', 'e', 'd', 'x'},
{'2', 'w', 's', 'z', KEY_LEFT_ALT},
{'1', 'q', 'a', 0, KEY_LEFT_GUI},
{KEY_ESC, KEY_TAB, KEY_CAPS_LOCK, KEY_LEFT_SHIFT, KEY_LEFT_CTRL},
};
bool lastButtonState = HIGH; //last state of specific key (in my case letter A)
void setup() {
Keyboard.begin();
Serial.begin(9600);
for (int i = 0; i < rowCount; i++) {
pinMode(rows[i], OUTPUT);
digitalWrite(rows[i], HIGH);
}
for (int i = 0; i < colCount; i++) {
pinMode(cols[i], INPUT_PULLUP);
}
}
void loop() {
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < colCount; j++) {
digitalWrite(rows[i], LOW);
bool buttonState = digitalRead(cols[j]);
if (i == 2 && j == 12) { //if specific key is pressed (in my case letter A)
if (buttonState != lastButtonState) {
if (buttonState == LOW) {
Keyboard.press(layout[j][i]);
lastButtonState = buttonState;
} else {
Keyboard.release(layout[j][i]);
lastButtonState = buttonState;
}
}
}
digitalWrite(rows[i], HIGH);
}
Serial.println(lastButtonState);
}
}
The problem with this is that I would have to store 61 different state values for each key and use them individually.
Is there a way to make it more efficient?