Skip to content

Instantly share code, notes, and snippets.

/TiSilent.ino Secret
Created Feb 17, 2018

Embed
What would you like to do?
TI Silent 700 keyboard controller
/*******************************************************************************
* 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
You can’t perform that action at this time.