One critical issue arises when attaching mechanical switches, as found in computer keyboards, to digital electronics: switch bounce.
When switches are opened and closed, the connection across the switch contacts does not cleanly transition from its previous state to its new state. Instead the switch contacts will (literally) bounce between the old state and new state before finally, after a period of a few milliseconds, settling on the new state. This presents a problem when only a single digital transition is required for each open or close of the switch. Whilst MAXI09’s keyboard is useable without addressing this problem, phantom key events have been observed and I’ve been meaning to tackle the problem for some time.
Solutions to this problem are possible using dedicated circuit elements or, which is nowadays more common, software.
Using software, there are a couple of different approaches but the one I’ve chosen to implement in my keyboard controller is the simplest: a “settling time”; a period of time in which the input must stay at the same value before a transition is registered.
In my keyboard controller’s case this is complicated by the fact that all 78 keys need to have this logic applied to them. But none the less the changes needed to implement key switch denouncing was fairly simple.
An array of counters has been introduced. This counter is zero when no transitions are pending, ie at start-up and directly after a key event has been generated; when it is zero it is not counting up. Inside the periodic timer interrupt handler, If a key state change is detected the counter on each key will be given the value 1. Otherwise, and only if the counter is non zero, the counter for each key will count up until it reaches a threshold value. Only when it reaches the threshold value will the key up or key down (determined by looking at the current state) event be generated. The counter is then reset to zero, stopping it. The following graph illustrates this behaviour:
At present the timer interrupt runs 200 times per second and the threshold value is 5, though these values probably need tweaking.
A small (memory) inefficiency exists: the debounce counter values are held in bytes, but since the counter never exceeds 15, it would be possible to hold the counter value for two keys in a single byte. Though the controller in the MAXI09 board, an ATMega8515, has a pretty generous 512 bytes of RAM – easily enough to hold a byte for each key – at some point I will implement this memory saving for the interesting technical challenge. Actually there is another inefficiency: a bounce counter is held for each of the 128 possible scan codes, not just the scancodes which are actually mapped to a key.
All told keyboard debouncing is a nice addition to the MAXI09. While bounces weren’t a massive problem, the odd random key event was generated causing a bit of a weird typing experience. The debouncing code appears to completely eliminate this problem.
The other thing I’ve been working on is a proper computer case for the MAXI09 PCB and keyboard. After considering a few options, I settled on acrylic as the material, laser cut and jointed with finger joints. The biggest challenge was finding and learning the CAD software needed to produce the needed laser cutting design files. After seeking some advice from the local makerspace, I settled on Autodesk Fusion 360. The last time I did any CAD it was with Autodesk AutoCAD, running in DOS on a 386. Boy has CAD changed just a bit since then!
The learning curve for such an comprehensive program as Fusion is immense, but it has also been extremely enjoyable navigating it.
Here’s a video, rendered from within Fusion 360, of the case I’ve designed:
One thing I’ve done is expose the three LEDs: the RGB LED attached to the keyboard controller, the power LED, and DISCO’s “user” LED. These will be attached via flying LEDs to the existing LED mounting points on the PCB.
The case was essentially designed around the PCB (and connectors) and keyboard, which were first created as accurate models within Fusion. The model for the PCB was made by creating the board and its six mounting screw-holes by using the measuring facilities within KiCAD. The external connectors (joystick, etc) were created as simple rectangular boxes, the dimensions of which were determined by measuring (with a digital calliper) each connector. The PCB mounting posts, and a simplified version of the Amiga 600 keyboard, were created in the same way.
After starting on the case itself I realised there was a fairly significant problem which had to be overcome: the JTAG connector for reprogramming the FPGAs and Config Flash on the MAXI09 board would be hidden, since the 10 pin box header is right in the middle of the PCB. Without exposing this connector I wouldn’t be able to work on he HDL for the FPGAs without opening the case. Not good, because I frequently find myself tweaking the VHDL.
The solution to this problem was quite simple: by adding a small PCB with two box headers, one at right angles (for the external connection) and one regular one, I could jumper the MAXI09 JTAG connector to another connector accessible from the outside of the case.
I did have a go making up this little PCB myself, using the toner transfer and ferrite chloride method I’ve previously descried. I got a reasonable result, but then I heard about a new Chinese PCB house: allpcb.com. These guys are ludicrously cheap; small double sided boards can be made up in batches of 5 for as little as US $10, including shipping via DHL. How they make any profit I don’t know, but I duly knocked up the design in KiCAD and sent off the Gerbers. Within a few days I had the little boards in my hands. I guess it’s good that you can now get professionally made up PCBs for so little money, but at the same time it makes me sad because making up PCBs at home is great fun.
Actual construction of the case in Fusion 360 was tedious, but straight-forward, considering this was the first time I’d used the software. These days, you can learn so much about a tool just from watching YouTube tutorials. One ‘Tuber I highly recommend for users of Fusion 360 is Lars Christensen. He has many, many videos on using the software.
Fusion 360 is a parameterised system; dimensions can be input not just as numbers but as named values. Fully exploited, this lets you change (say) the material thickness in your finger jointed design, and see the finger joints change dimension to this new thickness. Sadly my MAXI09 case is only partially parameterised; adjusting the material thickness from the 3 mm I started with causes the model to become inconsistent in places.
The actual case design is a box with a slope to accommodate the keyboard, which is itself supported by an additional piece of material supported by holes in the two sides. Holes along the back edge allow the connectors to be accessed, and additional holes allow the RGB, power, and mono audio sockets to be accessed along the left hand edge.
The design of the case did show a few lessons to be learned about the layout of the MAXI09 PCB:
- The connectors (eg the DB9s for the joysticks) should hang off the edge of the PCB instead of being flush with the edge, so that the connector is not so recessed into the case, which itself has a fairly substantial thickness.
- The placement of the large DIN RGB connector is poor; it gets in the way of the keyboard and is the reason the front vertical edge of the case is relatively high. It would have better to put it along the back of the board with the other connectors.
The whole design, with me learning along the way, took perhaps five days of evenings to complete, which I was pretty pleased with.
The next stage, then, was to get the case pieces manufactured. This consisted of exporting each piece’s “sketch” as a DXF file. After hunting around, I found Bristol Design Forge. The cost was £56.40, including materials and shipping, which I thought was reasonable bearing in mind the material itself at the needed size costs about £27 on eBay.
I’m currently at the point where I’ve received all the parts and have done a dry fit of the case. It goes together very well:
I have noticed one small problem: the keyboard support is obstructed by some electrolytic capacitors around the power connector. Whilst I modelled all the connectors, and thus could place the keyboard support in a way where the support was not obstructed by any of the connectors, I neglected to model the relatively tall capacitors, and sure enough a few of them are in the way. The solution should be simple enough: I will remove the caps and re-solder them, but bent over at an angle so they are not as tall.
Another possible problem is I want to remain able to open the case to get at (and possibly remove) the motherboard and the keyboard. Hopefully the finger joints will have enough friction to allow the case to be closed without every joint being glued.
So the next thing will be complete the assembly, solder flying leads for the LEDs and hopefully have a MAXI09 that I can drag around the house without the computer falling apart!