Connecting PS/2 Keyboard to BBC micro:bit for Enhanced Communication

Translated from: http://www.suppertime.co.uk/blogmywiki/2020/08/ps2-keyboard-microbit/

Connecting PS/2 Keyboard to BBC micro:bit for Enhanced Communication

For many years, I have wanted to connect a regular computer keyboard to the BBC micro:bit to make radio messaging and encryption easier to use. I had seen and used something similar on Arduino, which used a complex C++ library to read data from a PS/2 keyboard, parsing each data bit. But that was not the way I preferred.

Previously, I had connected a thermal printer directly to the micro:bit and sent it some serial data, and it printed the message immediately. I never thought a homemade matrix keyboard would work on the first try, but it did.

Sometimes, it helps to be free from knowledge and tradition, although I must quickly add, except when flying a plane or performing surgery.

Therefore, I decided to take this approach to solve the micro:bit PS/2 keyboard issue.

What is a PS/2 keyboard? A PS/2 keyboard is an old-style keyboard before USB – they have round plugs, usually wrapped in purple plastic, while PS/2 mice often have green plugs. They are not particularly easy to buy, at least not new, but people often throw them away, as we will see…

They are just a matrix of buttons connected to a small microcontroller (which operates at 5 volts, while the micro:bit is 3 volts) that converts key presses into serial data. The protocol is quite daunting… sending an 11-bit data at a frequency between 10 to 16.7 kHz, including:

1 start bit (always 0)
8 data bits (least significant bit first)
1 parity bit (odd parity)
1 stop bit (always 1)

So I decided to ignore all of this.

One day, while walking my dog, I found a PS/2 keyboard thrown on the roadside, with the plug cut off. I took it home and disassembled it, hoping to understand the function of each colored cable through the PCB. (There is no standard for PS/2 cable colors)

Searching the internet yielded no results. Fortunately, by examining the cut plug, I was able to figure out the functions of this particular Dell keyboard:

Pink = 5v

Black = GND

White = data

Brown = clock

Connecting PS/2 Keyboard to BBC micro:bit for Enhanced Communication

I connected the black wire to the micro:bit GND pin and the pink wire to the micro:bit 3v pin. The LED lit up, indicating it was performing a self-test. The NUM LOCK light even lit up (but not the CAPS LOCK; I found that was done by the PC using software to send signals back to the keyboard!). So, the PS/2 keyboard can be powered by the micro:bit’s 3v supply without needing an external power source.
Now, if I ignore the clock line and assume the PS/2 keyboard is just sending serial data, we can read the serial data on the micro:bit, as long as we know the baud rate. The range of 10 to 16.7 kHz is daunting; I tried several times, connecting pin 1 to the white data cable, and found that using 10000 baud produced some meaningful data.
import micropython # to enable disabling of accidental keyboard interrupt
from microbit import *
uart.init(baudrate=10000, bits=8, parity=None, stop=1, tx=None, rx=pin1)
micropython.kbd_intr(-1) # disable accidental keyboard interrupt, no idea if this works or is needed
while True:    if uart.any():        data = bytearray(1)        uart.readinto(data, 1)        display.scroll(data[0])

For example, pressing the letter Q always produces 139, 248, 139, while pressing A produces 142, 248, 142.

From my readings, I learned (it does require a bit of knowledge) that a PS/2 keyboard sends a code when you press a key, and then sends a release code when you let go. So 139, 248, 139 indeed means “press Q”, “release Q”.

So all I had to do was sniff the codes for each key I was interested in and create a dictionary to look them up and convert them to letters. So far, I only care about letters, numbers, and some very basic punctuation, but I have implemented my own caps lock and backspace. (The caps lock light does not light up, but one day…)

The key codes for other keyboards may differ, so if needed, use the sniffer program to create your own list. You may also need to use a different baud rate, but this Dell works at 10,000.

Encrypted Radio Communication Project

Let’s use this newfound knowledge to build a super spy communicator! No one will see you hiding in the bushes with a micro:bit and a Dell PS/2 keyboard pulled from the trash!

Put the program below into the receiving micro:bit:

from microbit import *
import radio
radio.config(group=23)
radio.on()
storedMessage = ''
while True:    message = radio.receive()    if message:        display.scroll(message)        storedMessage = message    if button_a.was_pressed():        display.scroll(storedMessage)

For the transmitter, use the following program. Remember, you need to connect pin 1 of the micro:bit to the data line of the keyboard – mine is white, but other keyboards may not be. Also, connect the micro:bit 3v pin to the power line of the keyboard (mine is pink) and the micro:bit GND pin to the ground line of the keyboard (on this Dell, it’s black).

import micropython # to enable disabling of accidental keyboard interrupt
from microbit import *
import radio
radio.config(group=23)
uart.init(baudrate=10000, bits=8, parity=None, stop=1, tx=None, rx=pin1)
micropython.kbd_intr(-1) # disable accidental keyboard interrupt if ctrl-C character received on serial input
dataList = []
delay = 250
capsLock = True
message = ''
keyCodes = {  139: 'Q', 207: 'W', 210: 'E', 215: 'R', 150: 'T', 219: 'Y', 222: 'U', 161: 'I', 226: 'O', 231: 'P',  142: 'A', 205: 'S', 145: 'D', 213: 'F', 154: 'G', 217: 'H', 157: 'J', 224: 'K', 224: 'K', 229: 'L',  140: 'Z', 208: 'X', 209: 'C', 148: 'V', 152: 'B', 153: 'N', 220: 'M', 225: ',', 165: '.', 149: '_', 164: '?',  138: '1', 206: '2', 146: '3', 147: '4', 214: '5', 218: '6', 159: '7', 158: '8', 162: '9', 163: '0'}
while True:    if uart.any():        data = bytearray(1)        uart.readinto(data, 1)        dataList.append(data[0])        if len(dataList) == 3:            if dataList[0] in keyCodes:                if capsLock:                    letter = keyCodes[dataList[0]]                else:                    letter = keyCodes[dataList[0]].lower()                display.show(letter)                message = message + letter            elif dataList[0] == 172: # toggle caps lock                capsLock = not capsLock                if capsLock:                    display.show(Image.ARROW_N)                else:                    display.show(Image.ARROW_S)            elif dataList[0] == 242: # backspace                display.show(Image.ARROW_W)                message = message[:-1]            dataList = []            sleep(delay)    if button_a.was_pressed():        display.scroll(message)    if button_b.was_pressed():        radio.on() # I'm in love with Massachusetts        radio.send(message)        radio.off()        display.scroll('TX')        message = ''    display.clear()

Inputting messages is relatively slow. Letters will flash on the micro:bit display. The caps lock key toggles case, but the shift key does not work. If you make a mistake, press the backspace key, which will delete the last character.

Press button A on the micro:bit to see the message, and button B will wirelessly send the message. This will also delete the message because a good spy would cover their tracks, right?

Sometimes it needs a reset when powered on, so if it doesn’t work the first time, press the reset button on the back of the micro:bit and see if you can sort it out.

If you make any improvements, please let me know. I would be very happy if you could like my blog or my YouTube channel.

Leave a Comment

×