Morse Code on the BBC micro:bit!

The BBC micro:bit

I’m going to be talking about the two Morse Code problems in the Grok Learning BBC micro:bit Crash Course;

I’ll be covering what the problems teach, how to solve them, and some common pitfalls and what to do about them.

We use the BBC micro:bit because it’s a relatively cheap way to get a physical device to experiment with and learn about. In this age of the Internet of Things (IoT) understanding how physical devices work is really important. The micro:bit offers an easy entry into IoT and provides students with a more tactile experience.

These problems are great for kids from grades 5–8 and covers content from the Australian Curriculum: Digital Technologies including: ACTDIP019 and ACTDIP030. It may be a bit difficult for younger kids, but with sufficient help they should be able to do it.

Morse Code Chart

Morse Code is a method of sending text. By sending combinations of short and long signals, you can send text to someone else. These signals can be sound, or electricity, lights, or even blinking your eyes.

On the micro:bit we’ll use lights, showing the code on the display.

Here’s an example. What does it say? The answer is at the bottom!

Let’s start with the Transmitter.

This problem is the simpler of the two, and really serves to reinforce how to use the micro:bit radio. Let’s start by importing the standard micro:bit library, as well as the radio, and we’ll turn the radio on too.

from microbit import *
import radio
radio.on()

On our transmitter, we’re going to send a short signal (called a dot) when the A button is pressed, and a long signal (a dash) when the B button is pressed.

We’ll need to use a while True: loop here. This ensures that the micro:bit will keep checking for button presses forever.

from microbit import *
import radio
radio.on()
while True:
...

Inside the while loop (where the ... is) we’ll need to check if each button has been pressed. We can do this with .was_pressed(). If they have been pressed we can use radio.send('dot') or radio.send('dash') to send our Morse Code.

from microbit import *
import radio
radio.on()
while True:
if button_a.was_pressed():
radio.send('dot')
if button_b.was_pressed():
radio.send('dash')

And that’s it!

That is the whole transmitter program.
It’s not too long, and is a good level of complexity for someone who’s written a couple of micro:bit programs and is looking to learn to use the radio.

But to use the radio you need…

The Receiver Program!

This program covers more topics than the transmitter does. In addition to the radio, and a while loop, the receiver uses the music library, displaying images, and sleep.

Again, let’s start with some imports, turning the radio on, and our while loop. The only difference from last time is that we’re also importing music .

from microbit import *
import music
import radio
radio.on()
while True:
...

To receive a message on the radio, we can use radio.receive() to get messages from the other micro:bit. We’ve got to remember to assign it to a variable, so we can use it later.

from microbit import *
import music
import radio
radio.on()
while True:
r = radio.receive()

Let’s set up an if and an elif to check if we received a "dot" or a "dash".

from microbit import *
import music
import radio
radio.on()
while True:
r = radio.receive()
if r == 'dot':
...
elif r == 'dash':
...

When we receive "dot", we want to display a dot. Just the middle light in the 5 x 5 display. To show something on the display we need to use display.show(...) and replace the ... with an image.

A micro:bit displaying a “dot” it’s received.

To create an image with this: Image('00000:00000:00900:00000:00000')
Each chunk of 5 numbers is one row on the display, from top top bottom. Each number can range from 0 to 9, and says how bright the LEDs should be. This image above is the image we want to use for the dot. Just a single LED lit in the middle of the display.

For the "dash" we want to display the whole middle row lit up.

A micro:bit displaying a “dash”
from microbit import *
import music
import radio
radio.on()
while True:
r = radio.receive()
if r == 'dot':
dislay.show(Image('00000:00000:00900:00000:00000'))
...
elif r == 'dash':
dislay.show(Image('00000:00000:99999:00000:00000'))
...

In addition to showing an image, we want to play a note as well. For this we can use music.play(...), which gets given a string describing the note, e.g. 'F5:1'.

The F5 is the note and octave we want to play, and the 1 is how long we want to play it for in beats. We’ll use this note for our dot, and we’ll do the same for three beats (F5:3) for our dash.

from microbit import *
import music
import radio
radio.on()
while True:
r = radio.receive()
if r == 'dot':
dislay.show(Image('00000:00000:00900:00000:00000'))
music.play('F5:1')
...
elif r == 'dash':
dislay.show(Image('00000:00000:99999:00000:00000'))
music.play('F5:3')
...

After we’ve played these notes we want to clear the display, and sleep for 300 milliseconds to give some time between each of the dots and dashes.

Here’s how that looks.

from microbit import *
import music
import radio
radio.on()
while True:
r = radio.receive()
if r == 'dot':
dislay.show(Image('00000:00000:00900:00000:00000'))
music.play('F5:1')
display.clear()
sleep(300)
elif r == 'dash':
dislay.show(Image('00000:00000:99999:00000:00000'))
music.play('F5:3')
display.clear()
sleep(300)

Some Common Issues

Most of the tricks here are in the receiver, so we’ll focus on that. The first trick is to save radio.receive() as a variable. If you don’t do this, and instead use if radio.receive() == 'dot' and elif radio.receive() == 'dash'. You’ll find that it won’t work correctly. What’s happening here is that each time you use radio.receive() it gets a new signal from radio, which means that you’re missing incoming data.

Another big trick is the images. These big image strings can be confusing, so don’t stress if you or your students have difficulty. Each number sets the brightness of 1 LED on the micro:bit, and the numbers are grouped by row. Experimenting with showing different images should help with this.

The last thing to note is that the display.clear() and sleep(300) need to be in both the dot and dash sections. If it’s after the if elif section, you’ll find you’re only able to receive messages sometimes, since the receiver will sleep for 300 milliseconds every time it checks for a message, not just after it receives one.

I hope you found this helpful. If you have any questions about this, or other Grok Learning problems you’d like us to cover, let us know in the comments below. Check out our other micro:bit courses here!

The answer:

So, you’ve had a look at that gif above. You’ve written your own morse code programs. What does it say? Here’s what it says in morse code:

• –     – • • •     – • – •

If you look at the chart above, you’ll see that this says “ABC”