A Keyboard And Other Good Stuff
Before I write about the keyboard here’s some other stuff.. For months now I have been fiddling with design details for TLC-MBC but at the same time just itching to get it onto a PCB. Well… the wait is almost over – a few weeks ago Aslak3 sent me a PLCC44 dip adapter so that I could test the 65SPI on TLC_MBC. My initial tests proved to me that the circuitry was correct and the 65SPI did indeed work. This was the last thing to do before the PCB design was finalized, and so a couple of weeks ago I sent off to Seeed Studio for set of TLC-MBC PCBs. Delivery is usually about four weeks so I have a couple of weeks more to wait… Once I have received the PCBs and verified them, I shall put the Kicad project on my Github account.In the meantime here’s a preview.
I am looking for a keyboard and have a couple of requirements of it:
- It is small: I shall be making a case for TLC-MBC so I don’t care what case the keyboard is in, it will be ripped out, but the width of the keys alone should be no more than 19cm give or take a cm.
- The keys should be on a PCB and not on one of those flexible circuit thingies – I will need to hack the matrix and that’s difficult when the cicuit is on flexible plastic sheet.
- I would prefer mechanical switches, but I don’t know if they are available on the smaller keyboards.
I did find one about the right size on eBay but when it arrived I found the matrix to be on flexi-plastic and so no good for my needs. So, If anyone is reading this and you know of a suitable keyboard please let me know in the comments below. Thank you.
A Keyboard Decoder
For a while now, I have wanted a keyboard so that I no longer need the PC to use TLC-MBC and I decided that instead of more programming I would work on a keyboard decoder. There are several ways of doing this:
- A microcontroller can be connected to the keyboard matrix, it decodes which key has been pressed and sends out either a scancode or the ASCII character code for that key. This is a popular way of getting the job done.
- The keyboard matrix could be connected to a couple of ports on a PIA/VIA, this would put all the decoding work on the proccesor’s shoulders.
- A few pins of a PIA/VIA port could be used to decode the output from a PS2 keyboard.
- A keyboard controller such as the KR2376-ST could be used, a possible drawback is that it requires multiple voltages and a specific keyboard matrix to work.
All of these are viable ways of getting the job done, but they have been done before. A while back I “discovered” the use of diodes when I had a problem with interrupts and I thought it might be interesting to use diodes along with a bit of TTL to decode a keyboard matrix and output either a scan-code or the ASCII value of the key.
This would be a completely hardware solution – NO software. I have built a 4×5 keyboard, I shall be using this as the test-subject until I get a “real” keyboard. It has 4 rows and 5 columns. I built it months ago with the idea of using it as a hex keypad with some 7 segment leds for output, but that never happened as I made the video card and connected the PC via serial…
So I would need a way of selecting each row in turn. I decided to use a 74HC14 based clock pumped into a 7493 counter which in turn was connected to a 74138 1 of 8 decoder. This was bread-boarded and it worked each row was selected, active low, in sequence.
Moving on to the columns, I started playing around with the diodes. After multiple tries, I realized the polarity of the rows was wrong. I needed a high level for the active row. I could either add inverters to the 8 outputs of the 74138 or I could build a decoder and remove the 74138. I decided on the later and I chose to make a 2-4 decoder for now as it is less chips to wire up. I used a 7408 quad 2 input AND gate and two spare inverters from the 74HC14.
The columns were tied low through a resistor and their ends connected to a diode each. This worked – kinda.. As the diodes were all connected together this only let me know that a button had been pressed but not which column. So I thought why not have multiple diodes on each column to decode the column number and the “binary bus” was born. This was good! I had 2 lines for rows and now 4 lines for columns and this should work for upto 15 columns – thats 60 keys.
So, now I have a total of 6 bits and from their value I can tell which key has been pressed but how does the computer know WHEN it has been pressed? This keyboard needs a Strobe output. Lines b0-b3 are all low when no keys are pressed. A high on any of them indicates a key press. I added a 7432 quad 2 input OR gate and tied their output to a 74121 one shot to output a high pulse whenever a key was pressed. I also used the 7432 output to go into a NAND gate so that I could stop the 7493 and read it’s value for the row count.Here’s the bread board layout so far.
So far so good.. But there is a problem – two in fact:
- If multiple keys are pressed their combined value is output on the binary bus.
- Thinking ahead, how do I deal with shift, control and alt in light of the first problem?
To fix the first problem I added a 74LS574 Octal latch that is triggered by the Strobe from the 74121. This will hold the value of the first key pressed and ignore all subsequent key presses until the first key is released. This works for me as I am no touch typist.
The second problem is a little more awkward. Shift, Control and Alt have to be seperate from the matrix, this means there are now 6+3 equals 9 output lines – I would need a port and one bit from another port – wastful!! And this is for just a scan-code the computer still has to figure out the ASCII value. So why not do like the KR2376 and use a rom? Or in this case an eeprom, then the nine lines could be fed into the address pins and the data bus can output the ASCII value. I can use the top address line as a “bank” switch to select between ASCII and scan-code output.
I’m going to use a 28C64 – 8K x 8 as I have a couple of them. I’m using a total of 10 address lines so I could use a 1K x 8 eeprom but the only ones I have seen are serial so no good for this application. I shall just tie the unused address lines on the 28C64 to ground.
The final addition is a 74ls645 Octal Buffer on the eeprom’s data bus as I’m not sure the eeprom can drive the short ribbon cable that will be eventually used to connect to TLC-MBC’s VIA port. so here in all it’s glory is the schematic for my keyboard controller/decoder.
This is for the full 60 key (plus 3) keyboard and here is what the PCB will look like courtesy of Kicad’s 3D viewer (click for a large view). As you can see, in the end I used 9 chips and 32 diodes! Chip choice was mostly driven by what I had on hand so there’s a mixture:
- 74LS645 – Wanted to use 74LS241 but didn’t have any.
For testing I’ve hooked up a 12 segment led bar to the output of the 74LS645, this way I can see if the values are correct. All that remains is to program an eeprom, which I did after assigning the blank keys a value each. While this setup works, I’m still not totally confident about some timing, specifically the strobe and the actual data. The strobe enables the 74LS574 to latch the row/col data. The data then goes to the eeprom, gets decoded and the resulting data is sent thru the 74LS645. I am using the strobe signal to also tell the computer that a new key has been pressed and I’m not sure that the new value will be ready. So I have modified the circuit slightly. The spare NAND gate is now on the strobe line before it joins the the output connector, this will both invert and delay the strobe signal so that the data and strobe will be more in sync.
I’m happy that I started with a 2-4 decoder, had I tried the 3-8 decoder that would have resulted in an additional 2 chips (74LS11) though it would cut down the diodes to a total of 13. Board space would have been about the same but laying out the PCB would have been more difficult.
I have designed it as a single sided board and this has resulted in just over 50 jumpers and 426 drill holes! I’m debating whether to make it myself or get Seeed to do it for about £12 and roughly a four week wait… Anyway, for those of you that are interested, I will upload the Kicad project for this upto my Github account in the next day or so.