Code
#define TABS 1
#define TAB 2
#define CAPSLOCK 4
#define LSHIFT 8
#define CODE 16
#define MARGIN 32
#define WORDERASER 64
#define CORRECT 128
#define RSHIFT 256
#define HALF 512
#define BS 1024
int r_pins[] = {8, 22, 24, 26, 28, 30, 32, 50};
int w_pins[] = {38, 40, 42, 44, 46, 48, 52};
int debounceThreshold = 135; // Milliseconds to wait to ensure keys have settled and we process them
// 10 11 12 13 14 15 17
char* kdata[][8] = { // Keypress
{"k", "l", ";", "'", "m", ",", "."}, // 1
{"u", "i", "o", "P", "!", "!", "j"}, // 2
{"7", "8", "9", "0", "-", "=", "!"}, // 3
{"!", "1", "2", "3", "4", "5", "6"}, // 4
{"!", "q", "w", "e", "r", "t", "y"}, // 5
{"!", "a", "s", "d", "f", "g", "h"}, // 6
{"!", "z", "x", "c", "v", "b", "n"}, // 7
{"!", "/", "!", "!", " ", "!", "!"}, // 16
};
char* udata[][8] = { // 'Uppercase' map
{"K", "L", ":", "\"", "M", "<", ">"}, // 1
{"U", "I", "O", "P", "!", "!", "J"}, // 2
{"&", "*", "(", ")", "_", "+", "!"}, // 3
{"!", "!", "@", "#", "$", "%", "^"}, // 4
{"!", "Q", "W", "E", "R", "T", "Y"}, // 5
{"!", "A", "S", "D", "F", "G", "H"}, // 6
{"!", "Z", "X", "C", "V", "B", "N"}, // 7
{"!", "?", "!", "!", " ", "!", "!"}, // 16
};
char* sdata[][8] = { // Special keys
{" ", " ", " ", " ", " ", " ", " "}, // 1
{" ", " ", " ", " ", "H", "E", " "}, // 2
{" ", " ", " ", " ", " ", " ", "D"}, // 3
{"Z", " ", " ", " ", " ", " ", " "}, // 4
{"T", " ", " ", " ", " ", " ", " "}, // 5
{"C", " ", " ", " ", " ", " ", " "}, // 6
{"L", " ", " ", " ", " ", " ", " "}, // 7
{"S", " ", "O", "M", " ", "W", "R"}, // 16
};
unsigned int flags = 0;
char gotChar = ' ';
char uChar = ' ';
unsigned int debounceWait = 0;
int capsLock = 0;
void setup() {
int i;
Serial.begin(9600);
delay(1500);
Serial.println("Setting up pins");
for (i = 0; i <=7; i++) {
pinMode(r_pins[i], INPUT_PULLUP);
}
for (i = 0; i <=6; i++) {
pinMode(w_pins[i], OUTPUT);
digitalWrite(w_pins[i], HIGH);
}
// Configuration display
Serial.print("Debounce threshold: "); Serial.println(debounceThreshold);
int sz = sizeof(flags);
Serial.print("unsigned int size: "); Serial.println(sz);
Serial.println("Ready...");
}
void loop() {
int r; int w; int val;
// Scan rows individually by bringing the column low and checking the rows for grounded pins
for (w = 0; w <= 6; w++) {
digitalWrite(w_pins[w], LOW);
for (r = 0; r <= 7; r++) {
val = digitalRead(r_pins[r]);
if (val == 0) {
// This signal is grounded, so we have a keypress
// Check to see if this is a Special Key
if (*sdata[r][w] != ' ') {
if (*sdata[r][w] == 'L') {
flags |= LSHIFT; // Left shift
} else if (*sdata[r][w] == 'S') {
flags |= RSHIFT; // Right shift
} else if (*sdata[r][w] == 'Z') {
flags |= TABS; // TabS
} else if (*sdata[r][w] == 'T') {
//flags |= TAB; // Tab
gotChar = '\t';
} else if (*sdata[r][w] == 'C') {
flags |= CAPSLOCK; // CAPSLOCK
} else if (*sdata[r][w] == 'O') {
flags |= CODE; // Code
} else if (*sdata[r][w] == 'M') {
flags |= MARGIN; // Margin
} else if (*sdata[r][w] == 'W') {
flags |= WORDERASER; // WordEraser
} else if (*sdata[r][w] == 'R') {
flags |= CORRECT; // Correct
} else if (*sdata[r][w] == 'H') {
flags |= HALF; // Half
} else if (*sdata[r][w] == 'D') {
// flags |= BS; // Back space
gotChar = '\b';
} else if (*sdata[r][w] == 'E') {
gotChar = '\n'; // Enter
}
if (debounceWait == 0) { debounceWait = millis(); } // Set the debounce timer if it isn't already
} else {
gotChar = *kdata[r][w];
uChar = *udata[r][w];
if (debounceWait == 0) { debounceWait = millis(); } // Set the debounce timer if it isn't already
}
}
}
digitalWrite(w_pins[w], HIGH);
}
// Finished scanning keyboard - if we've set the debounce timer, AND the debounce timer has passed
if (debounceWait != 0 && (millis() - debounceWait) > debounceThreshold) {
if (gotChar != '\0') {
if (capsLock || ((flags & LSHIFT) == (LSHIFT)) || ((flags & RSHIFT) == (RSHIFT))) {
gotChar = uChar;
}
Serial.print(gotChar);
}
if ((flags & CAPSLOCK) == CAPSLOCK) {
if (!capsLock) { capsLock = 1; } else { capsLock = 0; }
}
// Clear everything out for the next keypress
gotChar = '\0';
flags ^= flags;
debounceWait = 0;
}
}