Keyboard Ghosting Explained
microsoft.com
microsoft.com
So where is that keyboard?
Just to be crisp here, an STM32F429 can have 135 digital I/Os in the 208 quad flat pack. It also has a megabyte of flash and 192K of RAM. It also has a USB Phy built right in so you can just wire it up to a USB connector. Its $8 in 1K quantities in that package. So parts : chip, PC board, 120 or so switches and plastic case and key caps. Sure its more expensive than the $0.75 AVR chip they currently use but we're talking high end keyboards here.
To my mind the interesting problem is how to get NKRO down into every keyboard. I'm sure it's possible with sufficiently clever engineering, but even with an almost-zero cost burden over bog-standard 2KRO this is almost certainly one of those frustrating situations where mass quality is achievable but only if you can get customers and manufacturers to know and care enough.
> Sure its more expensive than the $0.75 AVR chip they currently use but we're talking high end keyboards here.
Would extra PCB layers would be another significant source of increased cost here?
I was amazed when my Das Keyboard came with a USB->PS2 adapter, and said to use the PS2 to get N-key rollover (I think it's limited to 6 on USB.)
I am still slightly amazed every time I remember that the older format is higher spec - although I assume it is something to do with bandwidth on a "serial bus" (especially since most keyboards are forced to run at USB1.1 speed, for some reason).
Anyone who can explain these mysteries is welcome to reply :)
The following table represents the keyboard input report (8 bytes).
Byte Description
0 Modifier keys
1 Reserved
2 Keycode 1
3 Keycode 2
4 Keycode 3
5 Keycode 4
6 Keycode 5
7 Keycode 6
Which is where the 6 key roll over comes from. However this is really the minimum implementation so that BIOS'es can use USB keyboards. If you read the spec carefully there isn't anything that says you can't implement a different reporting structure, as long as your HID driver is expecting it. My guess is rather than ship "special" keyboard drivers they just use the standard one, and they opt to use PS/2 connectors which work in the same way (they are really just a serial port and can send as many keys as they want) for the 'corner' case of full n-key rollover.Also, I've never actually run into a problem using it over USB on a Mac or PC, so I guess it can't be that bad! (I do play games, but this keyboard goes on my work machine in whichever office that is.)
So we can stick millions of transistors on an integrated circuit, but a hundred diodes? Too difficult!
The transistors on an IC are like pixels on an image. Every individual component is a single transaction. Not surprisingly it's way cheaper to transfer an 1MB picture than 100 small requests that each have their own overhead.
It's a difference between the processes they are made with. It would also be expensive to have hundreds of individual transistors. It's the fact that they live in the same packaging and are manufactured at the same moment into the silicon what makes them cheap.
Nowadays I can't imagine buying a keyboard that shares the same technical limitations. I would consider it ... I don't know, disrespectful to my 12-year-old self, that 20 years later I'd still be dealing with the same dumb problem.
You can splurge on a more expensive keyboard (I have a Filco Majestouch at home) that don't use this cheap techinque and have a much better feel.
The users end blaming you for their character deaths and the overall experience is frustrating. The best solution I found was to use a different key for shooting, such as left Ctrl, 'a' or 'z'.
If you ever wondered why you can't use the large button on your keyboard to trigger the main action in a game, blame your keyboard manufacturer.
Basically I got the hardware and wrote software for a Motorola 68hc11 to control it. The way it worked was that you would put a value on an 8 bit register that would activate one "bit". This bit would be connected to 8 different keys on the keyboard. You would get an 8 bit value out the other end that would tell you which keys were connected at the time.
So for example the value:
01000000
might correspond go keys 1, 6, 11, 16, 21, 26, 31 and 36. If you got the value:
01011001
out the other end, you knew that keys 6, 16, 21 and 36 were pressed. The 68hc11 scanned so fast that you couldn't fool it. I remember my professor standing there for ages mashing the keyboard trying to get it to break with different key combinations.
If such an old microcontroller could handle 48 keys so easily, why the hell would a modern microcontroller not be able to use the exact same method? ie. instead of doing it in "rows and columns" just treat the keys as a linear array and deal with which keys are pressed and which aren't.
00100000
onto the input register, and I get:
01000000
on the output register, that can only correspond to one key at the time I read the register.
EDIT: I think perhaps you're underestimating how quickly a microcontroller can scan a keyboard. If I press 2 keys simultaneously that are both connected to the same output pin on the output register at different times, the rate at which I scan the input register is so fast that it would be physically impossible for me not to detect that as 2 distinct keys being pressed.
Going back to your original example, if one would press keys 1, 2 and 6 at the same time your microcontroller would falsely detect 7 as being also pressed (because keys 1 and 6 shorts two input wires together). This assuming that your output register drives strong 1 and weak (preferably floating) 0. If it has strong drive for both 0 and 1, then such combination of pressed keys would cause some unpredictable effect, possibly including burning out the pins.
If I put a voltage on pin 2, and key A is pressed, I will get a voltage at pin 1. If I put a voltage on pin 3 and key B is pressed, I will get a voltage at pin 1.
It doesn't matter if both are pressed simultaneously because I am reading them sequentially.
All you have to do is scan the keys quickly enough that someone can't "sneak in" a key press in between scans which turns out is possible with even the lowest powered hardware.
He's basically running sets of 8 keys through a mux, and changing the selector of the mux to scan through the keys rapidly, 8 at a time.
There is one output wire per key, at least until it gets to the mux.
http://www.microsoft.com/appliedsciences/antighostingexplain... http://www.tomshardware.com/reviews/mechanical-switch-keyboa...
Last words on the article
IIRC, to get past this, all you need to do is emulate a hub with fifteen or twenty keyboards attached. Then you can press every key at once!
There are several cases of driver bugs you have to work around and ignoring driver bugs, it's just generally much harder than it should be (which means more device bugs):
* USB HID specifies two interfaces: the full report interface and a simplified "boot interface" that lets you avoid parsing interface descriptors. The boot interface supports only 6 keys, low speed and it's supposed to be used by bioses etc. Some host devices (like TVs) use the boot interface, those can't support more than 6kro.
* A USB device can specify several interfaces, the host selects which one it'll use to talk to it. For HID devices the boot interface (if supported) has to come first. The problem is that sometimes the first one is selected as it's the "default" one. It's not really supposed to happen but when it does, you can't have more than 6kro.
* The number of simultaneous keys a keyboard (one of its interfaces) can report is specified in its interface descriptor. The USB HID spec contains few sentences that can be easily misunderstood to mean that if a keyboard can report more than simultaneous 6 keys, it doesn't support the boot interface. Some bios writers read it that way, so if you have a fully compliant keyboard with nkro, it will fail on some (buggy) bioses.
* USB specifies low-speed (1.5Mbit/s) and full-speed (12Mbit/s) operation (2.0 adds high speed and 3.0 adds super speed). At low speed the payload length of the interrupt frames the HID devices use are limited to 8 bytes, which limits them to 6 keys (one byte is used for modifiers, one is reserved) for one frame messages. It's possible to chain multiple frames per message, but some OSes don't support that. This means that a nkro low-speed keyboard will (on buggy oses) have only 6kro.
* A way to work around the last problem is to make a keyboard that uses the full-speed interface. The problem is that one some systems this fails hard (the keyboard doesn't work at all).
(source: I wanted to make my own dream keyboard. The existing USB HID device implementations i could find had various limitations so I decided that i'd make my own one. I mean, hey, how hard could it be?)
On the other hand I can't understand why they had designed HID in this way, when essentially all previous PC keyboard interfaces worked by sending state changes (key down/key up) and not full state. It's not like that generating down/up events would add significant complexity to keyboard, there has to be whole lot of stuff for the USB itself and also it's already there for PS/2.
And other than that, there's no artifact of the protocol that would hinder the development of such support?
I've seen keyboards with what looked like hardware 'nkro' toggles, and overheard discussions to the effect that many implementations of nkro over usb are sometimes 'unreliable', which sounds like inexcusable behavior on either part of the keyboard's controller, the software driver, or the protocol itself.
Quite frankly I really don't care for n-key rollover, it's a silly marketing argument as far as I'm concerned. 6 KRO without ghosting "ought to be enough for anybody", especially if the alternative breaks compatibility. Maybe the hardcore gamers will disagree though.
Since then I use z for shooting and problem solved :) Avoid three keys combinations in the same area of the keyboard and it will be fine.
I didn't know about "keyboard ghosting", but with z (or x) and the arrows it doesn't happen, so I assumed it was because the space key is close to the arrows and because some internals of the keyboard it can't register three keys down at the same time in the same area (but the arrow keys and z works just fine).
But there is an even bigger issue: engineers are cheap, too. Once you get a design that "works", for varying values of "work", it's like pulling teeth to get an electrical engineer to change anything.
Some of it has good reason. It's really difficult to prototype new circuits. We can prototype new code as fast as we can write it. Have you ever tried using Eagle? Or LabView? Constantly fighting with a goofy UI to build circuit designs, and then you really only have a simulation at that point. To get the real thing (analogous to compiling?), you have to fab a prototype, which fewer and fewer places are doing in-house anymore, which will take a day, or maybe a week. I compile my software 15 times an hour!
And it doesn't necessarily have to be this way. LabView sucks because EEs are shitty programmers. Every hardware shop I've walked into, I was the guy to suggest they start using such outlandishly cutting edge technology as source control. It's been even harder to convince some of the older engineers that no, nobody uses CVS anymore, and the little you remember of it from 15 years ago isn't going to help you anyway.
"Oh yeah, let's write our own atoi(). That sounds like a great idea. What's that? You didn't realize that I'd be sending you a direct copy of what was on the LCD screen? Why wouldn't you want to know that the LCD shows a space in the 10s column between the negative sign and the value when the value is more than -10?"
So yeah. Everyone is a bunch of cheap bastards. I'm not saying it's any better on the software side. Software engineers couldn't be counted on to put a florescent light tube in the right way if their life depended on it. But at least most software engineers try to abdicate hardware responsibility to other people. EEs think "it's just code, anyone can do it."
When I tried the same tactic on my computer at home, I discovered it didn't have the same problem. The chords that were unrecognizable at school worked just fine on my keyboard at home. I surmised that the difference was in how the keyboards detected the key presses.
Over the next few days/weeks I wrote a program that could actually inspect the key queue in memory and mapped out the chords which would fail. I could actually map out what appeared to be groups of keys that caused this problem. I did the same thing for the keyboard I had at my house and while there were some combinations that would lock up the keys, I found that it could handle many more simultaneous keys.
Maybe it wasn't so surprising that the next year I started my EE degree?
I did the same thing about figuring out which keys would block my opponent from moving, both in Super Fighter and in the PC ports of the Mortal Kombat games. Didn't go as far as automatically calculating it per keyboard, though. We actually tried to play honestly without using that for advantage, a gentleman's agreement to only press keys for just as long as you needed.
It's been a few years, so I don't remember too much about the game. I only remember it was such a good port that I could learn moves on the clone and that made me a much better player in the arcades.
I also played my share of Mortal Kombat and Doom on those desktops. Mortal Kombat was great because it was actually a port by Probe/Acclaim and as far as I could tell it played identically. That became a valuable skill in college.
Probably my favorite misuse of equipment was from my senior year of high school. I got myself a 486 DX2-50 monochrome laptop and my friend got a Toshiba color laptop. We hooked up Null MODEM cables and strung them out over a couple seat rows and columns. We played Doom death matches in the middle of class lectures.
Having a laptop was unusual. Using one in a classroom, even more so. I don't know if our government teacher thought we were taking notes -- we weren't -- but I don't think he suspected we were playing multiplayer games. Besides, collectively my friends and I had the best grades in the class, so as long as we weren't being disruptive we could pretty much do as we pleased. We were still the only ones who would answer any questions or engage in political debate.
This is pretty vague. How exactly does this disambiguate which keys are being pressed?
The key electrical concept is a voltage divider: http://en.wikipedia.org/wiki/Voltage_divider
Each row of three buttons is in parallel with each other, each with a different value of resister. When a switch closes, it allows current to flow through that switch's resistor. The final voltage at the end of the row of buttons is directly related to which buttons are pressed. Given the right selection of resistors, you can tell exactly what combination of button presses have occurred.
A diagram I had drawn to explain it to a project mate: https://raw.github.com/capnmidnight/GeblinkenKiosk/master/do...
And the (can't remember if it's accurate, but certainly close enough to get the concept) diagram of the full circuit: https://raw.github.com/capnmidnight/GeblinkenKiosk/master/do...
The spreadsheet I wrote to figure out the voltage thresholds for given resister values: https://github.com/capnmidnight/GeblinkenKiosk/blob/master/s...
And the code that read the analog pins on the Arduino to figure out the state: https://github.com/capnmidnight/GeblinkenKiosk/blob/master/s...
They say they've patented this technology but in fact it's been used for (smaller) keypads with microcontrollers for a long time before that; I remember reading some application notes that showed this technique.
Aside from gaming, one application that's hurt by rollover is the open source stenotype program Plover:
I would like to try it, but I tote around a MacBook Pro and I don't care enough about Plover to try to carry a keyboard around and awkwardly put it on top of the built-in keyboard or something. Still, this is one of the few cases where I feel constrained by the unreplaceable hardware.
Keyboards in the last few years have had:
- Mushy key feel. I can't tell when I've actually done a keystroke.
- Keys that are hard to strike (need to press on them just right, or they hang up or don't register). This is particularly bad on the wider keys.
- Keytops too close together; I mash multiple keys.
- Embarrassingly bad features: Function-key lock is the classic one here. Let's not talk about the 'diamond' arrow keys that have occasionally appeared.
I'd buy half a dozen "Natural" keyboards with decent Cherry hardware running the show, ESC in the right spot, and no wacky features. I don't even need a numeric keypad. I'd pay more money for some remapping (though just about any 20 cent microcontroller will have enough EEPROM to do this).
Whaddya say, Microsoft? Care to make a good keyboard again?
Edit: incidentally, this keyboard, despite being fairly new, only gets 5 or 6 keys on the rollover test at the top of the article
For one, I type far too quickly for auditory feedback to be of any meaningful use. Second, a combination muscle memory and spring feedback usually catch situations where I've missed a key (I can feel that I hit it too lightly). Third, I find some of the mechanical keyboards to be too stiff and require more force to fully press each key, leaving my arms more fatigued at the end of the day.
I suppose it's individual preference, but the soft clicking I get from my laptop or Microsoft ergo keyboard (low-travel laptop style keys) are more than enough for me.
To add to your list of keyboard gripes though:
- Keys with sloped sides (an extension of "keytops too close together") that cause me to hit adjacent keys when I slightly miss
- "Fn" and Ctrl keys swapped. I was working with keyboard in a seldom-used office yesterday that caused me to repeatedly clear lines when I meant to hit Ctrl+C. I will be replacing that hunk o' junk.
- Absolutely no separation between Function keys and numeric keys.
I also wonder if there is a problem with the diagram. Sometimes when I was pressing 10 or more keys, the enter key would turn on.
Back then Macintoshes were advertised as "keyboard not included" so Apple got to soak you for a very well-engineered item.
Perhaps: M0115 vs. M0116 is probably the quintessential AT vs. compact layout conflict, though, so I'm sure there were plenty of supporters on either side. I also assume that the compact M0116 actually sold significantly more, as I've almost never seen an extended keyboard used with a non-modular Mac like the SE or Classic. The M0115 was consciously part of the Macintosh II revolution (or counter-revolution?): SJ was famously among the people who presumably preferred the M0116 http://www.flickr.com/photos/jurvetson/841771 .
The keyboard defaults to 6KRO. When I set it to NKRO (over USB), the OS X keyboard viewer showed as many keys as I could hold down. However, it no longer recognized the Caps Lock key as Control, as mapped in the System Preferences.
So basically, if you have a two-stick console with 6 buttons for each player, you had to wire it in a way that was impossible for Player 1 to ghost/block Player 2's keys (and vice versa). So when you found a combination that ghosted/blocked, you'd just map them to opposite directions on the same side since it's not possible to press UP+DOWN or LEFT+RIGHT at the same time on a joystick.
Here are some details: http://arcadecontrols.com/arcade_input.shtml#KeyboardGhostin...
Want to learn more? Hit the geekhack forums (search for NKRO) or geekhack channel on freenode.
> Typically, ghosting is the result of one or more of following three limitations: the hardware can't read the given key combination, the software on the computer doesn't support multiple simultaneous keys, or the communication protocol between the hardware and software limits the maximum number of simultaneous keys reported. The next section discusses in more detail the hardware design of typical keyboards that limits the number of keys that can be read at the same time.
The article also links to another page that describes the issue with USB: http://www.microsoft.com/appliedsciences/content/projects/Si...
And then for a while was the craze for finding this good old keyboard (IBM, HP, whatever) that did not block to play SC2 and other games (back in the days multiplayer was divinding the keyboard - to two - and much better fun if you ask me)
Instead of having an "all hot" electrical configuration, it would cycle through the rows with a "one hot" configuration, and read the columns. If I recall correctly, it would be something like 20 cycles of a 4Mhz Z-80 to read one 5-column row (you'd need 8 of them to read the entire 40-key keyboard), and it was done every 50hz/60hz interrupt by the main CPU - modern keyboards have an ASIC on par or 100 times faster than a Z-80 just for the keyboard.
I use a $3 one (which I bought to replace the one I used for over a decade) and I've never had such issues. I use this keyboard for coding and gaming, not just for common tasks which require low performance.
This is because in RTS and MOBA while you might be rapidly hitting your keys you should be hitting them in succession, not simultaneously! In the FPS on the other hand you might be trying to walk forward and right while crouching and reloading, which requires four keys to do. This would cause problems for my keyboard.
Programming is more like the RTS than the FPS in this respect. You may be hitting a lot of keys, but the combinations are more likely to involve modifiers such as CTRL, ALT, or shift rather than a combination of letters.
So, I take it that anti-ghosting measures are primarily meant for gaming keyboards.
'Another marketing strategy is to state that the keyboard allows "up to" some large number of key presses.'
'Microsoft's SideWinder X4 features multitouch technology that allows it to detect, and report ANY combination of QWERTY keys, up to 17 keys.'
Placeholder fail
I'm assuming they went the custom-protocol-extension route, meaning sending more than 6 keys restricted to Windows-only drivers?
Or did they do something else?