micro:bit radio messager with OLED display

What it is

Based on my previous micro:bit keyboard project, this allows you to type a message on a micro:bit using an old PC PS/2 keyboard and send it over radio to another micro:bit.

How to make it

You’ll need a couple of micro:bits, a micro:bit breakout board, a small OLED display, some jumper wires and a breadboard. You’ll also need an old PS/2 keyboard with the plug cut off and you’ll need to identify the 5v VCC, data and GND wires on the PS/2 keyboard cable. See my previous post for more on this.

Connect the keyboard to the micro:bit like this:

KBD | micro:bit
5v VCC -> 3v
data -> pin 1
GND -> GND

Connect the OLED display like this:

OLED | micro:bit
VCC -> 3v
GND -> GND
SCL -> SCL (pin 19)
SDA -> SDA (pin 20)

As well as the Python program at the end of this page, you’ll need to add two Python libraries ssd1306.py and ssd1306_text.py to make the OLED display work. You can do this using the online micro:bit Python editor. Click on the Load/Save button then ‘Show files’ then ‘Add a file’:

adding more files in the Python editor

Flash the 3 files to your micro:bit and you may need to press the reset button on the back of the micro:bit before first use. Your mileage may vary with the Baud rate, and the precise keycodes for each letter.

The receiving micro:bit will need some code on it like this:

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)

How to use it

Type your message and it should appear on the OLED display. Backspace will delete any errors. Caps lock key will toggle upper & lower case – the letter A in the bottom right-hand corner shows you which mode it’s in. Pressing enter will send your message by radio and clear the message.

How it works

It works using the principle of brute ignorance. I ignore the proper protocols for PS/2 keyboards and treat it as incoming serial data at 10000 Baud. This worked for me with the old Dell keyboard I found on the street. PS/2 keyboards send 3 codes every time you press a key: a key identifier, a release code when you let go, and it repeats the key identifier. The program looks these up and turns them into the appropriate letters every time 3 codes are received.

Improve it

- Change radio channel on the fly
- Add a Caesar cypher with selectable key – great for group interception / cryptanalysis games!

The main code

Here’s the Python code. You’ll also need those two Python OLED display libraries mentioned above, remember!

from ssd1306 import initialize, clear_oled
from ssd1306_text import add_text
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
dataList = []
delay = 1000
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'
}

initialize()
clear_oled()
add_text(11, 3, 'A')
x = 0
y = 0

while True:
    add_text(x, y, '_') # cursor
    if capsLock:
        add_text(11, 3, 'A')
    else:
        add_text(11, 3, 'a')
    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()
                add_text(x, y, letter)
                x += 1
                if x > 11:
                    x = 0
                    y += 1
                if y > 2:
                    y = 0
                    clear_oled()
                if x < 0:
                    x = 0
                if y < 0:
                    y = 0
                message = message + letter
            elif dataList[0] == 172: # toggle caps lock
                capsLock = not capsLock
            elif dataList[0] == 242: # backspace
                message = message[:-1]
                add_text(x, y, ' ')
                x -= 1
            elif dataList[0] == 131: # press F12 to review message
                display.scroll(message)
            elif dataList[0] == 236: # send message when enter pressed
                radio.on()
                radio.send(message)
                radio.off()
                add_text(0, 3, 'TX')
                message = ''
                x = 0
                y = 0
                sleep(delay)
                clear_oled()
            dataList = []
    display.clear()
This entry was posted in microbit and tagged , , , . Bookmark the permalink.

Leave a Reply