-
-
Save anonymous/c4d13350561a5cabc513968b2c66db1d to your computer and use it in GitHub Desktop.
TI Silent 700 keyboard controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************* | |
* Copyright 2018 Christian Sloma | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* 1. Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the following disclaimer. | |
* | |
* 2. Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation | |
* and/or other materials provided with the distribution. | |
* | |
* 3. Neither the name of the copyright holder nor the names of its contributors | |
* may be used to endorse or promote products derived from this software | |
* without specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
* POSSIBILITY OF SUCH DAMAGE. | |
******************************************************************************/ | |
// This is a controller for keyboards of the TI Silent 700 Terminal with Micro | |
// Switch SD logic scan modules. The normal keys have switch modules marked | |
// with 1A3S and the heavier keys are marked with 1A8S. | |
// | |
// Have a look at the Deskthority WIKI to learn more about these switches: | |
// https://deskthority.net/wiki/Micro_Switch_SD_Series | |
// | |
// === Setup === | |
// | |
// This is an Arduino sketch and I use it with a Teensy 2.0. | |
// - install teensyduino | |
// https://www.pjrc.com/teensy/td_download.html | |
// - you will also need the teensy loader to be running in the background | |
// https://www.pjrc.com/teensy/loader.html | |
// - in the Arduino Tools menu ... | |
// - make sure you have the correct board type (Teensy 2.0) | |
// - make sure you have selected a USB Type which contains "Keyboard" | |
// | |
// === Connecting the keyboard === | |
// | |
// You will need a multimeter to trace the hall sensors of the switches to the | |
// connector of the keyboard. The switches will have 4 pins. The outer pins are | |
// +5V and GND, the inner pins are used to drive the matrix. To differentiate | |
// between +5V and GND, have a look at the switches underneath the shift and | |
// control keys: two of the pins on these switches should be directly connected. | |
// The outer of these two pins is the GND pin. The pin next to GND is the input | |
// pin for the switch, and for the switches where it is not connected directly | |
// to GND, we will drive the pin low to activate the corrosponding switch. | |
// The pin on the opposite site of GND is the +5V. The inner pin next to +5V is | |
// the output pin of the switch, and we will read it to determine if the key is | |
// pressed or not. | |
// | |
// 1) Use the multimeter to determine which connections on the edge connector | |
// are connected to | |
// - GND and +5V. | |
// - the output pins of control and shift. | |
// - the input and output pins of the other switches. You should have 7 | |
// input connections and 8 output connections on the edge connector. | |
// 2) Connect GND and +5V to the corrosponding pins on the teensy. | |
// 3) Connect the input pins of the switches to pins D0 up to D6. | |
// (You might not want the LED to light up all the time. In that case use D7 | |
// instead of D6 and change the array 'outputPins' accordingly) | |
// 4) Connect the output pins of the switches to pins B0 to B7. | |
// 5) Connect the output pin of shift to pin F0 and the output pin of control to | |
// pin F1. | |
// | |
// === Setting up the key matrix === | |
// | |
// If the keyboard does not emit the keys you want, you will have to edit the | |
// 'keys' array in the code below. If you activate the serial monitor in arduino | |
// you should see a print statement with the row and column of pressed keys. | |
// This should help fill in the matrix. Note that indices in C start with 0. | |
// | |
// A list of the possible keycodes can be found here: | |
// https://www.pjrc.com/teensy/td_keyboard.html. | |
// | |
// I have added an additional keycode for the key next to the left shift key on | |
// ISO keyboards: KEY_ISO_BACKSLASH | |
// | |
// If you do not want the keyboard to emit keypresses during matrix setup remove | |
// the two slashes in front of SUPPRESS_KEY_EVENTS below. | |
//#define SUPPRESS_KEY_EVENTS | |
/******************************************************************************* | |
* This is the arduino keycode for the key next to the left shift key on ISO | |
* keyboards. | |
*/ | |
const unsigned int KEY_ISO_BACKSLASH = 0xF064u; | |
/******************************************************************************* | |
* The output pins of the teensy. These are used to decide which switches in the | |
* matrix are activated or not, and should be connected to the input pins of the | |
* switch sensors. | |
*/ | |
int outputPins[] = { | |
PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4, PIN_D5, PIN_D6 | |
}; | |
const int outputPinCount = sizeof(outputPins) / sizeof(outputPins[0]); | |
/******************************************************************************* | |
* The input pins from which the teensy reads whether a key in the matrix is | |
* pressed or not. These should be connected to the output pins of the switch | |
* sensors. | |
*/ | |
int inputPins[] = { | |
PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B5, PIN_B6, PIN_B7 | |
}; | |
const int inputPinCount = sizeof(inputPins) / sizeof(inputPins[0]); | |
/******************************************************************************* | |
* Number of keys that are wired in the matrix | |
*/ | |
const int keyCount = inputPinCount * outputPinCount; | |
/******************************************************************************* | |
* This array tells us whether a key is currently pressed or not. | |
*/ | |
bool keyState[keyCount]; | |
/******************************************************************************* | |
* The array of keycodes that will be emitted by the matrix. Rows are output | |
* pins and columns are input pins of the teensy. | |
*/ | |
unsigned int keys[keyCount] = { | |
// row 0 | |
KEY_SPACE, KEY_Z, KEY_ISO_BACKSLASH, KEY_ENTER, | |
KEY_TAB, KEY_CAPS_LOCK, KEY_SCROLL_LOCK, KEY_ESC, | |
// row 1 | |
KEY_SLASH, MODIFIERKEY_RIGHT_ALT, KEY_BACKSPACE, KEY_COMMA, | |
KEY_MINUS, KEY_1, KEY_0, KEY_PERIOD, | |
// row 2 | |
KEY_BACKSLASH, KEY_QUOTE, KEY_SEMICOLON, KEY_LEFT_BRACE, | |
KEY_RIGHT_BRACE, KEY_A, KEY_EQUAL, KEY_BACKSPACE, | |
// rows 3 to 6 | |
KEY_O, KEY_J, KEY_K, KEY_L, KEY_M, KEY_Q, KEY_P, KEY_N, | |
KEY_G, KEY_B, KEY_C, KEY_D, KEY_E, KEY_I, KEY_H, KEY_F, | |
KEY_7, KEY_2, KEY_3, KEY_4, KEY_5, KEY_9, KEY_8, KEY_6, | |
KEY_W, KEY_R, KEY_S, KEY_T, KEY_U, KEY_Y, KEY_X, KEY_V | |
}; | |
/******************************************************************************* | |
* The input pins of the shift and control key sensors are always connected to | |
* ground, and therefore always active. fixedPins contains the input pins of the | |
* teensy to which the output pins of these switches are connected. | |
*/ | |
int fixedPins[] = { | |
PIN_F0, PIN_F1 | |
}; | |
const int fixedPinCount = sizeof(fixedPins) / sizeof(fixedPins[0]); | |
/******************************************************************************* | |
* This array tells us whether one of the always activated switches is currently | |
* pressed or not. | |
*/ | |
bool fixedKeyState[fixedPinCount]; | |
/******************************************************************************* | |
* This array used to determine which keycodes the always activated switches | |
* should emit. | |
*/ | |
unsigned int fixedKeys[fixedPinCount] = { | |
MODIFIERKEY_SHIFT, MODIFIERKEY_CTRL | |
}; | |
void setup() | |
{ | |
Serial.begin(9600); | |
for (int outputIndex = 0; outputIndex < outputPinCount; outputIndex++) | |
{ | |
pinMode(outputPins[outputIndex], OUTPUT); | |
digitalWrite(outputPins[outputIndex], HIGH); | |
} | |
for (int inputIndex = 0; inputIndex < inputPinCount; inputIndex++) | |
{ | |
pinMode(inputPins[inputIndex], INPUT_PULLUP); | |
} | |
for (int keyIndex = 0; keyIndex < keyCount; keyIndex++) | |
{ | |
keyState[keyIndex] = false; | |
} | |
for (int fixedIndex = 0; fixedIndex < fixedPinCount; fixedIndex++) | |
{ | |
pinMode(fixedPins[fixedIndex], INPUT_PULLUP); | |
fixedKeyState[fixedIndex] = false; | |
} | |
} | |
void loop() | |
{ | |
for (int outputIndex = 0; outputIndex < outputPinCount; outputIndex++) | |
{ | |
digitalWrite(outputPins[outputIndex], LOW); | |
// has to be larger than the sum of rise/fall time (10 µs) and propagation | |
// delay (1.1 µs); see Micro_Switch_SD16_Keyswitch_Modules.pdf, page 2 | |
delayMicroseconds(15); | |
for (int inputIndex = 0; inputIndex < inputPinCount; inputIndex++) | |
{ | |
int keyIndex = (outputIndex * inputPinCount) + inputIndex; | |
bool newState = !digitalRead(inputPins[inputIndex]); | |
if (newState != keyState[keyIndex]) | |
{ | |
if (newState) | |
{ | |
Serial.print("output: "); | |
Serial.print(outputIndex); | |
Serial.print(", input: "); | |
Serial.println(inputIndex); | |
#ifndef SUPPRESS_KEY_EVENTS | |
Keyboard.press(keys[keyIndex]); | |
#endif | |
} | |
else | |
{ | |
#ifndef SUPPRESS_KEY_EVENTS | |
Keyboard.release(keys[keyIndex]); | |
#endif | |
} | |
keyState[keyIndex] = newState; | |
} | |
} | |
digitalWrite(outputPins[outputIndex], HIGH); | |
} | |
for (int fixedIndex = 0; fixedIndex < fixedPinCount; fixedIndex++) | |
{ | |
bool newState = !digitalRead(fixedPins[fixedIndex]); | |
if (newState != fixedKeyState[fixedIndex]) | |
{ | |
if (newState) | |
{ | |
Serial.print("fixed: "); | |
Serial.println(fixedIndex); | |
#ifndef SUPPRESS_KEY_EVENTS | |
Keyboard.press(fixedKeys[fixedIndex]); | |
#endif | |
} | |
else | |
{ | |
#ifndef SUPPRESS_KEY_EVENTS | |
Keyboard.release(fixedKeys[fixedIndex]); | |
#endif | |
} | |
fixedKeyState[fixedIndex] = newState; | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment