/* requires keypad library by Mark Stanley, Alexander Brevig from: http://www.arduino.cc/playground/Code/Keypad Uses the PJRC Teensy++ 2.0 and Teensyduino libraries, specifically USB HID and Keyboard(): http://www.pjrc.com/teensy/teensyduino.html */ #include // added breakout pins for DISK READ LED, KEYBOARD SWITCH, and 40/80 COLUMN SWITCH (rev.4 board) int LEDPin = 8; int DvorakPin = 9; int ColumnsPin = 10; /* Declares the matrix rows/cols of the Apple IIc keyboard. */ // Prevent compiler warning about casts from unsigned ints to chars #define C(x) ((char) (x)) const byte ROWS = 8; // rows const byte COLS = 10; // columns char keys[ROWS][COLS] = { { C(KEY_ESC), C(KEY_1), C(KEY_2), C(KEY_3), C(KEY_4), C(KEY_6), C(KEY_5), C(KEY_7), C(KEY_8), C(KEY_9) }, { C(KEY_TAB), C(KEY_Q), C(KEY_W), C(KEY_E), C(KEY_R), C(KEY_Y), C(KEY_T), C(KEY_U), C(KEY_I), C(KEY_O)}, { C(KEY_A), C(KEY_D), C(KEY_S), C(KEY_H), C(KEY_F), C(KEY_G), C(KEY_J), C(KEY_K), C(KEY_SEMICOLON), C(KEY_L)}, { C(KEY_Z), C(KEY_X), C(KEY_C), C(KEY_V), C(KEY_B), C(KEY_N), C(KEY_M), C(KEY_COMMA), C(KEY_PERIOD), C(KEY_SLASH)}, { 0, 0, 0, 0, 0, 0, C(KEY_BACKSLASH), C(KEY_EQUAL), C(KEY_0), C(KEY_MINUS)}, { 0, 0, 0, 0, 0, 0, C(KEY_TILDE), C(KEY_P), C(KEY_LEFT_BRACE), C(KEY_RIGHT_BRACE)}, { 0, 0, 0 , 0, 0, 0, C(KEY_ENTER), C(KEY_UP), C(KEY_SPACE), C(KEY_QUOTE)}, { 0, 0, 0, 0, 0, 0, C(KEY_BACKSPACE), C(KEY_DOWN), C(KEY_LEFT), C(KEY_RIGHT)}, }; char Fkeys[2][10] = { {C(KEY_1), C(KEY_2), C(KEY_3), C(KEY_4), C(KEY_5), C(KEY_6), C(KEY_7), C(KEY_8), C(KEY_9), C(KEY_0)}, {C(KEY_F1), C(KEY_F2), C(KEY_F3), C(KEY_F4), C(KEY_F5), C(KEY_F6), C(KEY_F7), C(KEY_F8), C(KEY_F9), C(KEY_F10)} }; /* Keyboard matrix X0 1 2 3 4 5 6 7 8 9 Y0 ESC 1 2 3 4 6 5 7 8 9 1 TAB Q W E R Y T U I O 2 A D S H F G J K ; L 3 Z X C V B N M < > ? 4 \ + 0 - 5 ~ P [ ] 6 RET UP SPC " 7 DEL DN LT RT Matrix J9 Teensy X0 31 26 1 24 4 2 22 5 3 8 14 4 14 17 5 6 13 6 10 15 7 1 3 8 4 12 9 2 11 Y0 12 16 1 33 25 2 18 7 3 20 38 4 3 2 5 5 1 6 7 0 7 9 27 NC 13 17 30 GND 21 SFT 34 24 CTL 32 23 CMD 16 8 CMD 26 20 CAPS 28 21 J9 pinout 1 X7 2 X9 3 Y4 4 X8 5 Y5 6 X5 7 Y6 8 X3 9 Y7 10 X6 11 DISK LED (5v) 12 Y0 13 NC 14 X4 15 KEYBOARD SW 16 CLOSED APPLE 17 NC 18 Y2 19 40/80 COL SWITCH 20 Y3 21 GROUND ??? 22 X2 23 GROUND ??? 24 X1 25 POWER LED (5v) 26 OPEN APPLE 27 LED GROUND ??? 28 CAPS LOCK 29 RESET 30 NC 31 X0 32 CONTROL 33 Y1 34 SHIFT */ byte rowPins[ROWS] = { // Y0 - Y9 16, 25, 7, 38, 2, 1, 0, 27 }; //connect to the row pinouts of the keypad byte colPins[COLS] = { // X0 - X7 26, 4, 5, 14, 17, 13, 15, 3, 12, 11 }; //connect to the column pinouts of the keypad Keypad KPD = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); const int SHIFTPin = 24; // the pin that the shift key is attached to const int CTRLPin = 23; // the pin that the control key is attached to const int APPLEPin1 = 43; // the pin that the open-apple key is attached to const int APPLEPin2 = 44; // the pin that the closed-apple key is attached to const int CAPSPin = 21; // these pins are special in that they are dis/connected to ground, instead of to a row/col /*** open/closed apple are grounded through resistors on the //c. need to detect voltage drop as analogread, not digital. must be on analog pin. ***/ char modifierKeys[4]; #define KEY_CAPS_UNLOCK 0 boolean resetCapsLock = false; // Allows one caps unlock signal. unsigned long dTime = 0; boolean CAPSLock = false; // Initialize this to a reasonable value. boolean FKEYS = false; // used to set numbers to F-Key equivalent. currently tied to caps lock void setup() { pinMode(SHIFTPin, INPUT); pinMode(CTRLPin, INPUT); pinMode(APPLEPin1, INPUT); pinMode(APPLEPin2, INPUT); digitalWrite(APPLEPin1, HIGH); digitalWrite(APPLEPin2, HIGH); digitalWrite(SHIFTPin, HIGH); digitalWrite(CTRLPin, HIGH); pinMode(CAPSPin, INPUT); digitalWrite(CAPSPin, HIGH); // Turn on the DISK READ LED (rev4 board) // digitalWrite(LEDPin, HIGH); // This gives time for the keyboard to hook up to the PC. // Otherwise the caps lock state may be incorrect. delay(1000); } void loop() { //probably should be on an interrupt, to catch high->low transition // Only do something if the pin is different from previous state. boolean newCaps = digitalRead(CAPSPin) ? false : true; if ( (CAPSLock != newCaps) && !resetCapsLock) { CAPSLock = newCaps; // Remember new CAPSLock. Keyboard.set_key6((uint8_t) KEY_CAPS_LOCK); // Send KEY_CAPS_LOCK. dTime = millis(); // Reset delay timer. resetCapsLock = true; // Serial.print("Caps = "); // Serial.println(CAPSLock); // Turn on the LED for caps lock. // digitalWrite(LED, CAPSLock ? HIGH : LOW); } if ( resetCapsLock && (millis() - dTime) > 10) { Keyboard.set_key6(KEY_CAPS_UNLOCK); resetCapsLock = false; } // If caps lock is set, then turn number keys into function keys. FKEYS = CAPSLock; /*char CAPSState = digitalRead(CAPSPin); if (CAPSState == LOW) { Keyboard.set_key6(KEY_CAPS_LOCK); } else { Keyboard.set_key6(0); } */ char SHIFTState = digitalRead(SHIFTPin); if (SHIFTState == LOW) { modifierKeys[0] = MODIFIERKEY_SHIFT; digitalWrite(SHIFTPin, HIGH); } else { digitalWrite(SHIFTPin, HIGH); modifierKeys[0] = 0; } char CTRLState = digitalRead(CTRLPin); if (CTRLState == LOW) { modifierKeys[1] = MODIFIERKEY_CTRL; digitalWrite(CTRLPin, HIGH); } else { modifierKeys[1] = 0; digitalWrite(CTRLPin, HIGH); } char OAPPLEState = analogRead(APPLEPin2); char CAPPLEState = analogRead(APPLEPin1); // *** NOW USING CLOSED APPLE AS ALT/OPTION if (OAPPLEState < 20) { modifierKeys[2] = MODIFIERKEY_GUI; digitalWrite(APPLEPin1, HIGH); } else { modifierKeys[2] = 0; digitalWrite(APPLEPin1, HIGH); } if (CAPPLEState < 20) { modifierKeys[3] = MODIFIERKEY_ALT; digitalWrite(APPLEPin2, HIGH); } else { modifierKeys[3] = 0; digitalWrite(APPLEPin2, HIGH); } // to use the TILDE key as ALT/OPTION /* modifierKeys[3] = 0; if( KPD.isPressed(KEY_TILDE) ) { modifierKeys[3] = MODIFIERKEY_ALT; } */ // *** NOW USING CLOSED APPLE AS ALT/OPTION Keyboard.set_modifier( modifierKeys[0] | modifierKeys[1] | modifierKeys[2] | modifierKeys[3] ); KPD.getKeys(); // Scan for all pressed keys. 6 Max, + 4 modifiers. Should be plenty, but can be extended to 10+ // Set keyboard keys to default values. Keyboard.set_key1(0); Keyboard.set_key2(0); Keyboard.set_key3(0); Keyboard.set_key4(0); Keyboard.set_key5(0); //Keyboard.set_key6(0); /* based on suggestion from Craig Brooks uses CAPS LOCK to turn number keys into F-Key equivalent. */ // Update keyboard keys to active values. if ( KPD.key[0].kchar && ( KPD.key[0].kstate == PRESSED || KPD.key[0].kstate == HOLD )) { //Serial.println(FKEYS); if (FKEYS) { // number keys 1 through 0 for f1 - f10 if ((KPD.key[0].kchar >= 0x1E) && (KPD.key[0].kchar <= 0x27)) { KPD.key[0].kchar += 0x1C; // Serial.println( KPD.key[0].kchar, HEX ); // - and = for f11 and f12 } else if ( KPD.key[0].kchar == 0x2D || KPD.key[0].kchar == 0x2E ) { KPD.key[0].kchar += 0x17; } } Keyboard.set_key1( KPD.key[0].kchar ); } if ( KPD.key[1].kchar && ( KPD.key[1].kstate == PRESSED || KPD.key[1].kstate == HOLD )) Keyboard.set_key2( KPD.key[1].kchar ); if ( KPD.key[2].kchar && ( KPD.key[2].kstate == PRESSED || KPD.key[2].kstate == HOLD )) Keyboard.set_key3( KPD.key[2].kchar ); if ( KPD.key[3].kchar && ( KPD.key[3].kstate == PRESSED || KPD.key[3].kstate == HOLD )) Keyboard.set_key4( KPD.key[3].kchar ); if ( KPD.key[4].kchar && ( KPD.key[4].kstate == PRESSED || KPD.key[4].kstate == HOLD )) Keyboard.set_key5( KPD.key[4].kchar ); //if( KPD.key[5].kchar && ( KPD.key[5].kstate==PRESSED || KPD.key[5].kstate==HOLD )) //Keyboard.set_key6( KPD.key[5].kchar ); Keyboard.send_now(); Keyboard.set_modifier(0); }