Connecting a thermal printer to a BBC microbit

 

UPDATE – I have tidied up the code a lot and put a demo program on Github for you to enjoy – prints out a demo page like the one below:

I have a Sparkfun thermal till-roll printer which I used for making my Little Box of Poems – this was a box that printed out a random poem at the press of a big red shiny button. The original one was powered by an Arduino and then I made a Raspberry Pi version. I also made an internet printer using it, and a box that printed out the weather forecast just before I woke each day.

It had been sitting idle for a while and I started to wonder if I might be able to make a Little Box of Poems (or something similar) using a humble BBC micro:bit. And if making 2-player wireless microbit Pong was harder than I expected, then this was actually much easier than I could have dared hope.

This is what you’ll need:

  • a microbit
  • a serial (NOT USB!) thermal till-roll printer as sold by PimoroniSparkfun or Adafruit
  • a 5-9v power supply for the printer that can deliver at least 1.5A, 2A is better.
  • 2 jumper leads to connect the GND and RX pins of your printer to the microbit
  • I also used a Kitronik edge connector / breakout board to make connecting to the microbit easier.
  • Some Python code (below)
  • The Mu editor to flash the Python program to your microbit.

I connected the GND pin on the microbit to the black TTL GND wire on the printer, and I connected pin 8 on the microbit to the yellow TTL RX wire on the printer. I didn’t connect the printer’s TX pin as this is just 1-way communication, microbit to printer.

I had absolutely no idea what I was doing, but armed with an amusingly-translated Chinese instruction manual, some wires and blind faith I found that I could print some text with just a few lines of Python. It was a bit feint and garbled at first, and I seemed to be getting messages from the console! Look carefully and you’ll see my ‘hello world’.

After a bit of jiggery-pokery (and reading the manual) I realised that I needed to send a linefeed (LF) character to get it to print the contents of the buffer. I found that at its simplest I could print different messages with different button presses with just a few lines of Python. I chose pin 8 for transmission as it looked like it wasn’t used for anything else, and the only other wire you need to connect is GND on the microbit to GND on the printer TTL connection. The \x0A at the end of the message is a hex code for line feed – this causes the printer to print the contents of its buffer and feed the paper up 1 line.

import microbit

microbit.uart.init(baudrate=19200, bits=8, parity=None, stop=1, tx=microbit.pin8, rx=None)

while True:
    if microbit.button_a.is_pressed() and microbit.button_b.is_pressed():
        microbit.uart.write("both buttons pressed\x0A\x0A")
    elif microbit.button_a.is_pressed():
        microbit.uart.write("message A\x0A\x0A")
    elif microbit.button_b.is_pressed():
        microbit.uart.write("message B\x0A\x0A")
    microbit.sleep(100)

I then wrote some slightly more complex code that would allow wide text, inverse text and even print 13 digit EAN-format bar codes. It would be easy to add double-height printing, more challenging but fun to get graphics working!

import microbit

microbit.uart.init(baudrate=19200, bits=8, parity=None, stop=1, tx=microbit.pin8, rx=None)

def normal_print(msg):
    microbit.uart.write(msg+"\x0A\x0A\x0A\x0A")

def wide_print(msg):
    microbit.uart.write("\x1B\x0E"+msg+"\x0A\x0A\x0A\x0A\x1B\x14")

def bold_print(msg):
    microbit.uart.write("\x1B\x451"+msg+"\x0A\x0A\x0A\x0A\x1B\x450")

def inverse_print(msg):
    microbit.uart.write("\x1D\x421"+msg+"\x0A\x0A\x0A\x0A\x1D\x420")

def print_barcode(msg):
    microbit.uart.write("\x1D\x6B\x43\x0D"+msg+"\x0A\x0A")

# increase printing temperature - increase hex number A0 for darker print
microbit.uart.write("\x1B\x37\x07\xA0\x02")

while True:
    if microbit.button_a.is_pressed() and microbit.button_b.is_pressed():
        microbit.display.scroll("AB")
        wide_print("both buttons")
    elif microbit.button_a.is_pressed():
        normal_print("1234567890123")
        microbit.display.scroll("A")
    elif microbit.button_b.is_pressed():
        microbit.display.scroll("B")
        inverse_print("message B")
    microbit.sleep(100)

I had to do it – a microbit version of the Little Box of Poems. Press button A and a random short poem is printed. You could modify this code with poems of your own, or perhaps make a Christmas cracker joke generator… let me know what ideas you have!

import microbit
import random

microbit.uart.init(baudrate=19200, bits=8, parity=None, stop=1, tx=microbit.pin8, rx=None)

def normal_print(msg):
    microbit.uart.write(msg+"\x0A\x0A\x0A\x0A")

def wide_print(msg):
    microbit.uart.write("\x1B\x0E"+msg+"\x0A\x0A\x0A\x0A\x1B\x14")

def bold_print(msg):
    microbit.uart.write("\x1B\x451"+msg+"\x0A\x0A\x0A\x0A\x1B\x450")

def inverse_print(msg):
    microbit.uart.write("\x1D\x421"+msg+"\x0A\x0A\x0A\x0A\x1D\x420")

def print_barcode(msg):
    microbit.uart.write("\x1D\x6B\x43\x0D"+msg+"\x0A\x0A")

poemtitle = ['In a station of the Metro', 'The Sick Rose', 'This is just to say', 'Surprise']

poemtext = ['The apparition of these faces in the crowd;\n\
Petals on a wet, black bough.', 'O Rose thou art sick.\n\
The invisible worm,\n\
That flies in the night\n\
In the howling storm:\n\n\
Has found out thy bed\n\
Of crimson joy:\n\
And his dark secret love\n\
Does thy life destroy.', 'I have eaten\n\
the plums\n\
that were in\n\
the icebox\n\n\
and which\n\
you were probably\n\
saving\n\
for breakfast\n\n\
Forgive me\n\
they were delicious\n\
so sweet\n\
and so cold', 'I lift the toilet seat\n\
as if it were the nest of a bird\n\
and i see cat tracks\n\
all around the edge of the bowl.']

poemauthor = ['Ezra Pound\n', 'William Blake\n', 'William Carlos Williams\n', 'Richard Brautigan\n']

# increase printing temperature - increase hex number A0 for darker print
microbit.uart.write("\x1B\x37\x07\xA0\x02")

while True:
    if microbit.button_a.is_pressed():
        poem = random.randrange(0,4)
        microbit.display.scroll(str(poem))
        wide_print(poemtitle[poem])
        normal_print(poemtext[poem])
        inverse_print(poemauthor[poem])
    microbit.sleep(100)

I then built the printer and microbit into an old soap powder box in the time-honoured Box of Poems tradition:

And finally… a festive twist. This version of the code will print a random poem if you press button A, and a really bad Christmas cracker joke if you press button B:

import microbit
import random

microbit.uart.init(baudrate=19200, bits=8, parity=None, stop=1, tx=microbit.pin8, rx=None)

def normal_print(msg):
    microbit.uart.write(msg+"\x0A\x0A")

def wide_print(msg):
    microbit.uart.write("\x1B\x0E"+msg+"\x0A\x0A\x1B\x14")

def big_print(msg):
    microbit.uart.write("\x1D\x211"+msg+"\x0A\x0A\x1D\x210")

def bold_print(msg):
    microbit.uart.write("\x1B\x451"+msg+"\x0A\x0A\x1B\x450")

def inverse_print(msg):
    microbit.uart.write("\x1D\x421"+msg+"\x0A\x0A\x1D\x420")

def print_barcode(msg):
    microbit.uart.write("\x1D\x6B\x43\x0D"+msg+"\x0A\x0A")

poemtitle = ['In a station of the Metro', 'The Sick Rose', 'This is just to say', 'Surprise']

poemtext = ['The apparition of these faces in the crowd;\n\
Petals on a wet, black bough.', 'O Rose thou art sick.\n\
The invisible worm,\n\
That flies in the night\n\
In the howling storm:\n\n\
Has found out thy bed\n\
Of crimson joy:\n\
And his dark secret love\n\
Does thy life destroy.', 'I have eaten\n\
the plums\n\
that were in\n\
the icebox\n\n\
and which\n\
you were probably\n\
saving\n\
for breakfast\n\n\
Forgive me\n\
they were delicious\n\
so sweet\n\
and so cold', 'I lift the toilet seat\n\
as if it were the nest of a bird\n\
and i see cat tracks\n\
all around the edge of the bowl.']

poemauthor = ['Ezra Pound\n', 'William Blake\n',
'William Carlos Williams\n', 'Richard Brautigan\n']

joke_question = ['Why are Christmas trees so bad\nat sewing?\n',
'Why did the turkey join\nthe band?\n',
'What song do you sing at a\nsnowman\'s birthday party?\n',
'Which famous playwright was\nterrified of Christmas?\n']

joke_answer = ['They always drop their needles!\n',
'Because it had\nthe drumsticks\n',
'Freeze a jolly\ngood fellow\n',
'Noel Coward!\n']

# increase printing temperature - increase hex number A0 for darker print
microbit.uart.write("\x1B\x37\x07\xFF\xFF")

microbit.display.scroll("Press A for poem, B for joke",
delay=150, wait=False, loop=True, monospace=False)

while True:
    if microbit.button_a.is_pressed():
        poem = random.randrange(0,4)
        wide_print(poemtitle[poem])
        normal_print(poemtext[poem])
        inverse_print(poemauthor[poem])
    elif microbit.button_b.is_pressed():
        joke = random.randrange(0,4)
        wide_print("I say, I say, I say...")
        normal_print(joke_question[joke])
        wide_print(joke_answer[joke])
    microbit.sleep(200)
This entry was posted in computers, microbit and tagged , , , , . Bookmark the permalink.

3 Responses to Connecting a thermal printer to a BBC microbit

  1. Simon says:

    This is super awesome!
    I’m just starting out on a project using one of these thermal printers. I hope to be able to print out some sort of encoded message as part of a puzzle box I’m constructing. I would love to be able to get graphics printing, and have the printer spit out a message using a pigpen cipher.
    I think I’ll start with a simple caesar cipher, as text I can manage! (I think)
    Really appreciate this tutorial – absolutely no way I could do this without it!!!

Leave a Reply