After managing to build a board to read keystrokes on an Apple IIe keyboard and send them to a modern computer via USB, now I'm trying to tackle the job going in the opposite direction.
After some research and testing, it looks like the IIe is pulsing the "columns" pins about 20 times a second. In normal operation, a switch in the matrix keyboard connects a column to a "row" and the computer reads that as a keypress. The timing is important. If I set a row pin high, the IIe cycles through all the column combinations until the row is set low again.
So, what I've done as a proof of concept is hook up a column to pin 10 and a row to pin 8. When I trigger the keypress (in this case, by sending "a" via serial) the input value of the column pin is sent out to the row pin, and the proper letter shows up on the IIe screen. Success! (I'm leaving the USB host problem until later, most likely to be handled by a Circuits@Home shield)
void setup()
{
// initialize the serial communication:
Serial.begin(115200);
pinMode(10, INPUT); // column
pinMode(8, OUTPUT); // row
digitalWrite(8,LOW);
digitalWrite(10,LOW);
}
void loop()
{
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
if(inByte == 'a') { // i typed "a"
inputPin = 10; // set the in/out pins
outputPin = 8;
} else {
inputPin = 0; // something else was typed, so set the in/out to an unused pin
outputPin = 0;
}
}
if(inputPin > 0) {
val = digitalRead(inputPin); // read the input pin
digitalWrite(outputPin,val); // send the pulse to output
} else {
digitalWrite(outputPin,LOW); // stop pulsing output
}
}
To cover the whole matrix, however, there are 8 columns and 10 rows. And modifier keys (shift, control) that get read when the pin is grounded.
So, i need more pins than the ATMega328 provides - i could use a larger Arduino, but my eventual goal is to embed just the ATMega on a smaller board.
I've read here and elsewhere about ganging up inputs with a 4021 IC (shift register). Would this be a good application? I imagine I would put all the columns into one register, and when I want to trigger the key that's a combination of column 3 and row 4, I could read the third bit from the register, and pulse row 4 in time with it.
Would that work, or am I wrong about how the register works? Will I be able to read the 4021 state fast enough to pulse the row pin in time with the input?