diff --git a/Teensy_Continuity_Tester/Matrix_Decoder_2pp.ino b/Teensy_Continuity_Tester/Matrix_Decoder_2pp.ino new file mode 100644 index 0000000..623fdd9 --- /dev/null +++ b/Teensy_Continuity_Tester/Matrix_Decoder_2pp.ino @@ -0,0 +1,372 @@ +/* Copyright 2020 Frank Adams + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +// It will determine how a laptop keyboard matrix is wired using a Teensy ++2.0 on an FPC daughterboard. +// Open an editor on a computer and load or create a file that lists every key +// on the laptop keyboard that will be tested. Connect the FPC cable of the test keyboard +// to the Teensy/FPC board. Connect a USB cable from the Teensy to the computer. +// Wait a few seconds for the computer to see the Teensy as a keyboard. If numbers are reported on the screen +// before any keys are pressed, these pin numbers are shorted together and must be fixed. +// Press each key one by one on the test keyboard as listed on the editor screen. When a key +// is pressed on the test keyboard, the program detects which two pins on the FPC connector +// were connected. Those two pin numbers are sent over USB (separated by a TAB) and displayed +// on the editor. After sending the numbers, a DOWN ARROW is sent over USB to prepare for +// the next key. Once all keys on the test keyboard have been pressed, the file in +// the editor can be saved to create a row-column matrix. +// +// If your keyboard has diodes, you must pay attention to the order of the two pins that are reported by the Teensy. The code performs +// a bottom up test first, followed by a top down test so that one of the two tests will forward bias the diode. +// The first pin reported over USB is the cathode side and the second pin is the anode side. The diode direction must be taken into +// account when programming the TMK or Teensyduino keyboard routine. +// +// Revision History +// Rev 1.00 - June 6, 2020 - Original Release +// +// Load an array with the Teensy ++2.0 I/O numbers that correspond to FPC pins 1 thru 36. + int con_pin[] = {PIN_B7, PIN_B6, PIN_D0, PIN_B5, PIN_D1, PIN_B4, PIN_D2, PIN_B3, PIN_D3, PIN_B2, PIN_D4, PIN_B1, PIN_D5, PIN_B0, PIN_D6, PIN_E7, PIN_D7, PIN_E6, + PIN_E0, PIN_E1, PIN_F0, PIN_C0, PIN_F1, PIN_C1, PIN_F2, PIN_C2, PIN_F3, PIN_C3, PIN_F4, PIN_C4, PIN_F5, PIN_C5, PIN_F6, PIN_C6, PIN_F7, PIN_C7}; +// +// Define maximum and minimum pin numbers that will be tested. +// max_pin is usually set to the FPC connector size. min_pin is usually set to 1. The routine will start testing at pin 1 and go up to the max pin size. +// The max and min pin values can be adjusted to exclude testing the FPC traces at the edges if they are reported as shorted. An example would be if pin 1 +// and pin 36 are both grounds. They will be reported as tied together but they are not needed by the key matrix. In this case, set the +// min_pin to 2 or the max_pin to 35. +// +int max_pin = 36; // the keyboard FPC connector pin count. If set to 34, unsolder the LED or the code won't work +int min_pin = 1; // the first pin to be tested on the FPC connector (usually pin 1) +// +// load the key codes used in sending usb numbers, tab, and down arrow +int key_1 = KEY_1; +int key_2 = KEY_2; +int key_3 = KEY_3; +int key_4 = KEY_4; +int key_5 = KEY_5; +int key_6 = KEY_6; +int key_7 = KEY_7; +int key_8 = KEY_8; +int key_9 = KEY_9; +int key_0 = KEY_0; +int key_tab = KEY_TAB; +int key_down = KEY_DOWN; +// +// Function to set a pin as an input with a pullup so it's high unless grounded by a key press +void go_z(int pin) +{ + pinMode(pin, INPUT_PULLUP); + digitalWrite(pin, HIGH); +} + +// Function to set a pin as an output and drive it to a logic low (0 volts) +void go_0(int pin) +{ + pinMode(pin, OUTPUT); + digitalWrite(pin, LOW); +} + +// Function to send numbers over USB for display on an editor +void usb_num(int num) // the numbers 0 thru 33 are sent over usb as 1 thru 34 +{ + switch (num) { + case 0: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + break; + case 1: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + break; + case 2: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + break; + case 3: + Keyboard.set_key1(key_4); + Keyboard.send_now(); + break; + case 4: + Keyboard.set_key1(key_5); + Keyboard.send_now(); + break; + case 5: + Keyboard.set_key1(key_6); + Keyboard.send_now(); + break; + case 6: + Keyboard.set_key1(key_7); + Keyboard.send_now(); + break; + case 7: + Keyboard.set_key1(key_8); + Keyboard.send_now(); + break; + case 8: + Keyboard.set_key1(key_9); + Keyboard.send_now(); + break; + case 9: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_0); + Keyboard.send_now(); + break; + case 10: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(50); + Keyboard.set_key1(0); + Keyboard.send_now(); + delay(50); + Keyboard.set_key2(key_1); + Keyboard.send_now(); + break; + case 11: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_2); + Keyboard.send_now(); + break; + case 12: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_3); + Keyboard.send_now(); + break; + case 13: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_4); + Keyboard.send_now(); + break; + case 14: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_5); + Keyboard.send_now(); + break; + case 15: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_6); + Keyboard.send_now(); + break; + case 16: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_7); + Keyboard.send_now(); + break; + case 17: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_8); + Keyboard.send_now(); + break; + case 18: + Keyboard.set_key1(key_1); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_9); + Keyboard.send_now(); + break; + case 19: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_0); + Keyboard.send_now(); + break; + case 20: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_1); + Keyboard.send_now(); + break; + case 21: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(50); + Keyboard.set_key1(0); + Keyboard.send_now(); + delay(50); + Keyboard.set_key2(key_2); + Keyboard.send_now(); + break; + case 22: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_3); + Keyboard.send_now(); + break; + case 23: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_4); + Keyboard.send_now(); + break; + case 24: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_5); + Keyboard.send_now(); + break; + case 25: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_6); + Keyboard.send_now(); + break; + case 26: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_7); + Keyboard.send_now(); + break; + case 27: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_8); + Keyboard.send_now(); + break; + case 28: + Keyboard.set_key1(key_2); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_9); + Keyboard.send_now(); + break; + case 29: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_0); + Keyboard.send_now(); + break; + case 30: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_1); + Keyboard.send_now(); + break; + case 31: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_2); + Keyboard.send_now(); + break; + case 32: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + delay(50); + Keyboard.set_key1(0); + Keyboard.send_now(); + delay(50); + Keyboard.set_key2(key_3); + Keyboard.send_now(); + break; + case 33: + Keyboard.set_key1(key_3); + Keyboard.send_now(); + delay(20); + Keyboard.set_key2(key_4); + Keyboard.send_now(); + break; + } + delay(20); + Keyboard.set_key1(0); // clear out the key slots + Keyboard.set_key2(0); + Keyboard.send_now(); + delay(20); + Keyboard.set_key1(key_tab); // Tab over to position for next number + Keyboard.send_now(); + delay(20); + Keyboard.set_key1(0); // clear out the tab from the slot + Keyboard.send_now(); + delay(20); +} + +// Function to send a down arrow over usb to position for the next key +void down_arrow(void) { + Keyboard.set_key1(key_down); // send a down arrow + Keyboard.send_now(); + delay(20); + Keyboard.set_key1(0); // release the down arrow + Keyboard.send_now(); +} + +// --------------------------------------------------Setup----------------------------------- +void setup() { + for (int k = 0; k < max_pin; k++) { // loop thru all connector pins + go_z(con_pin[k]); // set each pin as an input with a pullup + } + delay(15000); // Wait for the host to connect to the Teensy as a keyboard. If 2 pins are shorted, + // you want the host to be ready to receive the pin numbers. +} +// +// -------------------------------------------Main Loop-------------------------------------- +// +void loop() { +// +// ***********Bottom up Test************ +// + for (int i=min_pin-1; imin_pin-1; p--) { // outer loop pin + go_0(con_pin[p]); // make the outer loop pin an output and send this pin low + for (int r=p-1; r>=min_pin-1; r--) { // inner loop pin + delayMicroseconds(10); // give time to let the signals settle out + if (!digitalRead(con_pin[r])) { // check for connection between inner and outer pins + usb_num(p); // send outer loop pin number over usb + usb_num(r); // send inner loop pin number over usb + down_arrow(); // send a down arrow over usb + while(!digitalRead(con_pin[r])) { // wait until key is released + ; + } + } + } + go_z(con_pin[p]); // return the outer loop pin to float with pullup + } +// +delay(25); // overall keyboard scan rate is about 30 milliseconds +// +}