Then I recently stumbled on a blogpost where someone connects a ZX81 keyboard to the Arduino Leonardo, and I found a cheap (€12,-) Leonardo-clone so I decided this was the way to go.
The board came with front headers, which makes connecting the keyboard super easy.
This is the C64 Keyboard matrix: ( diagram from the 'WaitingForFriday' blog)
It is connected to the Arduino as follows:
A - D0
B - D1
C - D2
D - D3
E - D4
F - D5
G - D6
H - D7
0 - D8
1 - D9
2 - D10
3 - D11
4 - A0
5 - A1
6 - A2
7 - A3
The code can be a mix of the code from 'Biosrythm' and TechTonic . :
#include <Keyboard.h> // ZX81 USB Keyboard for Leonardo // (c) Dave Curran // 2013-04-27 // Modified with Function keys by Tony Smith // 2014-02-15 // Adapted for use with Commodore 64 Keyboard by Cees Meijer // 2015-11-04 // Enable the debug mode (serial output) by keeping F7 pressed when
// starting the program // Special Commodore graphic characters are not implemented #define NUM_ROWS 8 #define NUM_COLS 8 #define SHIFT_ROW 3 #define SHIFT_COL 1 #define RSHIFT_ROW 4 #define RSHIFT_COL 6 #define F7_ROW 7 #define F7_COL 7 #define DEBOUNCE_VALUE 100 #define REPEAT_DELAY 500 // Keymap for normal use byte keyMap[NUM_ROWS][NUM_COLS] = { {'1', '3', '5', '7', '9', '+', '$', KEY_BACKSPACE}, {KEY_LEFT_ARROW, 'w', 'r', 'y', 'i', 'p', '*', KEY_RETURN}, {'~', 'a', 'd', 'g', 'j', 'l', ';', KEY_LEFT_ARROW}, {'~', 0 , 'x', 'v', 'n', ',', '/', KEY_UP_ARROW}, {' ', 'z', 'c', 'b', 'm', '.', 0 , KEY_F1}, {'~', 's', 'f', 'h', 'k',':', '=' , KEY_F3}, {'q', 'e', 't', 'u', 'o', '@', KEY_UP_ARROW, KEY_F5}, {'2', '4', '6', '8', '0', '-', '~', KEY_F7} }; // Keymap if Shift is pressed byte keyMapShifted[NUM_ROWS][NUM_COLS] = { {'!', '#', '%', '\'', ')', '+', '$', KEY_BACKSPACE}, {KEY_LEFT_ARROW, 'W', 'R', 'Y', 'I', 'P', '*', KEY_RETURN}, {'~', 'A', 'D', 'G', 'J', 'L', ']', KEY_RIGHT_ARROW}, {'~', 0 , 'X', 'V', 'N', '<', '?', KEY_DOWN_ARROW}, {' ', 'Z', 'C', 'B', 'M', '>', 0 ,KEY_F2}, {'~', 'S', 'F', 'H', 'K','[', '=', KEY_F4}, {'Q', 'E', 'T', 'U', 'O', '@', KEY_UP_ARROW, KEY_F6}, {'"', '$', '&', '(', '0', '-', '~', KEY_F8} }; // Global Variables int debounceCount[NUM_ROWS][NUM_COLS]; int altKeyFlag; bool serial_output; // Define the row and column pins byte colPins[NUM_COLS] = {0,1,2 ,3 ,4 ,5 ,6 ,7}; // A,B,C,D,E,F,G,H byte rowPins[NUM_ROWS] = {8,9,10,11,A0,A1,A2,A3}; // SETUP void setup() { // Set all pins as inputs and activate pull-ups serial_output = false; for (byte c = 0 ; c < NUM_COLS ; c++) { pinMode(colPins[c], INPUT); digitalWrite(colPins[c], HIGH); // Clear debounce counts for (byte r = 0 ; r < NUM_ROWS ; r++) { debounceCount[r][c] = 0; } } // Set all pins as inputs for (byte r = 0 ; r < NUM_ROWS ; r++) { pinMode(rowPins[r], INPUT); } // Function key is NOT pressed altKeyFlag = ALT_KEY_OFF; pinMode(rowPins[F7_ROW], OUTPUT); if (digitalRead(colPins[F7_COL]) == LOW) serial_output = true; // Initialise the keyboard if (serial_output ) { Serial.begin(9600); } else { Keyboard.begin(); } } // LOOP void loop() { bool shifted = false; bool r_shifted = false; bool keyPressed = false; // Check for the Shift key being pressed pinMode(rowPins[SHIFT_ROW], OUTPUT); if (digitalRead(colPins[SHIFT_COL]) == LOW) shifted = true; pinMode(rowPins[RSHIFT_ROW], OUTPUT); if (digitalRead(colPins[RSHIFT_COL]) == LOW) shifted = true; pinMode(rowPins[SHIFT_ROW], INPUT); pinMode(rowPins[RSHIFT_ROW], INPUT); for (byte r = 0 ; r < NUM_ROWS ; r++) { // Run through the rows, turn them on pinMode(rowPins[r], OUTPUT); digitalWrite(rowPins[r], LOW); for (byte c = 0 ; c < NUM_COLS ; c++) { if (digitalRead(colPins[c]) == LOW) { // Increase the debounce count debounceCount[r][c]++; // Has the switch been pressed continually for long enough? int count = debounceCount[r][c]; if (count == DEBOUNCE_VALUE) { // First press keyPressed = true; pressKey(r, c, shifted); } else if (count > DEBOUNCE_VALUE) { // Check for repeats count -= DEBOUNCE_VALUE; if (count % REPEAT_DELAY == 0) { // Send repeat keyPressed = true; pressKey(r, c, shifted); } } } else { // Not pressed; reset debounce count debounceCount[r][c] = 0; } } // Turn the row back off pinMode(rowPins[r], INPUT); } digitalWrite(rowPins[RSHIFT_ROW], LOW); digitalWrite(rowPins[SHIFT_ROW], LOW); } void pressKey(byte r, byte c, bool shifted) { // Send the keypress if (serial_output)
{
Serial.print("|");Serial.print("\r\n");Serial.print("|");
Serial.print(r);Serial.print(",");Serial.print(c);Serial.print(":");
} byte key = shifted ? keyMapShifted[r][c] : keyMap[r][c]; if (serial_output) { if (key > 0){ Serial.write(key);} } else { if (key > 0 ) Keyboard.write(key); } }