Unlocking some puzzles requires building a better key... board

Unlocking some puzzles requires building a better key... board

  • Comments 2

Hi, this is Matt from the Windows Performance team.  Sometimes we are presented with problems that defy our usual troubleshooting and require a creative approach.  In a recent case, we needed a way to test the responsiveness of an application as text was typed into its fields.  Initially, we tested the program using a script that used the SendKeys method to time entry time.  Unfortunately, these tests aren’t completely realistic, since the script can be affected by the processor utilization on the system, and the script can’t create hardware interrupts like a keyboard does.  Realizing that only real keyboard input would be a valid test, and that the rate of typing needed to be reproduced exactly for each test, I set about building an automated keyboard. 

 

First, I found an old PS/2 style keyboard that hadn’t been used in years and opened it up.  Luckily, it was old enough to use all through-hole components, which made it easier to modify.  The main component I cared about was the keyboard encoder, which was a COP943C.  A search online turned up a datasheet for the keyboard encoder with a sample circuit design that looked very similar to this keyboard.  The document shows there are a couple of steps to determining which pins need to be shorted to generate a particular key. 

 

Each key has an ID number that is shown in figure one of the PDF (figure one below).  After finding the proper ID, a table is consulted to determine the row and column pins used to create that key code (figure two below).  Finally, those row and column numbers are translated into physical pins on the encoder using the schematic diagram (figure three below).  For example, the letter ‘a’ is number 31.  The matrix shows 31 is made with the L5 (column 6) pin and C6 (row 3) pin.  The pin out shows this to be physical pins 14 and 19.  When tested, shorting these pins creates an ‘a’.

 

See the video:

 

Figure 1: Key Codes

 ketpic1

Figure 2: Key Code Matrix

 key2

Figure 3: Encoder Pin Out

 key3

Now that we know how the keyboard circuit works, we need a method to generate key “presses.”  For this, I found a board I assembled a year or two ago using a PCB and components from moderndevice.com.  The board is an Arduino clone that is based on Atmel’s ATmega168 microcontroller.  One of the great things about using an Arduino is their IDE, which allows for C programming with a number of pre-defined functions to make development quick.  Also, the boot loader is already taken care of, which makes the work easier. 

 

Wiring the board to the keyboard was straightforward.  Figure 4 shows how to control a relay with an Arduino, and triggering a keyboard is rather similar.  A resistor is placed between a digital out pin of the Arduino and the base pin of a transistor.  The collector then goes to one pin of the keyboard encoder needed to type the letter desired, and the emitter goes to the other pin.

 

key4

Figure 4: Arduino-controlled Relay[ii]

In order to save on solder joints, I decided to chain together the transistors, which affected the key selection.  Additionally, because I wanted to leave the encoder in the original circuit and some of the pins were blocked by other components (resistors, capacitors), specific pins were selected.  Figure 5 shows the layout of the transistors.  These were soldered to a prototyping board with hook up wire to connect back to a breadboard with resistors and the Arduino and hook up wire soldered directly to the pins of the keyboard encoder.

key5

 

Figure 5: Transistor Layout

 

These pins selected allowed characters a, s, z, space, and enter to be typed.  All that remained was to write some software to trigger the transistors.  The code first sets the digital pins to output and logic low, turns on a LED to show it is working, then waits 3 minutes to allow time for the PC to boot and application in question to be launched.  The LED then goes out for a five-second warning, and then the loop sequence begins.  The loop turns on the LED, types “as z” followed by enter, then turns off the LED and sleeps for 2.5 seconds before starting again.

 

// Sample code to drive keyboard encoder

 

// Matt Burrough

 

// September, 2008

 

 

int ledPin = 13;             // Use digital pin 13 for a status LED

 

int sPin = 3;                // Connect pin 3 to the transistor connected to the s leads

 

int aPin = 4;                // Pin 4 is for a

 

int zPin = 5;                // Pin 5 is z

 

int enterPin = 6;            // Pin 6 is enter

 

int spacePin = 7;            // Pin 7 is space

 

int holdKey = 30;            // Milliseconds to "hold" each key down

 

int betweenKeys = 50;        // Milliseconds to wait between key presses

 

 

void setup() {               // Initial setup code (runs at power-on)

 

  setupPin(ledPin);          // Set up each pin with function below

 

  setupPin(sPin);        

 

  setupPin(aPin);

 

  setupPin(zPin);

 

  setupPin(enterPin);

 

  setupPin(spacePin);

 

  digitalWrite(ledPin, HIGH);  // Turn on the LED to show the board is on

 

  delay(180000);               // Wait 3 minutes to allow time for PC to boot

 

  digitalWrite(ledPin, LOW);   // Turn off the LED

 

  delay(5000);                 // Wait 5 seconds

 

}

 

 

void loop() {

 

  digitalWrite(ledPin, HIGH);  // Turn the LED on

 

 

 

  typeKey(aPin);               // Type keys

 

  typeKey(sPin);

 

  typeKey(spacePin);

 

  typeKey(zPin);

 

  typeKey(enterPin);

 

 

 

  digitalWrite(ledPin, LOW);    // Turn the LED off

 

  delay(2500);                  //Pause 2.5 seconds

 

}

 

 

void setupPin(int pin) {        // Used to set up pins...

 

  pinMode(pin, OUTPUT);         // Set the digital pin as output

 

  digitalWrite(pin, LOW);       // Turn off the pin

 

}

 

 

void typeKey(int pin) {         // Type a key...

 

  digitalWrite(pin, HIGH);      // "Press down" on a key

 

  delay(holdKey);               // Hold down the key

 

  digitalWrite(pin, LOW);       // "Release" the key

 

  delay(betweenKeys);           // Pause between keys

 

}

 

 

Figure 6: Code Sample

 key6

That’s how I made an automated keyboard.  I hope that you’ve found this post interesting; I’ll leave you with a photo of the finished product. 

 

 

 





Leave a Comment
  • Please add 3 and 2 and type the answer here:
  • Post
  • Arduinos are a ton of fun just to play with but that's way cool that you got to work with them as part of your paying job :-).

  • Updated video link: www.youtube.com/watch

Page 1 of 1 (2 items)