Microbit-Micropython 2
Microbit-Micropython 2
Microbit-Micropython 2
Documentation
Release 1.1.0-beta.1
Multiple authors
1 Introduction 3
1.1 Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.4 Input/Output Pins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.5 Music . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.6 Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.7 Movement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.8 Gestures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.9 Direction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.10 Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.11 Speech . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.12 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.13 Radio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.14 Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3 Microbit Module 51
3.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.2 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.3 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.4 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4 Audio 73
4.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.2 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3 Using audio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.4 Technical Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.5 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5 Bluetooth 77
7 Machine 81
i
7.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.2 Reading Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
8 MicroPython 83
8.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
9 Music 85
9.1 Musical Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
9.2 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
9.3 Built in Melodies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
9.4 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10 NeoPixel 91
10.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.2 Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.3 Using Neopixels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.4 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
11 The os Module 95
11.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
12 Radio 97
12.1 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
12.2 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
12.3 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
14 Speech 103
14.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
14.2 Punctuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
14.3 Timbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
14.4 Phonemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
14.5 Singing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
14.6 How Does it Work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
14.7 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
15 utime 113
15.1 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
ii
18.3 Including a user script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
19 Contributing 123
19.1 Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Index 127
iii
iv
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Welcome!
The BBC micro:bit is a small computing device for children. One of the languages it understands is the popular Python
programming language. The version of Python that runs on the BBC micro:bit is called MicroPython.
This documentation includes lessons for teachers and API documentation for developers (check out the index on the
left). We hope you enjoy developing for the BBC micro:bit using MicroPython.
If you’re a new programmer, teacher or unsure where to start, begin with the Tutorials and use the micro:bit Python
Editor to program the micro:bit.
Note: The MicroPython API will not work in the MakeCode editor, as this uses a different version of Python.
Tutorials 1
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
2 Tutorials
CHAPTER 1
Introduction
We suggest you use the micro:bit Python Editor or Mu when working through these tutorials.
Connect your micro:bit to your computer via a USB lead.
Write your script in the editor window and click the “Download” or “Flash” button to transfer it to the micro:bit.
If you have any problems with MicroPython or the editor, you can get support from the Micro:bit Educational Foun-
dation team via support.microbit.org.
The traditional way to start programming in a new language is to get your computer to say, “Hello, World!”.
. . . tells MicroPython to get all the stuff it needs to work with the BBC micro:bit. All this stuff is in a module called
microbit (a module is a library of pre-existing code). When you import something you’re telling MicroPython
that you want to use it, and * is Python’s way to say everything. So, from microbit import * means, in
English, “I want to be able to use everything from the microbit code library”.
The second line:
display.scroll("Hello, World!")
3
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
. . . tells MicroPython to use the display to scroll the string of characters “Hello, World!”. The display part of that
line is an object from the microbit module that represents the device’s physical display (we say “object” instead of
“thingy”, “whatsit” or “doodah”). We can tell the display to do things with a full-stop . followed by what looks like
a command (in fact it’s something we call a method). In this case we’re using the scroll method. Since scroll
needs to know what characters to scroll across the physical display we specify them between double quotes (") within
parenthesis (( and )). These are called the arguments. So, display.scroll("Hello, World!") means, in
English, “I want you to use the display to scroll the text ‘Hello, World!’”. If a method doesn’t need any arguments we
make this clear by using empty parenthesis like this: ().
Copy the “Hello, World!” code into your editor and flash it onto the device. Can you work out how to change the
message? Can you make it say hello to you? For example, I might make it say “Hello, Nicholas!”. Here’s a clue, you
need to change the scroll method’s argument.
1.2 Images
MicroPython is about as good at art as you can be if the only thing you have is a 5x5 grid of red LEDs (light emitting
diodes - the things that light up on the front of the device). MicroPython gives you quite a lot of control over the
display so you can create all sorts of interesting effects.
MicroPython comes with lots of built-in pictures to show on the display. For example, to make the device appear
happy you type:
I suspect you can remember what the first line does. The second line uses the display object to show a built-in
image. The happy image we want to display is a part of the Image object and called HAPPY. We tell show to use it
by putting it between the parenthesis (( and )).
4 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.2. Images 5
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
• Image.SQUARE_SMALL
• Image.RABBIT
• Image.COW
• Image.MUSIC_CROTCHET
• Image.MUSIC_QUAVER
• Image.MUSIC_QUAVERS
• Image.PITCHFORK
• Image.XMAS
• Image.PACMAN
• Image.TARGET
• Image.TSHIRT
• Image.ROLLERSKATE
• Image.DUCK
• Image.HOUSE
• Image.TORTOISE
• Image.BUTTERFLY
• Image.STICKFIGURE
• Image.GHOST
• Image.SWORD
• Image.GIRAFFE
• Image.SKULL
• Image.UMBRELLA
• Image.SNAKE
• Image.SCISSORS
There’s quite a lot! Why not modify the code that makes the micro:bit look happy to see what some of the other
built-in images look like? (Just replace Image.HAPPY with one of the built-in images listed above.)
Of course, you want to make your own image to display on the micro:bit, right?
That’s easy.
Each LED pixel on the physical display can be set to one of ten values. If a pixel is set to 0 (zero) then it’s off. It
literally has zero brightness. However, if it is set to 9 then it is at its brightest level. The values 1 to 8 represent the
brightness levels between off (0) and full on (9).
Armed with this information, it’s possible to create a new image like this:
6 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
boat = Image("05050:"
"05050:"
"05050:"
"99999:"
"09990")
display.show(boat)
(When run, the device should display an old-fashioned “Blue Peter” sailing ship with the masts dimmer than the boat’s
hull.)
Have you figured out how to draw a picture? Have you noticed that each line of the physical display is represented by
a line of numbers ending in : and enclosed between " double quotes? Each number specifies a brightness. There are
five lines of five numbers so it’s possible to specify the individual brightness for each of the five pixels on each of the
five lines on the physical display. That’s how to create a new image.
Simple!
In fact, you don’t need to write this over several lines. If you think you can keep track of each line, you can rewrite it
like this:
boat = Image("05050:05050:05050:99999:09990")
1.2.2 Animation
Static images are fun, but it’s even more fun to make them move. This is also amazingly simple to do with MicroPython
~ just use a list of images!
Here is a shopping list:
Eggs
Bacon
Tomatoes
I’ve simply created a list called shopping and it contains three items. Python knows it’s a list because it’s enclosed
in square brackets ([ and ]). Items in the list are separated by a comma (,) and in this instance the items are three
strings of characters: "Eggs", "Bacon" and "Tomatoes". We know they are strings of characters because they’re
enclosed in quotation marks ".
You can store anything in a list with Python. Here’s a list of numbers:
Note: Numbers don’t need to be quoted since they represent a value (rather than a string of characters). It’s the
difference between 2 (the numeric value 2) and "2" (the character/digit representing the number 2). Don’t worry if
this doesn’t make sense right now. You’ll soon get used to it.
It’s even possible to store different sorts of things in the same list:
1.2. Images 7
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
As with a single image, we use display.show to show it on the device’s display. However, we tell MicroPython
to use Image.ALL_CLOCKS and it understands that it needs to show each image in the list, one after the other. We
also tell MicroPython to keep looping over the list of images (so the animation lasts forever) by saying loop=True.
Furthermore, we tell it that we want the delay between each image to be only 100 milliseconds (a tenth of a second)
with the argument delay=100.
Can you work out how to animate over the Image.ALL_ARROWS list? How do you avoid looping forever (hint:
the opposite of True is False although the default value for loop is False)? Can you change the speed of the
animation?
Finally, here’s how to create your own animation. In my example I’m going to make my boat sink into the bottom of
the display:
from microbit import *
boat1 = Image("05050:"
"05050:"
"05050:"
"99999:"
"09990")
boat2 = Image("00000:"
"05050:"
"05050:"
"05050:"
"99999")
boat3 = Image("00000:"
"00000:"
"05050:"
"05050:"
"05050")
boat4 = Image("00000:"
"00000:"
"00000:"
"05050:"
"05050")
boat5 = Image("00000:"
"00000:"
"00000:"
"00000:"
"05050")
boat6 = Image("00000:"
"00000:"
(continues on next page)
8 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.3 Buttons
So far we have created code that makes the device do something. This is called output. However, we also need the
device to react to things. Such things are called inputs.
It’s easy to remember: output is what the device puts out to the world whereas input is what goes into the device for it
to process.
The most obvious means of input on the micro:bit are its two buttons, labelled A and B. Somehow, we need MicroPy-
thon to react to button presses.
This is remarkably simple:
sleep(10000)
display.scroll(str(button_a.get_presses()))
All this script does is sleep for ten thousand milliseconds (i.e. 10 seconds) and then scrolls the number of times you
pressed button A. That’s it!
While it’s a pretty useless script, it introduces a couple of interesting new ideas:
1. The sleep function will make the micro:bit sleep for a certain number of milliseconds. If you want a pause in
your program, this is how to do it. A function is just like a method, but it isn’t attached by a dot to an object.
2. There is an object called button_a and it allows you to get the number of times it has been pressed with the
get_presses method.
Since get_presses gives a numeric value and display.scroll only displays characters, we need to convert
the numeric value into a string of characters. We do this with the str function (short for “string” ~ it converts things
into strings of characters).
The third line is a bit like an onion. If the parenthesis are the onion skins then you’ll notice that display.scroll
contains str that itself contains button_a.get_presses. Python attempts to work out the inner-most answer
first before starting on the next layer out. This is called nesting - the coding equivalent of a Russian Matrioshka doll.
1.3. Buttons 9
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Let’s pretend you’ve pressed the button 10 times. Here’s how Python works out what’s happening on the third line:
Python sees the complete line and gets the value of get_presses:
display.scroll(str(button_a.get_presses()))
Now that Python knows how many button presses there have been, it converts the numeric value into a string of
characters:
display.scroll(str(10))
display.scroll("10")
While this might seem like a lot of work, MicroPython makes this happen extraordinarily fast.
Often you need your program to hang around waiting for something to happen. To do this you make it loop around a
piece of code that defines how to react to certain expected events such as a button press.
To make loops in Python you use the while keyword. It checks if something is True. If it is, it runs a block of code
called the body of the loop. If it isn’t, it breaks out of the loop (ignoring the body) and the rest of the program can
continue.
Python makes it easy to define blocks of code. Say I have a to-do list written on a piece of paper. It probably looks
something like this:
Shopping
Fix broken gutter
Mow the lawn
If I wanted to break down my to-do list a bit further, I might write something like this:
10 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Shopping:
Eggs
Bacon
Tomatoes
Fix broken gutter:
Borrow ladder from next door
Find hammer and nails
Return ladder
Mow the lawn:
Check lawn around pond for frogs
Check mower fuel level
It’s obvious that the main tasks are broken down into sub-tasks that are indented underneath the main task to which
they are related. So Eggs, Bacon and Tomatoes are obviously related to Shopping. By indenting things we
make it easy to see, at a glance, how the tasks relate to each other.
This is called nesting. We use nesting to define blocks of code like this:
display.show(Image.SURPRISED)
The running_time function returns the number of milliseconds since the device started.
The while running_time() < 10000: line checks if the running time is less than 10000 milliseconds (i.e.
10 seconds). If it is, and this is where we can see scoping in action, then it’ll display Image.ASLEEP. Notice how
this is indented underneath the while statement just like in our to-do list.
Obviously, if the running time is equal to or greater than 10000 milliseconds then the display will show Image.
SURPRISED. Why? Because the while condition will be False (running_time is no longer < 10000). In that
case the loop is finished and the program will continue after the while loop’s block of code. It’ll look like your
device is asleep for 10 seconds before waking up with a surprised look on its face.
Try it!
If we want MicroPython to react to button press events we should put it into an infinite loop and check if the button
is_pressed.
An infinite loop is easy:
while True:
# Do stuff
(Remember, while checks if something is True to work out if it should run its block of code. Since True is
obviously True for all time, you get an infinite loop!)
Let’s make a very simple cyber-pet. It’s always sad unless you’re pressing button A. If you press button B it dies. (I
realise this isn’t a very pleasant game, so perhaps you can figure out how to improve it.):
while True:
(continues on next page)
1.3. Buttons 11
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
display.clear()
Can you see how we check what buttons are pressed? We used if, elif (short for “else if”) and else. These are
called conditionals and work like this:
if something is True:
# do one thing
elif some other thing is True:
# do another thing
else:
# do yet another thing.
There are strips of metal along the bottom edge of the BBC micro:bit that make it look as if the device has teeth. These
are the input/output pins (or I/O pins for short).
Some of the pins are bigger than others so it’s possible to attach crocodile clips to them. These are the ones labelled 0,
12 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1, 2, 3V and GND (computers always start counting from zero). If you attach an edge connector board to the device
it’s possible to plug in wires connected to the other (smaller) pins.
In MicroPython, each pin on the BBC micro:bit is represented by an object called pinN, where N is the number pf the
pin.
For example, to use the pin labelled 0 (zero), you can use the object called pin0 in your script.
These objects have various methods associated with them depending upon what the specific pin is capable of eg. read,
write or touch.
The simplest example of input via the pins is a check to see if they are touched. So, you can tickle your micro:bit to
make it laugh like this:
while True:
if pin0.is_touched():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)
With one hand, hold your micro:bit by the GND pin. Then, with your other hand, touch (or tickle) the 0 (zero) pin.
You should see the display change from grumpy to happy!
This is a form of very basic input measurement. However, the fun really starts when you plug in circuits and other
devices via the pins.
The simplest thing we can attach to the micro:bit is a Piezo buzzer. There are two types of piezo buzzers. The simplest
type to use are called active buzzers. Active buzzers contain an oscillator that produces a tone at a predetermined pitch
when a current is passed through them. Passive buzzers require an oscillating current to be passed through them to
produce a tone at the frequency of the oscillation. In short, active buzzers are simple to use but produce only one tone,
while passive buzzers are slightly more complicated to use but can produce a variety of tones.
We’re going to use an active piezo buzzer for output. To attach one to your BBC micro:bit you should attach crocodile
clips to pin 0 and GND (as shown below).
The wire from pin 0 should be attached to the positive connector on the buzzer and the wire from GND to the negative
connector.
The following program will cause the buzzer to make a sound:
pin0.write_digital(1)
This is fun for about 5 seconds and then you’ll want to make the horrible squeaking stop. Let’s improve our example
and make the device bleep:
while True:
pin0.write_digital(1)
sleep(20)
pin0.write_digital(0)
sleep(480)
Can you work out how this script works? Remember that 1 is “on” and 0 is “off” in the digital world.
The device is put into an infinite loop and immediately switches pin 0 on. This causes the buzzer to emit a beep. While
the buzzer is beeping, the device sleeps for twenty milliseconds and then switches pin 0 off. This gives the effect of a
short bleep. Finally, the device sleeps for 480 milliseconds before looping back and starting all over again. This means
you’ll get two bleeps per second (one every 500 milliseconds).
We’ve made a very simple metronome!
1.5 Music
MicroPython on the BBC micro:bit comes with a powerful music and sound module. It’s very easy to generate bleeps
and bloops from the device by attaching a speaker or set of wired headphones.
If you are attaching a speaker, a passive piezo buzzer, or headphones, you can use crocodile clips to attach pin 0 and
GND to the positive and negative inputs. It doesn’t matter which way round they are connected to a speaker, but a
piezo buzzer may be polarized (check for a “+” marking the positive terminal).
14 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Note: Do not attempt this with an active Piezo buzzer - such buzzers are only able to play a single tone.
import music
music.play(music.NYAN)
Notice that we import the music module. It contains methods used to make and control sound.
MicroPython has quite a lot of built-in melodies. Here’s a complete list:
• music.DADADADUM
• music.ENTERTAINER
• music.PRELUDE
• music.ODE
• music.NYAN
• music.RINGTONE
• music.FUNK
• music.BLUES
• music.BIRTHDAY
• music.WEDDING
• music.FUNERAL
• music.PUNCHLINE
• music.PYTHON
• music.BADDY
• music.CHASE
• music.BA_DING
• music.WAWAWAWAA
• music.JUMP_UP
• music.JUMP_DOWN
• music.POWER_UP
1.5. Music 15
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
• music.POWER_DOWN
Take the example code and change the melody. Which one is your favourite? How would you use such tunes as signals
or cues?
NOTE[octave][:duration]
For example, "A1:4" refers to the note named A in octave number 1 to be played for a duration of 4.
Make a list of notes to create a melody (it’s equivalent to creating an animation with a list of images). For example,
here’s how to make MicroPython play opening of “Frere Jaques”:
import music
Note: MicroPython helps you to simplify such melodies. It’ll remember the octave and duration values until you next
change them. As a result, the example above can be re-written as:
import music
tune = ["C4:4", "D", "E", "C", "C", "D", "E", "C", "E", "F", "G:8",
"E:4", "F", "G:8"]
music.play(tune)
Notice how the octave and duration values only change when they have to. It’s a lot less typing and simpler to read.
MicroPython lets you make tones that are not musical notes. For example, here’s how to create a Police siren effect:
import music
while True:
for freq in range(880, 1760, 16):
music.pitch(freq, 6)
for freq in range(1760, 880, -16):
music.pitch(freq, 6)
16 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Notice how the music.pitch method is used in this instance. It expects a frequency. For example, the frequency
of 440 is the same as a concert A used to tune a symphony orchestra.
In the example above the range function is used to generate ranges of numeric values. These numbers are used to
define the pitch of the tone. The three arguments for the range function are the start value, end value and step size.
Therefore, the first use of range is saying, in English, “create a range of numbers between 880 and 1760 in steps of
16”. The second use of range is saying, “create a range of values between 1760 and 880 in steps of -16”. This is
how we get a range of frequencies that go up and down in pitch like a siren.
Because the siren should last forever it’s wrapped in an infinite while loop.
Importantly, we have introduced a new sort of a loop inside the while loop: the for loop. In English it’s like saying,
“for each item in some collection, do some activity with it”. Specifically in the example above, it’s saying, “for each
frequency in the specified range of frequencies, play the pitch of that frequency for 6 milliseconds”. Notice how the
thing to do for each item in a for loop is indented (as discussed earlier) so Python knows exactly which code to run to
handle the individual items.
1.6 Random
Sometimes you want to leave things to chance, or mix it up a little: you want the device to act randomly.
MicroPython comes with a random module to make it easy to introduce chance and a little chaos into your code. For
example, here’s how to scroll a random name across the display:
display.scroll(random.choice(names))
The list (names) contains seven names defined as strings of characters. The final line is nested (the “onion” effect
introduced earlier): the random.choice method takes the names list as an argument and returns an item chosen at
random. This item (the randomly chosen name) is the argument for display.scroll.
Can you modify the list to include your own set of names?
Random numbers are very useful. They’re common in games. Why else do we have dice?
MicroPython comes with several useful random number methods. Here’s how to make a simple dice:
display.show(str(random.randint(1, 6)))
Every time the device is reset it displays a number between 1 and 6. You’re starting to get familiar with nesting, so it’s
important to note that random.randint returns a whole number between the two arguments, inclusive (a whole
number is also called an integer - hence the name of the method). Notice that because display.show expects a
character then we use the str function to turn the numeric value into a character (we turn, for example, 6 into "6").
If you know you’ll always want a number between 0 and N then use the random.randrange method. If you give
it a single argument it’ll return random integers up to, but not including, the value of the argument N (this is different
to the behaviour of random.randint).
1.6. Random 17
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Sometimes you need numbers with a decimal point in them. These are called floating point numbers and it’s possible
to generate such a number with the random.random method. This only returns values between 0.0 and 1.0
inclusive. If you need larger random floating point numbers add the results of random.randrange and random.
random like this:
from microbit import *
import random
The random number generators used by computers are not truly random. They just give random like results given a
starting seed value. The seed is often generated from random-ish values such as the current time and/or readings from
sensors such as the thermometers built into chips.
Sometimes you want to have repeatable random-ish behaviour: a source of randomness that is reproducible. It’s like
saying that you need the same five random values each time you throw a dice.
This is easy to achieve by setting the seed value. Given a known seed the random number generator will create the
same set of random numbers. The seed is set with random.seed and any whole number (integer). This version of
the dice program always produces the same results:
from microbit import *
import random
random.seed(1337)
while True:
if button_a.was_pressed():
display.show(str(random.randint(1, 6)))
Can you work out why this program needs us to press button A instead of reset the device as in the first dice example..?
1.7 Movement
Your BBC micro:bit comes with an accelerometer. It measures movement along three axes:
• X - tilting from left to right.
• Y - tilting forwards and backwards.
• Z - moving up and down.
There is a method for each axis that returns a positive or negative number indicating a measurement in milli-g’s. When
the reading is 0 you are “level” along that particular axis.
For example, here’s a very simple spirit-level that uses get_x to measure how level the device is along the X axis:
from microbit import *
while True:
reading = accelerometer.get_x()
if reading > 20:
display.show("R")
elif reading < -20:
(continues on next page)
18 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
If you hold the device flat it should display -; however, rotate it left or right and it’ll show L and R respectively.
We want the device to constantly react to change, so we use an infinite while loop. The first thing to happen within
the body of the loop is a measurement along the X axis which is called reading. Because the accelerometer is
so sensitive I’ve made level +/-20 in range. It’s why the if and elif conditionals check for > 20 and < -20.
The else statement means that if the reading is between -20 and 20 then we consider it level. For each of these
conditions we use the display to show the appropriate character.
There is also a get_y method for the Y axis and a get_z method for the Z axis.
If you’ve ever wondered how a mobile phone knows which up to show the images on its screen, it’s because it uses
an accelerometer in exactly the same way as the program above. Game controllers also contain accelerometers to help
you steer and move around in games.
One of the most wonderful aspects of MicroPython on the BBC micro:bit is how it lets you easily link different
capabilities of the device together. For example, let’s turn it into a musical instrument (of sorts).
Connect a speaker as you did in the music tutorial. Use crocodile clips to attach pin 0 and GND to the positive and
negative inputs on the speaker - it doesn’t matter which way round they are connected to the speaker.
What happens if we take the readings from the accelerometer and play them as pitches? Let’s find out:
1.7. Movement 19
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
while True:
music.pitch(accelerometer.get_y(), 10)
The key line is at the end and remarkably simple. We nest the reading from the Y axis as the frequency to feed into
the music.pitch method. We only let it play for 10 milliseconds because we want the tone to change quickly as
the device is tipped. Because the device is in an infinite while loop it is constantly reacting to changes in the Y axis
measurement.
That’s it!
Tip the device forwards and backwards. If the reading along the Y axis is positive it’ll change the pitch of the tone
played by the micro:bit.
Imagine a whole symphony orchestra of these devices. Can you play a tune? How would you improve the program to
make the micro:bit sound more musical?
1.8 Gestures
The really interesting side-effect of having an accelerometer is gesture detection. If you move your BBC micro:bit in
a certain way (as a gesture) then MicroPython is able to detect this.
MicroPython is able to recognise the following gestures: up, down, left, right, face up, face down,
freefall, 3g, 6g, 8g, shake. Gestures are always represented as strings. While most of the names should be
obvious, the 3g, 6g and 8g gestures apply when the device encounters these levels of g-force (like when an astronaut
is launched into space).
To get the current gesture use the accelerometer.current_gesture method. Its result is going to be one of
the named gestures listed above. For example, this program will only make your device happy if it is face up:
while True:
gesture = accelerometer.current_gesture()
if gesture == "face up":
display.show(Image.HAPPY)
else:
display.show(Image.ANGRY)
Once again, because we want the device to react to changing circumstances we use a while loop. Within the scope of
the loop the current gesture is read and put into gesture. The if conditional checks if gesture is equal to "face
up" (Python uses == to test for equality, a single equals sign = is used for assignment - just like how we assign the
gesture reading to the gesture object). If the gesture is equal to "face up" then use the display to show a happy
face. Otherwise, the device is made to look angry!
1.8.1 Magic-8
A Magic-8 ball is a toy first invented in the 1950s. The idea is to ask it a yes/no question, shake it and wait for it to
reveal the truth. It’s rather easy to turn into a program:
20 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
answers = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful",
]
while True:
display.show("8")
if accelerometer.was_gesture("shake"):
display.clear()
sleep(1000)
display.scroll(random.choice(answers))
Most of the program is a list called answers. The actual game is in the while loop at the end.
The default state of the game is to show the character "8". However, the program needs to detect if it has been shaken.
The was_gesture method uses its argument (in this case, the string "shake" because we want to detect a shake)
to return a True / False response. If the device was shaken the if conditional drops into its block of code where it
clears the screen, waits for a second (so the device appears to be thinking about your question) and displays a randomly
chosen answer.
Why not ask it if this is the greatest program ever written? What could you do to “cheat” and make the answer always
positive or negative? (Hint: use the buttons.)
1.9 Direction
There is a compass on the BBC micro:bit. If you ever make a weather station use the device to work out the wind
direction.
1.9.1 Compass
1.9. Direction 21
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
while True:
needle = ((15 - compass.heading()) // 30) % 12
display.show(Image.ALL_CLOCKS[needle])
Note: You must calibrate the compass before taking readings. Failure to do so will produce garbage results.
The calibration method runs a fun little game to help the device work out where it is in relation to the Earth’s
magnetic field.
To calibrate the compass, tilt the micro:bit around until a circle of pixels is drawn on the outside edges of the display.
The program takes the compass.heading and, using some simple yet cunning maths, floor division // and modulo
%, works out the number of the clock hand to use to display on the screen so that it is pointing roughly North.
1.10 Storage
Sometimes you need to store useful information. Such information is stored as data: representation of information (in
a digital form when stored on computers). If you store data on a computer it should persist, even if you switch the
device off and on again.
Happily MicroPython on the micro:bit allows you to do this with a very simple file system. Because of memory
constraints there is approximately 30k of storage available on the file system.
Note: The micropython file system should not be confused with the micro:bit mass storage mode which presents the
device as a USB drive. Mass storage mode is only intended for copying across a HEX file, so you won’t see files you
create using the file system appearing on the MICROBIT drive.
22 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
A computer file is a named digital resource that’s stored on a file system. Such resources contain useful information as
data. This is exactly how a paper file works. It’s a sort of named container that contains useful information. Usually,
both paper and digital files are named to indicate what they contain. On computers it is common to end a file with a
.something suffix. Usually, the “something” indicates what type of data is used to represent the information. For
example, .txt indicates a text file, .jpg a JPEG image and .mp3 sound data encoded as MP3.
Some file systems (such as the one found on your laptop or PC) allow you to organise your files into directories: named
containers that group related files and sub-directories together. However, the file system provided by MicroPython is a
flat file system. A flat file system does not have directories - all your files are just stored in the same place.
The Python programming language contains easy to use and powerful ways in which to work with a computer’s file
system. MicroPython on the micro:bit implements a useful subset of these features to make it easy to read and write
files on the device, while also providing consistency with other versions of Python.
Warning: Flashing your micro:bit will DESTROY ALL YOUR DATA since it re-writes all the flash memory
used by the device and the file system is stored in the flash memory.
However, if you switch off your device the data will remain intact until you either delete it or re-flash the device.
Reading and writing a file on the file system is achieved by the open function. Once a file is opened you can do stuff
with it until you close it (analogous with the way we use paper files). It is essential you close a file so MicroPython
1.10. Storage 23
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
The with statement uses the open function to open a file and assign it to an object. In the example above, the open
function opens the file called story.txt (obviously a text file containing a story of some sort). The object that’s
used to represent the file in the Python code is called my_file. Subsequently, in the code block indented underneath
the with statement, the my_file object is used to read() the content of the file and assign it to the content
object.
Here’s the important point, the next line containing the print statement is not indented. The code block associated
with the with statement is only the single line that reads the file. Once the code block associated with the with
statement is closed then Python (and MicroPython) will automatically close the file for you. This is called context
handling and the open function creates objects that are context handlers for files.
Put simply, the scope of your interaction with a file is defined by the code block associated with the with statement
that opens the file.
Confused?
Don’t be. I’m simply saying your code should look like this:
Just like a paper file, a digital file is opened for two reasons: to read its content (as demonstrated above) or to write
something to the file. The default mode is to read the file. If you want to write to a file you need to tell the open
function in the following way:
Notice the 'w' argument is used to set the my_file object into write mode. You could also pass an 'r' argument
to set the file object to read mode, but since this is the default, it’s often left off.
Writing data to the file is done with the (you guessed it) write method that takes the string you want to write to the
file as an argument. In the example above, I write the text “Hello, World!” to a file called “hello.txt”.
Simple!
Note: When you open a file and write (perhaps several times while the file is in an open state) you will be writing
OVER the content of the file if it already exists.
If you want to append data to a file you should first read it, store the content somewhere, close it, append your data to
the content and then open it to write again with the revised content.
While this is the case in MicroPython, “normal” Python can open files to write in “append” mode. That we can’t do
this on the micro:bit is a result of the simple implementation of the file system.
24 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.10.2 OS SOS
As well as reading and writing files, Python can manipulate them. You certainly need to know what files are on the
file system and sometimes you need to delete them too.
On a regular computer, it is the role of the operating system (like Windows, OSX or Linux) to manage this on Python’s
behalf. Such functionality is made available in Python via a module called os. Since MicroPython is the operating
system we’ve decided to keep the appropriate functions in the os module for consistency so you’ll know where to find
them when you use “regular” Python on a device like a laptop or Raspberry Pi.
Essentially, you can do three operations related to the file system: list the files, remove a file and ask for the size of a
file.
To list the files on your file system use the listdir function. It returns a list of strings indicating the file names of
the files on the file system:
import os
my_files = os.listdir()
To delete a file use the remove function. It takes a string representing the file name of the file you want to delete as
an argument, like this:
import os
os.remove('filename.txt')
Finally, sometimes it’s useful to know how big a file is before reading from it. To achieve this use the size function.
Like the remove function, it takes a string representing the file name of the file whose size you want to know. It
returns an integer (whole number) telling you the number of bytes the file takes up:
import os
file_size = os.size('a_big_file.txt')
It’s all very well having a file system, but what if we want to put or get files on or off the device?
Just use the microfs utility!
If you have Python installed on the computer you use to program your BBC micro:bit then you can use a special utility
called microfs (shortened to ufs when using it in the command line). Full instructions for installing and using all
the features of microfs can be found in its documentation.
Nevertheless it’s possible to do most of the things you need with just four simple commands:
$ ufs ls
story.txt
The ls sub-command lists the files on the file system (it’s named after the common Unix command, ls, that serves
the same function).
The get sub-command gets a file from the connected micro:bit and saves it into your current location on your com-
puter (it’s named after the get command that’s part of the common file transfer protocol [FTP] that serves the same
function).
1.10. Storage 25
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
$ ufs rm story.txt
The rm sub-command removes the named file from the file system on the connected micro:bit (it’s named after the
common Unix command, rm, that serves the same function).
Finally, the put sub-command puts a file from your computer onto the connected device (it’s named after the put
command that’s part of FTP that serves the same function).
Note: The ufs get and put commands only operate on one file at a time.
The file system also has an interesting property: if you just flashed the MicroPython runtime onto the device then
when it starts it’s simply waiting for something to do. However, if you copy a special file called main.py onto the
file system, upon restarting the device, MicroPython will run the contents of the main.py file.
Furthermore, if you copy other Python files onto the file system then you can import them as you would any other
Python module. For example, if you had a hello.py file that contained the following simple code:
def say_hello(name="World"):
return "Hello, {}!".format(name)
. . . you could import and use the say_hello function like this:
display.scroll(say_hello())
Of course, it results in the text “Hello, World!” scrolling across the display. The important point is that such an example
is split between two Python modules and the import statement is used to share code.
Note: If you have flashed a script onto the device in addition to the MicroPython runtime, then MicroPython will
ignore main.py and run your embedded script instead.
To flash just the MicroPython runtime, simply make sure the script you may have written in your editor has zero
characters in it. Once flashed you’ll be able to copy over a main.py file.
1.11 Speech
26 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.11. Speech 27
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
28 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
It’s a little known fact that DALEKs enjoy poetry ~ especially limericks. They go wild for anapestic meter with a strict
AABBA form. Who’d have thought?
(Actually, as we’ll learn below, it’s The Doctor’s fault DALEKs like limericks, much to the annoyance of Davros.)
In any case, we’re going to create a DALEK poetry recital on demand.
Before the device can talk you need to plug in a speaker like this:
The simplest way to get the device to speak is to import the speech module and use the say function like this:
import speech
speech.say("Hello, World")
1.11. Speech 29
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
While this is cute it’s certainly not DALEK enough for our taste, so we need to change some of the parameters that
the speech synthesiser uses to produce the voice. Our speech synthesiser is quite powerful in this respect because we
can change four parameters:
• pitch - how high or low the voice sounds (0 = high, 255 = Barry White)
• speed - how quickly the device talks (0 = impossible, 255 = bedtime story)
• mouth - how tight-lipped or overtly enunciating the voice sounds (0 = ventriloquist’s dummy, 255 = Foghorn
Leghorn)
• throat - how relaxed or tense is the tone of voice (0 = falling apart, 255 = totally chilled)
Collectively, these parameters control the quality of sound - a.k.a. the timbre. To be honest, the best way to get the
tone of voice you want is to experiment, use your judgement and adjust.
To adjust the settings you pass them in as arguments to the say function. More details can be found in the speech
module’s API documentation.
After some experimentation we’ve worked out this sounds quite DALEK-esque:
Being Cyborgs DALEKs use their robot capabilities to compose poetry and it turns out that the algorithm they use is
written in Python like this:
# Loop over each line in the poem and use the speech module to recite it.
for line in poem:
(continues on next page)
30 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.11.4 Phonemes
You’ll notice that sometimes, the say function doesn’t accurately translate from English words into the correct sound.
To have fine grained control of the output, use phonemes: the building-block sounds of language.
The advantage of using phonemes is that you don’t have to know how to spell! Rather, you only have to know how to
say the word in order to spell it phonetically.
A full list of the phonemes the speech synthesiser understands can be found in the API documentation for speech.
Alternatively, save yourself a lot of time by passing in English words to the translate function. It’ll return a first
approximation of the phonemes it would use to generate the audio. This result can be hand-edited to improve the
accuracy, inflection and emphasis (so it sounds more natural).
The pronounce function is used for phoneme output like this:
speech.pronounce("/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP.")
How could you improve on The Doctor’s code to make it use phonemes?
By changing the pitch setting and calling the sing function it’s possible to make the device sing (although it’s not
going to win Eurovision any time soon).
The mapping from pitch numbers to musical notes is shown below:
1.11. Speech 31
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
The sing function must take phonemes and pitch as input like this:
speech.sing("#115DOWWWW")
Notice how the pitch to be sung is prepended to the phoneme with a hash (#). The pitch will remain the same for
subsequent phonemes until a new pitch is annotated.
The following example demonstrates how all three generative functions (say, pronounce and sing) can be used
to produce speech like output:
"""
speech.py
~~~~~~~~
Simple speech example to make the micro:bit say, pronounce and sing
something. This example requires a speaker/buzzer/headphones connected
to P0 and GND,or the latest micro:bit device with built-in speaker.
"""
import speech
from microbit import sleep
32 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.12 Network
It is possible to connect devices together to send and receive messages to and from each other. This is called a network.
A network of interconnected networks is called an internet. The Internet is an internet of all the internets.
Networking is hard and this is reflected in the program described below. However, the beautiful thing about this project
is it contains all the common aspects of network programming you need to know about. It’s also remarkably simple
and fun.
But first, let’s set the scene. . .
1.12.1 Connection
Imagine a network as a series of layers. At the very bottom is the most fundamental aspect of communication: there
needs to be some sort of way for a signal to get from one device to the other. Sometimes this is done via a radio
connection, but in this example we’re simply going to use two wires.
1.12. Network 33
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
It is upon this foundation that we can build all the other layers in the network stack.
As the diagram shows, blue and red micro:bits are connected via crocodile leads. Both use pin 1 for output and pin 2
for input. The output from one device is connected to the input on the other. It’s a bit like knowing which way round
to hold a telephone handset - one end has a microphone (the input) and the other a speaker (the output). The recording
of your voice via your microphone is played out of the other person’s speaker. If you hold the phone the wrong way
up, you’ll get strange results!
It’s exactly the same in this instance: you must connect the wires properly!
1.12.2 Signal
The next layer in the network stack is the signal. Often this will depend upon the characteristics of the connection. In
our example it’s simply digital on and off signals sent down the wires via the IO pins.
If you remember, it’s possible to use the IO pins like this:
The next step involves describing how to use and handle a signal. For that we need a. . .
1.12.3 Protocol
If you ever meet the Queen there are expectations about how you ought to behave. For example, when she arrives you
may bow or curtsey, if she offers her hand politely shake it, refer to her as “your majesty” and thereafter as “ma’am”
and so on. This set of rules is called the royal protocol. A protocol explains how to behave given a specific situation
(such as meeting the Queen). A protocol is pre-defined to ensure everyone understands what’s going on before a given
situation arises.
34 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
It is for this reason that we define and use protocols for communicating messages via a computer network. Computers
need to agree before hand how to send and receive messages. Perhaps the best known protocol is the hypertext transfer
protocol (HTTP) used by the world wide web.
Another famous protocol for sending messages (that pre-dates computers) is Morse code. It defines how to send
character-based messages via on/off signals of long or short durations. Often such signals are played as bleeps. Long
durations are called dashes (-) whereas short durations are dots (.). By combining dashes and dots Morse defines a
way to send characters. For example, here’s how the standard Morse alphabet is defined:
Given the chart above, to send the character “H” the signal is switched on four times for a short duration, indicating
four dots (....). For the letter “L” the signal is also switched on four times, but the second signal has a longer
duration (.-..).
Obviously, the timing of the signal is important: we need to tell a dot from a dash. That’s another point of a protocol,
to agree such things so everyone’s implementation of the protocol will work with everyone elses. In this instance we’ll
just say that:
• A signal with a duration less than 250 milliseconds is a dot.
• A signal with a duration from 250 milliseconds to less than 500 milliseconds is a dash.
• Any other duration of signal is ignored.
• A pause / gap in the signal of greater than 500 milliseconds indicates the end of a character.
In this way, the sending of a letter “H” is defined as four “on” signals that last no longer than 250 milliseconds each,
followed by a pause of greater than 500 milliseconds (indicating the end of the character).
1.12. Network 35
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
1.12.4 Message
We’re finally at a stage where we can build a message - a message that actually means something to us humans. This
is the top-most layer of our network stack.
Using the protocol defined above I can send the following sequence of signals down the physical wire to the other
micro:bit:
...././.-../.-../---/.--/---/.-./.-../-..
1.12.5 Application
It’s all very well having a network stack, but you also need a way to interact with it - some form of application to send
and receive messages. While HTTP is interesting most people don’t know about it and let their web-browser handle it
- the underlying network stack of the world wide web is hidden (as it should be).
So, what sort of application should we write for the BBC micro:bit? How should it work, from the user’s point of
view?
Obviously, to send a message you should be able to input dots and dashes (we can use button A for that). If we want to
see the message we sent or just received we should be able to trigger it to scroll across the display (we can use button
B for that). Finally, this being Morse code, if a speaker is attached, we should be able to play the beeps as a form of
aural feedback while the user is entering their message.
Here’s the program, in all its glory and annotated with plenty of comments so you can see what’s going on:
36 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
def decode(buffer):
# Attempts to get the buffer of Morse code data from the lookup table. If
# it's not there, just return a full stop.
return MORSE_CODE_LOOKUP.get(buffer, '.')
# To create a DOT you need to hold the button for less than 250ms.
DOT_THRESHOLD = 250
# To create a DASH you need to hold the button for less than 500ms.
DASH_THRESHOLD = 500
# Put the device in a loop to wait for and react to key presses.
(continues on next page)
1.12. Network 37
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
38 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
How would you improve it? Can you change the definition of a dot and a dash so speedy Morse code users can use it?
What happens if both devices are sending at the same time? What might you do to handle this situation?
1.13 Radio
1.13.2 Bytes
A byte is a unit of information that (usually) consists of eight bits. A bit is the smallest possible unit of information
since it can only be in two states: on or off.
Bytes work like a sort of abacus: each position in the byte is like a column in an abacus - they represent an associated
number. In an abacus these are usually thousands, hundreds, tens and units (in UK parlance). In a byte they are 128,
64, 32, 16, 8, 4, 2 and 1. As bits (on/off signals) are sent over the air, they are re-combined into bytes by the recipient.
Have you spotted the pattern? (Hint: base 2.)
By adding the numbers associated with the positions in a byte that are set to “on” we can represent numbers between
0 and 255. The image below shows how this works with five bits and counting from zero to 32:
1.13. Radio 39
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
If we can agree what each one of the 255 numbers (encoded by a byte) represents ~ such as a character ~ then we can
start to send text one character per byte at a time.
Funnily enough, people have already thought of this ~ using bytes to encode and decode information is commonplace.
This approximately corresponds to the Morse-code “protocol” layer in the wired networking example.
A really great series of child (and teacher) friendly explanations of “all things bytes” can be found at the CS unplugged
website.
1.13.3 Addressing
The problem with radio is that you can’t transmit directly to one person. Anyone with an appropriate aerial can receive
the messages you transmit. As a result it’s important to be able to differentiate who should be receiving broadcasts.
The way the radio built into the micro:bit solves this problem is quite simple:
• It’s possible to tune the radio to different channels (numbered 0-83). This works in exactly the same way as kids’
walkie-talkie radios: everyone tunes into the same channel and everyone hears what everyone else broadcasts
via that channel. As with walkie-talkies, if you use adjacent channels there is a slight possibility of interference.
• The radio module allows you to specify two pieces of information: an address and a group. The address is like
a postal address whereas a group is like a specific recipient at the address. The important thing is the radio
will filter out messages that it receives that do not match your address and group. As a result, it’s important to
pre-arrange the address and group your application is going to use.
Of course, the micro:bit is still receiving broadcast messages for other address/group combinations. The important
thing is you don’t need to worry about filtering those out. Nevertheless, if someone were clever enough, they could
just read all the wireless network traffic no matter what the target address/group was supposed to be. In this case, it’s
essential to use encrypted means of communication so only the desired recipient can actually read the message that
was broadcast. Cryptography is a fascinating subject but, unfortunately, beyond the scope of this tutorial.
1.13.4 Fireflies
This is a firefly:
It’s a sort of bug that uses bioluminescence to signal (without wires) to its friends. Here’s what they look like when
they signal to each other:
radio.send("a message")
The example uses the send function to simply broadcast the string “a message”. To receive a message is even easier:
40 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
new_message = radio.receive()
As messages are received they are put on a message queue. The receive function returns the oldest message from
the queue as a string, making space for a new incoming message. If the message queue fills up, then new incoming
messages are ignored.
That’s really all there is to it! (Although the radio module is also powerful enough that you can send any arbitrary type
of data, not just strings. See the API documentation for how this works.)
Armed with this knowledge, it’s simple to make micro:bit fireflies like this:
# A micro:bit Firefly.
# By Nicholas H.Tollervey. Released to the public domain.
import radio
import random
from microbit import display, Image, button_a, sleep
# Create the "flash" animation frames. Can you work out how it's done?
flash = [Image().invert()*(i/9) for i in range(9, -1, -1)]
# Event loop.
while True:
# Button A sends a "flash" message.
if button_a.was_pressed():
radio.send('flash') # a-ha
# Read any incoming messages.
incoming = radio.receive()
if incoming == 'flash':
# If there's an incoming "flash" message display
# the firefly flash animation after a random short
# pause.
sleep(random.randint(50, 350))
display.show(flash, delay=100, wait=False)
# Randomly re-broadcast the flash message after a
# slight delay.
if random.randint(0, 9) == 0:
sleep(500)
radio.send('flash') # a-ha
The important stuff happens in the event loop. First, it checks if button A was pressed and, if it was, uses the radio to
send the message “flash”. Then it reads any messages from the message queue with radio.receive(). If there is
a message it sleeps a short, random period of time (to make the display more interesting) and uses display.show()
to animate a firefly flash. Finally, to make things a bit exciting, it chooses a random number so that it has a 1 in 10
chance of re-broadcasting the “flash” message to anyone else (this is how it’s possible to sustain the firefly display
among several devices). If it decides to re-broadcast then it waits for half a second (so the display from the initial
flash message has chance to die down) before sending the “flash” signal again. Because this code is enclosed within a
while True block, it loops back to the beginning of the event loop and repeats this process forever.
The end result (using a group of micro:bits) should look something like this:
These tutorials are only the first steps in using MicroPython with the BBC micro:bit. A musical analogy: you’ve got
a basic understanding of a very simple instrument and confidently play “Three Blind Mice”.
Code,
Hack it,
Less is more,
Keep it simple,
Small is beautiful,
(continues on next page)
42 Chapter 1. Introduction
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Best of luck!
44 Chapter 1. Introduction
CHAPTER 2
Everything directly related to interacting with the hardware lives in the microbit module. For ease of use it’s recom-
mended you start all scripts with:
The rest of the functionality is provided by objects and classes in the microbit module, as described below.
Note that the API exposes integers only (ie no floats are needed, but they may be accepted). We thus use milliseconds
for the standard time unit.
Note: You can see a list of all available modules by writing help('modules') in the REPL.
45
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
2.1.1 Buttons
button_a
button_b
2.1.2 Display
# gets the brightness of the pixel (x,y). Brightness can be from 0 (the pixel
# is off) to 9 (the pixel is at maximum brightness).
display.get_pixel(x, y)
# sets the brightness of the pixel (x,y) to val (between 0 [off] and 9 [max
# brightness], inclusive).
display.set_pixel(x, y, val)
# clears the display.
display.clear()
# shows the image.
display.show(image, delay=0, wait=True, loop=False, clear=False)
# shows each image or letter in the iterable, with delay ms. in between each.
display.show(iterable, delay=400, wait=True, loop=False, clear=False)
# scrolls a string across the display (more exciting than display.show for
# written messages).
display.scroll(string, delay=400)
2.1.3 Pins
Provide digital and analog input and output functionality, for the pins in the connector. Some pins are connected
internally to the I/O that drives the LED matrix and the buttons.
Each pin is provided as an object directly in the microbit module. This keeps the API relatively flat, making it very
easy to use:
• pin0
• pin1
• ...
• pin15
• pin16
• Warning: P17-P18 (inclusive) are unavailable.
• pin19
• pin20
Each of these pins are instances of the MicroBitPin class, which offers the following API:
2.1.4 Images
Images API:
# methods
# returns the image's width (most often 5)
image.width()
# returns the image's height (most often 5)
image.height()
# sets the pixel at the specified position (between 0 and 9). May fail for
# constant images.
image.set_pixel(x, y, value)
# gets the pixel at the specified position (between 0 and 9)
image.get_pixel(x, y)
# returns a new image created by shifting the picture left 'n' times.
image.shift_left(n)
# returns a new image created by shifting the picture right 'n' times.
image.shift_right(n)
# returns a new image created by shifting the picture up 'n' times.
image.shift_up(n)
# returns a new image created by shifting the picture down 'n' times.
(continues on next page)
#operators
# returns a new image created by superimposing the two images
image + image
# returns a new image created by multiplying the brightness of each pixel by n
image * n
Built-in images
Image.HEART Image.HEART_SMALL Image.HAPPY Image.SMILE Image.SAD Image.CONFUSED
Image.ANGRY Image.ASLEEP Image.SURPRISED Image.SILLY Image.FABULOUS Image.MEH
Image.YES Image.NO Image.TRIANGLE Image.TRIANGLE_LEFT Image.CHESSBOARD Image.
DIAMOND Image.DIAMOND_SMALL Image.SQUARE Image.SQUARE_SMALL Image.RABBIT Image.
COW Image.MUSIC_CROTCHET Image.MUSIC_QUAVER Image.MUSIC_QUAVERS Image.PITCHFORK
Image.XMAS Image.PACMAN Image.TARGET Image.TSHIRT Image.ROLLERSKATE Image.DUCK
Image.HOUSE Image.TORTOISE Image.BUTTERFLY Image.STICKFIGURE Image.GHOST Image.
SWORD Image.GIRAFFE Image.SKULL Image.UMBRELLA Image.SNAKE Image.SCISSORS
Clock:
Image.CLOCK1 Image.CLOCK2 Image.CLOCK3 Image.CLOCK4 Image.CLOCK5 Image.CLOCK6
Image.CLOCK7 Image.CLOCK8 Image.CLOCK9 Image.CLOCK10 Image.CLOCK11 Image.CLOCK12
Arrows:
Image.ARROW_N Image.ARROW_NE Image.ARROW_E Image.ARROW_SE Image.ARROW_S Image.
ARROW_SW Image.ARROW_W Image.ARROW_NW
The following are Python lists of images, useful for automatically displaying an animation or manually iterating
through them.
Image.ALL_CLOCKS Image.ALL_ARROWS
2.1.5 Accelerometer
The recognised gestures are: up, down, left, right, face up, face down, freefall, 3g, 6g, 8g, shake.
2.1.6 Compass
There is an I2C bus on the micro:bit that is exposed via the i2c object. It has the following methods:
# read n bytes from device with addr; repeat=True means a stop bit won't
# be sent.
i2c.read(addr, n, repeat=False)
# write buf to device with addr; repeat=True means a stop bit won't be sent.
i2c.write(addr, buf, repeat=False)
2.1.8 UART
Use uart to communicate with a serial device connected to the device’s I/O pins:
# set up communication (use pins 0 [TX] and 1 [RX]) with a baud rate of 9600.
uart.init()
# return True or False to indicate if there are incoming characters waiting to
# be read.
uart.any()
# return (read) n incoming characters.
uart.read(n)
# return (read) as much incoming data as possible.
uart.read()
# return (read) all the characters to a newline character is reached.
uart.readline()
# read bytes into the referenced buffer.
uart.readinto(buffer)
# write bytes from the buffer to the connected device.
uart.write(buffer)
Microbit Module
The microbit module gives you access to all the hardware that is built-in into your board.
3.1 Functions
microbit.panic(n)
Enter a panic mode that stops all execution, scrolls an error code in the micro:bit display and requires restart:
microbit.panic(255)
microbit.reset()
Restart the board.
microbit.running_time()
Returns The number of milliseconds since the board was switched on or restarted.
microbit.scale(value, from_, to)
Converts a value from a range to another range.
For example, to convert 30 degrees from Celsius to Fahrenheit:
This can be useful to convert values between inputs and outputs, for example an accelerometer x value to a
speaker volume.
Negative scaling is also supported, for example scale(25, from_=(0, 100), to=(0, -200)) will
return -50.
Parameters
• value – A number to convert.
51
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
3.2 Attributes
3.2.1 Buttons
There are two buttons on the board, called button_a and button_b.
Attributes
button_a
A Button instance (see below) representing the left button.
button_b
Represents the right button.
Classes
class Button
Represents a button.
Note: This class is not actually available to the user, it is only used by the two button instances, which are
provided already initialized.
is_pressed()
Returns True if the specified button button is currently being held down, and False otherwise.
was_pressed()
Returns True or False to indicate if the button was pressed (went from up to down) since the device
started or the last time this method was called. Calling this method will clear the press state so that the
button must be pressed again before this method will return True again.
get_presses()
Returns the running total of button presses, and resets this total to zero before returning.
Example
import microbit
while True:
if microbit.button_a.is_pressed() and microbit.button_b.is_pressed():
microbit.display.scroll("AB")
break
elif microbit.button_a.is_pressed():
microbit.display.scroll("A")
elif microbit.button_b.is_pressed():
microbit.display.scroll("B")
microbit.sleep(100)
The pins are your board’s way to communicate with external devices connected to it. There are 19 pins for your
disposal, numbered 0-16 and 19-20. Pins 17 and 18 are not available.
For example, the script below will change the display on the micro:bit depending upon the digital reading on pin 0:
while True:
if pin0.read_digital():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)
3.2. Attributes 53
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Pin Functions
This table summarises the pins available, their types and what they are internally connected to. The pins are available
as attributes on the microbit module: microbit.pin0 - microbit.pin20.
Pulse-Width Modulation
The pins of your board cannot output analog signal the way an audio amplifier can do it – by modulating the voltage
on the pin. Those pins can only either enable the full 3.3V output, or pull it down to 0V. However, it is still possible
to control the brightness of LEDs or speed of an electric motor, by switching that voltage on and off very fast, and
controlling how long it is on and how long it is off. This technique is called Pulse-Width Modulation (PWM), and
that’s what the write_analog method below does.
3.2. Attributes 55
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Above you can see the diagrams of three different PWM signals. All of them have the same period (and thus fre-
quency), but they have different duty cycles.
The first one would be generated by write_analog(511), as it has exactly 50% duty – the power is on half of the
time, and off half of the time. The result of that is that the total energy of this signal is the same, as if it was 1.65V
instead of 3.3V.
The second signal has 25% duty cycle, and could be generated with write_analog(255). It has similar effect as
if 0.825V was being output on that pin.
The third signal has 75% duty cycle, and can be generated with write_analog(767). It has three times as much
energy, as the second signal, and is equivalent to outputting 2.475V on th pin.
Note that this works well with devices such as motors, which have huge inertia by themselves, or LEDs, which blink
too fast for the human eye to see the difference, but will not work so good with generating sound waves. This board
can only generate square wave sounds on itself, which sound pretty much like the very old computer games – mostly
because those games also only could do that.
Classes
There are three kinds of pins, differing in what is available for them. They are represented by the classes listed below.
Note that they form a hierarchy, so that each class has all the functionality of the previous class, and adds its own to
that.
Note: Those classes are not actually available for the user, you can’t create new instances of them. You can only use
the instances already provided, representing the physical pins on your board.
class microbit.MicroBitDigitalPin
read_digital()
Return 1 if the pin is high, and 0 if it’s low.
write_digital(value)
Set the pin to high if value is 1, or to low, if it is 0.
set_pull(value)
Set the pull state to one of three possible values: pin.PULL_UP, pin.PULL_DOWN or pin.NO_PULL
(where pin is an instance of a pin). See below for discussion of default pull states.
get_pull()
Returns the pull configuration on a pin, which can be one of three possible values: NO_PULL,
PULL_DOWN, or PULL_UP. These are set using the set_pull() method or automatically configured
when a pin mode requires it.
get_mode()
Returns the pin mode. When a pin is used for a specific function, like writing a digital value,
or reading an analog value, the pin mode changes. Pins can have one of the following modes:
"unused", "analog", "read_digital", "write_digital", "display", "button",
"music", "audio", "touch", "i2c", "spi".
write_analog(value)
Output a PWM signal on the pin, with the duty cycle proportional to the provided value. The value
may be either an integer or a floating point number between 0 (0% duty cycle) and 1023 (100% duty).
set_analog_period(period)
Set the period of the PWM signal being output to period in milliseconds. The minimum valid value is
1ms.
set_analog_period_microseconds(period)
Set the period of the PWM signal being output to period in microseconds. The minimum valid value is
256µs.
get_analog_period_microseconds()
Returns the configured period of the PWM signal in microseconds.
class microbit.MicroBitAnalogDigitalPin
read_analog()
Read the voltage applied to the pin, and return it as an integer between 0 (meaning 0V) and 1023 (meaning
3.3V).
class microbit.MicroBitTouchPin
is_touched()
Return True if the pin is being touched with a finger, otherwise return False.
This test is done by measuring how much resistance there is between the pin and ground. A low resistance
gives a reading of True. To get a reliable reading using a finger you may need to touch the ground pin
with another part of your body, for example your other hand.
The pull mode for a pin is automatically configured when the pin changes to an input mode. Input modes are when you
call read_analog / read_digital / is_touched. The default pull mode for these is, respectively, NO_PULL,
PULL_DOWN, PULL_UP. Calling set_pull will configure the pin to be in read_digital mode with the given
pull mode.
Note: The micro:bit has external weak (10M) pull-ups fitted on pins 0, 1 and 2 only, in order for the touch sensing to
work.
3.2. Attributes 57
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
There are also external (10k) pull-ups fitted on pins 5 and 11, in order for buttons A and B to work.
For more info see the edge connector data sheet.
Note: GPIO pins are also used for the display, as described in the table above. If you want to use these pins for
another purpose, you may need to turn the display off.
For more info see the edge connector data sheet.
3.3 Classes
3.3.1 Image
The Image class is used to create images that can be displayed easily on the device’s LED matrix. Given an image
object it’s possible to display it via the display API:
display.show(Image.HAPPY)
• Image(string) - Create an image by parsing the string, a single character returns that glyph
• Image(width, height) - Create a blank image of given size
• Image(width, height, buffer) - Create an image from the given buffer
Classes
class microbit.Image(string)
class microbit.Image(width=None, height=None, buffer=None)
If string is used, it has to consist of digits 0-9 arranged into lines, describing the image, for example:
image = Image("90009:"
"09090:"
"00900:"
"09090:"
"90009")
will create a 5×5 image of an X. The end of a line is indicated by a colon. It’s also possible to use a newline (n)
to indicate the end of a line like this:
image = Image("90009\n"
"09090\n"
"00900\n"
"09090\n"
"90009")
The other form creates an empty image with width columns and height rows. Optionally buffer can be
an array of width``×``height integers in range 0-9 to initialize the image:
Image(2, 2, b'\x08\x08\x08\x08')
or:
Image(2, 2, bytearray([9,9,9,9]))
width()
Return the number of columns in the image.
height()
Return the numbers of rows in the image.
set_pixel(x, y, value)
Set the brightness of the pixel at column x and row y to the value, which has to be between 0 (dark) and
9 (bright).
This method will raise an exception when called on any of the built-in read-only images, like Image.
HEART.
get_pixel(x, y)
Return the brightness of pixel at column x and row y as an integer between 0 and 9.
shift_left(n)
Return a new image created by shifting the picture left by n columns.
3.3. Classes 59
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
shift_right(n)
Same as image.shift_left(-n).
shift_up(n)
Return a new image created by shifting the picture up by n rows.
shift_down(n)
Same as image.shift_up(-n).
crop(x, y, w, h)
Return a new image by cropping the picture to a width of w and a height of h, starting with the pixel at
column x and row y.
copy()
Return an exact copy of the image.
invert()
Return a new image by inverting the brightness of the pixels in the source image.
fill(value)
Set the brightness of all the pixels in the image to the value, which has to be between 0 (dark) and 9
(bright).
This method will raise an exception when called on any of the built-in read-only images, like Image.
HEART.
blit(src, x, y, w, h, xdest=0, ydest=0)
Copy the rectangle defined by x, y, w, h from the image src into this image at xdest, ydest. Areas in
the source rectangle, but outside the source image are treated as having a value of 0.
shift_left(), shift_right(), shift_up(), shift_down() and crop() can are all imple-
mented by using blit(). For example, img.crop(x, y, w, h) can be implemented as:
Attributes
The Image class also has the following built-in instances of itself included as its attributes (the attribute names indicate
what the image represents):
• Image.HEART
• Image.HEART_SMALL
• Image.HAPPY
• Image.SMILE
• Image.SAD
• Image.CONFUSED
• Image.ANGRY
• Image.ASLEEP
• Image.SURPRISED
• Image.SILLY
• Image.FABULOUS
• Image.MEH
• Image.YES
• Image.NO
• Image.CLOCK12, Image.CLOCK11, Image.CLOCK10, Image.CLOCK9, Image.CLOCK8, Image.
CLOCK7, Image.CLOCK6, Image.CLOCK5, Image.CLOCK4, Image.CLOCK3, Image.CLOCK2,
Image.CLOCK1
• Image.ARROW_N, Image.ARROW_NE, Image.ARROW_E, Image.ARROW_SE, Image.ARROW_S,
Image.ARROW_SW, Image.ARROW_W, Image.ARROW_NW
• Image.TRIANGLE
• Image.TRIANGLE_LEFT
• Image.CHESSBOARD
• Image.DIAMOND
• Image.DIAMOND_SMALL
• Image.SQUARE
• Image.SQUARE_SMALL
• Image.RABBIT
• Image.COW
• Image.MUSIC_CROTCHET
• Image.MUSIC_QUAVER
• Image.MUSIC_QUAVERS
• Image.PITCHFORK
• Image.XMAS
• Image.PACMAN
• Image.TARGET
• Image.TSHIRT
• Image.ROLLERSKATE
• Image.DUCK
• Image.HOUSE
• Image.TORTOISE
• Image.BUTTERFLY
• Image.STICKFIGURE
• Image.GHOST
• Image.SWORD
• Image.GIRAFFE
• Image.SKULL
• Image.UMBRELLA
3.3. Classes 61
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
• Image.SNAKE
• Image.SCISSORS
Finally, related collections of images have been grouped together:
* ``Image.ALL_CLOCKS``
* ``Image.ALL_ARROWS``
Operations
repr(image)
Create a new image by adding the brightness values from the two images for each pixel.
image * n
3.4 Modules
3.4.1 Accelerometer
Note: Gestures are not updated in the background so there needs to be constant calls to some accelerometer method
to do the gesture detection. Usually gestures can be detected using a loop with a small microbit.sleep() delay.
Functions
microbit.accelerometer.get_x()
Returns The acceleration measurement in the x axis in milli-g, as a positive or negative integer.
microbit.accelerometer.get_y()
Returns The acceleration measurement in the y axis in milli-g, as a positive or negative integer.
microbit.accelerometer.get_z()
Returns The acceleration measurement in the z axis in milli-g, as a positive or negative integer.
microbit.accelerometer.get_values()
Returns The acceleration measurements in all axes at once, as a three-element tuple of integers
ordered as X, Y, Z.
microbit.accelerometer.get_strength()
Get the acceleration measurement of all axes combined, as a positive integer. This is the Pythagorean sum of
the X, Y and Z axes.
Returns The combined acceleration strength of all the axes, in milli-g.
microbit.accelerometer.current_gesture()
Returns String with the name of the current gesture.
microbit.accelerometer.is_gesture(name)
Parameters name – String with the name of the gesture to check.
Returns Boolean indicating if the named gesture is currently active.
microbit.accelerometer.was_gesture(name)
Parameters name – String with the name of the gesture to check.
Returns Boolean indicating if the named gesture was active since the last call.
microbit.accelerometer.get_gestures()
Get a historical list of the registered gestures.
Calling this function clears the gesture history before returning.
Returns A tuple of the gesture history, most recent is listed last.
microbit.accelerometer.set_range(value)
Set the accelerometer sensitivity range, in g (standard gravity), to the closest values supported by the hardware,
so it rounds to either 2, 4, or 8 g.
Parameters value – New range for the accelerometer, an integer in g.
Examples
A fortune telling magic 8-ball. Ask a question then shake the device for an answer.
answers = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
(continues on next page)
3.4. Modules 63
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
while True:
display.show('8')
if accelerometer.was_gesture('shake'):
display.clear()
sleep(1000)
display.scroll(random.choice(answers))
sleep(10)
import microbit as m
import random
p = m.display.show
min_x = -1024
max_x = 1024
range_x = max_x - min_x
wall_min_speed = 400
player_min_speed = 200
wall_max_speed = 100
player_max_speed = 50
speed_max = 12
while True:
i = m.Image('00000:'*5)
s = i.set_pixel
player_x = 2
wall_y = -1
hole = 0
wall_speed = wall_min_speed
player_speed = player_min_speed
wall_next = 0
player_next = 0
while True:
t = m.running_time()
player_update = t >= player_next
wall_update = t >= wall_next
if not (player_update or wall_update):
next_event = min(wall_next, player_next)
delta = next_event - t
m.sleep(delta)
continue
if wall_update:
# calculate new speeds
speed = min(score, speed_max)
wall_speed = wall_min_speed + int((wall_max_speed - wall_min_speed) *
˓→speed / speed_max)
wall_next = t + wall_speed
if wall_y < 5:
# erase old wall
use_wall_y = max(wall_y, 0)
for wall_x in range(5):
if wall_x != hole:
s(wall_x, use_wall_y, 0)
wall_reached_player = (wall_y == 4)
if player_update:
player_next = t + player_speed
# find new x coord
x = m.accelerometer.get_x()
x = min(max(min_x, x), max_x)
# print("x accel", x)
s(player_x, 4, 0) # turn off old pixel
x = ((x - min_x) / range_x) * 5
x = min(max(0, x), 4)
x = int(x + 0.5)
# print("have", position, "want", x)
if not handled_this_wall:
if player_x < x:
player_x += 1
elif player_x > x:
player_x -= 1
# print("new", position)
# print()
if wall_update:
(continues on next page)
3.4. Modules 65
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
if wall_y < 5:
# draw new wall
use_wall_y = max(wall_y, 0)
for wall_x in range(5):
if wall_x != hole:
s(wall_x, use_wall_y, 6)
if player_update:
s(player_x, 4, 9) # turn on new pixel
p(i)
p(i.SAD)
m.sleep(1000)
m.display.scroll("Score:" + str(score))
while True:
if (m.button_a.is_pressed() and m.button_a.is_pressed()):
break
m.sleep(100)
3.4.2 Compass
This module lets you access the built-in electronic compass. Before using, the compass should be calibrated, otherwise
the readings may be wrong.
Warning: Calibrating the compass will cause your program to pause until calibration is complete. Calibration
consists of a little game to draw a circle on the LED display by rotating the device.
Functions
microbit.compass.calibrate()
Starts the calibration process. An instructive message will be scrolled to the user after which they will need to
rotate the device in order to draw a circle on the LED display.
microbit.compass.is_calibrated()
Returns True if the compass has been successfully calibrated, and returns False otherwise.
microbit.compass.clear_calibration()
Undoes the calibration, making the compass uncalibrated again.
microbit.compass.get_x()
Gives the reading of the magnetic field strength on the x axis in nano tesla, as a positive or negative integer,
depending on the direction of the field.
microbit.compass.get_y()
Gives the reading of the magnetic field strength on the y axis in nano tesla, as a positive or negative integer,
depending on the direction of the field.
microbit.compass.get_z()
Gives the reading of the magnetic field strength on the z axis in nano tesla, as a positive or negative integer,
depending on the direction of the field.
microbit.compass.heading()
Gives the compass heading, calculated from the above readings, as an integer in the range from 0 to 360,
representing the angle in degrees, clockwise, with north as 0.
microbit.compass.get_field_strength()
Returns an integer indication of the magnitude of the magnetic field around the device in nano tesla.
Example
"""
compass.py
~~~~~~~~~~
Creates a compass.
The user will need to calibrate the compass first. The compass uses the
built-in clock images to display the position of the needle.
"""
from microbit import *
# Start calibrating
compass.calibrate()
3.4.3 Display
This module controls the 5×5 LED display on the front of your board. It can be used to display images, animations
and even text.
3.4. Modules 67
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Functions
microbit.display.get_pixel(x, y)
Return the brightness of the LED at column x and row y as an integer between 0 (off) and 9 (bright).
microbit.display.set_pixel(x, y, value)
Set the brightness of the LED at column x and row y to value, which has to be an integer between 0 and 9.
microbit.display.clear()
Set the brightness of all LEDs to 0 (off).
microbit.display.show(image)
Display the image.
microbit.display.show(image, delay=400, *, wait=True, loop=False, clear=False)
If image is a string, float or integer, display letters/digits in sequence. Otherwise, if image is an iterable
sequence of images, display these images in sequence. Each letter, digit or image is shown with delay mil-
liseconds between them.
If wait is True, this function will block until the animation is finished, otherwise the animation will happen
in the background.
If loop is True, the animation will repeat forever.
If clear is True, the display will be cleared after the iterable has finished.
Note that the wait, loop and clear arguments must be specified using their keyword.
Note: If using a generator as the iterable, then take care not to allocate any memory in the generator as allocating
memory in an interrupt is prohibited and will raise a MemoryError.
Example
To continuously scroll a string across the display, and do it in the background, you can use:
import microbit
3.4.4 I2 C
The i2c module lets you communicate with devices connected to your board using the I2 C bus protocol. There can
be multiple slave devices connected at the same time, and each one has its own unique address, that is either fixed for
the device or configured on it. Your board acts as the I2 C master.
We use 7-bit addressing for devices because of the reasons stated here.
This may be different to other micro:bit related solutions.
How exactly you should communicate with the devices, that is, what bytes to send and how to interpret the responses,
depends on the device in question and should be described separately in that device’s documentation.
Functions
Warning: Changing the I2 C pins from defaults will make the accelerometer and compass stop working, as
they are connected internally to those pins.
microbit.i2c.scan()
Scan the bus for devices. Returns a list of 7-bit addresses corresponding to those devices that responded to the
scan.
microbit.i2c.read(addr, n, repeat=False)
Read n bytes from the device with 7-bit address addr. If repeat is True, no stop bit will be sent.
microbit.i2c.write(addr, buf, repeat=False)
Write bytes from buf to the device with 7-bit address addr. If repeat is True, no stop bit will be sent.
Connecting
You should connect the device’s SCL pin to micro:bit pin 19, and the device’s SDA pin to micro:bit pin 20. You also
must connect the device’s ground to the micro:bit ground (pin GND). You may need to power the device using an
external power supply or the micro:bit.
There are internal pull-up resistors on the I2 C lines of the board, but with particularly long wires or large number of
devices you may need to add additional pull-up resistors, to ensure noise-free communication.
3.4. Modules 69
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
3.4.5 SPI
The spi module lets you talk to a device connected to your board using a serial peripheral interface (SPI) bus. SPI
uses a so-called master-slave architecture with a single master. You will need to specify the connections for three
signals:
• SCLK : Serial Clock (output from master).
• MOSI : Master Output, Slave Input (output from master).
• MISO : Master Input, Slave Output (output from slave).
Functions
Polarity (aka CPOL) 0 means that the clock is at logic value 0 when idle and goes high (logic value 1) when
active; polarity 1 means the clock is at logic value 1 when idle and goes low (logic value 0) when active. Phase
(aka CPHA) 0 means that data is sampled on the leading edge of the clock, and 1 means on the trailing edge
(viz. https://en.wikipedia.org/wiki/Signal_edge).
The sclk, mosi and miso arguments specify the pins to use for each type of signal.
spi.read(nbytes)
Read at most nbytes. Returns what was read.
spi.write(buffer)
Write the buffer of bytes to the bus.
spi.write_readinto(out, in)
Write the out buffer to the bus and read any response into the in buffer. The length of the buffers should be
the same. The buffers can be the same object.
3.4.6 UART
The uart module lets you talk to a device connected to your board using a serial interface.
Functions
Warning: Initializing the UART on external pins will cause the Python console on USB to become unac-
cessible, as it uses the same hardware. To bring the console back you must reinitialize the UART without
passing anything for tx or rx (or passing None to these arguments). This means that calling uart.
init(115200) is enough to restore the Python console.
The baudrate defines the speed of communication. Common baud rates include:
• 9600
• 14400
• 19200
• 28800
• 38400
• 57600
• 115200
The bits defines the size of bytes being transmitted, and the board only supports 8. The parity parameter
defines how parity is checked, and it can be None, microbit.uart.ODD or microbit.uart.EVEN. The
stop parameter tells the number of stop bits, and has to be 1 for this board.
If tx and rx are not specified then the internal USB-UART TX/RX pins are used which connect to the USB
serial converter on the micro:bit, thus connecting the UART to your PC. You can specify any other pins you
want by passing the desired pin objects to the tx and rx parameters.
Note: When connecting the device, make sure you “cross” the wires – the TX pin on your board needs to be
connected with the RX pin on the device, and the RX pin – with the TX pin on the device. Also make sure the
ground pins of both devices are connected.
uart.any()
Return True if any data is waiting, else False.
uart.read([nbytes ])
Read bytes. If nbytes is specified then read at most that many bytes, otherwise read as many bytes as possible.
Return value: a bytes object or None on timeout.
A bytes object contains a sequence of bytes. Because ASCII characters can fit in single bytes this type of object
is often used to represent simple text and offers methods to manipulate it as such, e.g. you can display the text
using the print() function.
You can also convert this object into a string object, and if there are non-ASCII characters present the encoding
can be specified:
msg_bytes = uart.read()
msg_str = str(msg, 'UTF-8')
3.4. Modules 71
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Note: The timeout for all UART reads depends on the baudrate and is otherwise not changeable via Python.
The timeout, in milliseconds, is given by: microbit_uart_timeout_char = 13000 / baudrate
+ 1
Note: The internal UART RX buffer is 64 bytes, so make sure data is read before the buffer is full or some of
the data might be lost.
Warning: Receiving 0x03 will stop your program by raising a Keyboard Interrupt. You can enable or
disable this using micropython.kbd_intr().
uart.readall()
Removed since version 1.0.
Instead, use uart.read() with no arguments, which will read as much data as possible.
uart.readinto(buf [, nbytes ])
Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most
len(buf) bytes.
Return value: number of bytes read and stored into buf or None on timeout.
uart.readline()
Read a line, ending in a newline character.
Return value: the line read or None on timeout. The newline character is included in the returned bytes.
uart.write(buf )
Write the buffer to the bus, it can be a bytes object or a string:
uart.write('hello world')
uart.write(b'hello world')
uart.write(bytes([1, 2, 3]))
Audio
This module allows you play sounds from a speaker attached to the micro:bit.
The audio module can be imported as import audio or accessed via the microbit module as microbit.
audio.
In order to use the audio module you will need to provide a sound source.
A sound source is an iterable (sequence, like list or tuple, or a generator) of frames, each of 32 samples. The audio
modules plays samples at the rate of 7812.5 samples per second, which means that it can reproduce frequencies up to
3.9kHz.
4.1 Functions
4.2 Classes
class audio.AudioFrame
An AudioFrame object is a list of 32 samples each of which is an unsigned byte (whole number between 0
and 255).
It takes just over 4 ms to play a single frame.
73
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
copyfrom(other)
Overwrite the data in this AudioFrame with the data from another AudioFrame instance.
Parameters other – AudioFrame instance from which to copy the data.
You will need a sound source, as input to the play function. You can generate your own, like in examples/
waveforms.py.
Note: You don’t need to understand this section to use the audio module. It is just here in case you wanted to know
how it works.
The audio module can consumes an iterable (sequence, like list or tuple, or generator) of AudioFrame instances,
each 32 samples at 7812.5 Hz, and uses linear interpolation to output a PWM signal at 32.5 kHz, which gives tolerable
sound quality.
The function play fully copies all data from each AudioFrame before it calls next() for the next frame, so a
sound source can use the same AudioFrame repeatedly.
The audio module has an internal 64 sample buffer from which it reads samples. When reading reaches the start or
the mid-point of the buffer, it triggers a callback to fetch the next AudioFrame which is then copied into the buffer.
This means that a sound source has under 4ms to compute the next AudioFrame, and for reliable operation needs to
take less 2ms (which is 32000 cycles, so should be plenty).
4.5 Example
frame = audio.AudioFrame()
74 Chapter 4. Audio
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
triangle = audio.AudioFrame()
QUARTER = len(triangle)//4
for i in range(QUARTER):
triangle[i] = i*15
triangle[i+QUARTER] = 248-i*15
triangle[i+QUARTER*2] = 128-i*15
triangle[i+QUARTER*3] = i*15+8
show_wave("Triangle", triangle)
square = audio.AudioFrame()
HALF = len(square)//2
for i in range(HALF):
square[i] = 8
square[i+HALF] = 248
show_wave("Square", square)
sleep(1000)
for i in range(len(frame)):
frame[i] = 252-i*8
show_wave("Sawtooth", frame)
del frame
#Generate a waveform that goes from triangle to square wave, reasonably smoothly.
frames = [ None ] * 32
for i in range(32):
frames[i] = frame = audio.AudioFrame()
for j in range(len(triangle)):
frame[j] = (triangle[j]*(32-i) + square[j]*i)>>5
4.5. Example 75
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
76 Chapter 4. Audio
CHAPTER 5
Bluetooth
While the BBC micro:bit has hardware capable of allowing the device to work as a Bluetooth Low Energy (BLE)
device, it only has 16k of RAM. The BLE stack alone takes up 12k RAM which means there’s not enough memory
for MicroPython to support Bluetooth.
Note: MicroPython uses the radio hardware with the radio module. This allows users to create simple yet effective
wireless networks of micro:bit devices.
Furthermore, the protocol used in the radio module is a lot simpler than BLE, making it far easier to use in an
educational context.
77
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
78 Chapter 5. Bluetooth
CHAPTER 6
It is useful to store data in a persistent manner so that it remains intact between restarts of the device. On traditional
computers this is often achieved by a file system consisting of named files that hold raw data, and named directories
that contain files. Python supports the various operations needed to work with such file systems.
However, since the micro:bit is a limited device in terms of both hardware and storage capacity MicroPython pro-
vides a small subset of the functions needed to persist data on the device. Because of memory constraints there is
approximately 30k of storage available on the file system.
MicroPython on the micro:bit provides a flat file system; i.e. there is no notion of a directory hierarchy, the file system
is just a list of named files. Reading and writing a file is achieved via the standard Python open function and the
resulting file-like object (representing the file) of types TextIO or BytesIO. Operations for working with files on
the file system (for example, listing or deleting files) are contained within the os module.
If a file ends in the .py file extension then it can be imported. For example, a file named hello.py can be imported
like this: import hello.
An example session in the MicroPython REPL may look something like this:
79
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
open(filename, mode=’r’)
Returns a file object representing the file named in the argument filename. The mode defaults to 'r' which
means open for reading in text mode. The other common mode is 'w' for writing (overwriting the content of
the file if it already exists). Two other modes are available to be used in conjunction with the ones describes
above: 't' means text mode (for reading and writing strings) and 'b' means binary mode (for reading and
writing bytes). If these are not specified then 't' (text mode) is assumed. When in text mode the file object will
be an instance of TextIO. When in binary mode the file object will be an instance of BytesIO. For example,
use 'rb' to read binary data from a file.
class TextIO
class BytesIO
Instances of these classes represent files in the micro:bit’s flat file system. The TextIO class is used to represent
text files. The BytesIO class is used to represent binary files. They work in exactly the same except that TextIO
works with strings and BytesIO works with bytes.
You do not directly instantiate these classes. Rather, an appropriately configured instance of the class is returned
by the open function described above.
close()
Flush and close the file. This method has no effect if the file is already closed. Once the file is closed, any
operation on the file (e.g. reading or writing) will raise an exception.
name()
Returns the name of the file the object represents. This will be the same as the filename argument
passed into the call to the open function that instantiated the object.
read(size)
Read and return at most size characters as a single string or size bytes from the file. As a convenience,
if size is unspecified or -1, all the data contained in the file is returned. Fewer than size characters or
bytes may be returned if there are less than size characters or bytes remaining to be read from the file.
If 0 characters or bytes are returned, and size was not 0, this indicates end of file.
A MemoryError exception will occur if size is larger than the available RAM.
readinto(buf, n=-1)
Read characters or bytes into the buffer buf. If n is supplied, read n number of bytes or characters into
the buffer buf.
readline(size)
Read and return one line from the file. If size is specified, at most size characters will be read.
The line terminator is always '\n' for strings or b'\n' for bytes.
writable()
Return True if the file supports writing. If False, write() will raise OSError.
write(buf )
Write the string or bytes buf to the file and return the number of characters or bytes written.
Machine
The machine module contains specific functions related to the micro:bit hardware. Most functions in this module
allow to achieve direct and unrestricted access to and control of hardware blocks on a system (like CPU, timers, buses,
etc.). Used incorrectly, this can lead to malfunction, lockups, crashes of your board, and in extreme cases, hardware
damage.
7.1 Functions
machine.unique_id()
Returns a byte string with a unique identifier of a board. It will vary from one board instance to another.
machine.reset()
Resets the device in a manner similar to pushing the external RESET button.
machine.freq()
Returns CPU frequency in hertz.
machine.disable_irq()
Disable interrupt requests. Returns the previous IRQ state which should be considered an opaque value. This
return value should be passed to the machine.enable_irq() function to restore interrupts to their original
state, before machine.disable_irq() was called.
machine.enable_irq(state)
Re-enable interrupt requests. The state parameter should be the value that was returned from the most recent
call to the machine.disable_irq() function.
machine.time_pulse_us(pin, pulse_level, timeout_us=1000000)
Time a pulse on the given pin, and return the duration of the pulse in microseconds. The pulse_level argument
should be 0 to time a low pulse or 1 to time a high pulse.
If the current input value of the pin is different to pulse_level, the function first (*) waits until the pin input
becomes equal to pulse_level, then (**) times the duration that the pin is equal to pulse_level. If the pin is
already equal to pulse_level then timing starts straight away.
81
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
The function will return -2 if there was timeout waiting for condition marked (*) above, and -1 if there was
timeout during the main measurement, marked (**) above. The timeout is the same for both cases and given by
timeout_us (which is in microseconds).
The machine module allows you to read from the device’s memory, getting 1 byte (8 bits; mem8), 2 byte (16 bits;
mem16), or 4 byte (32 bits; mem32) words from physical addresses. For example: mem8[0x00] reads 1 byte on
physical address 0x00. This has a number of uses, for example if you’d like to read data from the nRF51 registers.
82 Chapter 7. Machine
CHAPTER 8
MicroPython
8.1 Functions
micropython.const(expr)
Used to declare that the expression is a constant so that the compiler can optimise it. The use of this function
should be as follows:
Constants declared this way are still accessible as global variables from outside the module they are declared
in. On the other hand, if a constant begins with an underscore then it is hidden, it is not available as a global
variable, and does not take up any memory during execution.
micropython.opt_level([level ])
If level is given then this function sets the optimisation level for subsequent compilation of scripts, and returns
None. Otherwise it returns the current optimisation level.
The optimisation level controls the following compilation features:
• Assertions: at level 0 assertion statements are enabled and compiled into the bytecode; at levels 1 and
higher assertions are not compiled.
• Built-in __debug__ variable: at level 0 this variable expands to True; at levels 1 and higher it expands
to False.
• Source-code line numbers: at levels 0, 1 and 2 source-code line number are stored along with the bytecode
so that exceptions can report the line number they occurred at; at levels 3 and higher line numbers are not
stored.
The default optimisation level is usually level 0.
83
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
micropython.mem_info([verbose ])
Print information about currently used memory. If the verbose argument is given then extra information is
printed.
micropython.qstr_info([verbose ])
Print information about currently interned strings. If the verbose argument is given then extra information is
printed.
This includes the number of interned strings and the amount of RAM they use. In verbose mode it prints out the
names of all RAM-interned strings.
micropython.stack_use()
Return an integer representing the current amount of stack that is being used. The absolute value of this is not
particularly useful, rather it should be used to compute differences in stack usage at different points.
micropython.heap_lock()
micropython.heap_unlock()
Lock or unlock the heap. When locked no memory allocation can occur and a MemoryError will be raised if
any heap allocation is attempted.
micropython.kbd_intr(chr)
Set the character that will raise a KeyboardInterrupt exception. By default this is set to 3 during script execution,
corresponding to Ctrl-C. Passing -1 to this function will disable capture of Ctrl-C, and passing 3 will restore it.
This function can be used to prevent the capturing of Ctrl-C on the incoming stream of characters that is usually
used for the REPL, in case that stream is used for other purposes
84 Chapter 8. MicroPython
CHAPTER 9
Music
This is the music module. You can use it to play simple tunes, provided that you connect a speaker to your board.
By default the music module expects the speaker to be connected via pin 0:
85
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
import music
NOTE[octave][:duration]
86 Chapter 9. Music
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
For example, A1:4 refers to the note “A” in octave 1 that lasts for four ticks (a tick is an arbitrary length of time
defined by a tempo setting function - see below). If the note name R is used then it is treated as a rest (silence).
Accidentals (flats and sharps) are denoted by the b (flat - a lower case b) and # (sharp - a hash symbol). For example,
Ab is A-flat and C# is C-sharp.
Note names are case-insensitive.
The octave and duration parameters are states that carry over to subsequent notes until re-specified. The default
states are octave = 4 (containing middle C) and duration = 4 (a crotchet, given the default tempo settings -
see below).
For example, if 4 ticks is a crotchet, the following list is crotchet, quaver, quaver, crotchet based arpeggio:
['r4:2', 'g', 'g', 'g', 'eb:8', 'r:2', 'f', 'f', 'f', 'd:8']
The definition and scope of an octave conforms to the table listed on this page about scientific pitch notation. For
example, middle “C” is 'c4' and concert “A” (440) is 'a4'. Octaves start on the note “C”.
9.2 Functions
music.set_tempo(ticks=4, bpm=120)
Sets the approximate tempo for playback.
A number of ticks (expressed as an integer) constitute a beat. Each beat is to be played at a certain frequency
per minute (expressed as the more familiar BPM - beats per minute - also as an integer).
Suggested default values allow the following useful behaviour:
• music.set_tempo() - reset the tempo to default of ticks = 4, bpm = 120
• music.set_tempo(ticks=8) - change the “definition” of a beat
• music.set_tempo(bpm=180) - just change the tempo
To work out the length of a tick in milliseconds is very simple arithmetic: 60000/bpm/
ticks_per_beat . For the default values that’s 60000/120/4 = 125 milliseconds or 1 beat
= 500 milliseconds.
music.get_tempo()
Gets the current tempo as a tuple of integers: (ticks, bpm).
music.play(music, pin=pin0, wait=True, loop=False)
Plays music containing the musical DSL defined above.
If music is a string it is expected to be a single note such as, 'c1:4'.
If music is specified as a list of notes (as defined in the section on the musical DSL, above) then they are played
one after the other to perform a melody.
In both cases, the duration and octave values are reset to their defaults before the music (whatever it may
be) is played.
An optional argument to specify the output pin can be used to override the default of microbit.pin0.
If wait is set to True, this function is blocking.
If loop is set to True, the tune repeats until stop is called (see below) or the blocking call is interrupted.
9.2. Functions 87
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
For the purposes of education and entertainment, the module contains several example tunes that are expressed as
Python lists. They can be used like this:
All the tunes are either out of copyright, composed by Nicholas H.Tollervey and released to the public domain or have
an unknown composer and are covered by a fair (educational) use provision.
They are:
• DADADADUM - the opening to Beethoven’s 5th Symphony in C minor.
• ENTERTAINER - the opening fragment of Scott Joplin’s Ragtime classic “The Entertainer”.
• PRELUDE - the opening of the first Prelude in C Major of J.S.Bach’s 48 Preludes and Fugues.
• ODE - the “Ode to Joy” theme from Beethoven’s 9th Symphony in D minor.
• NYAN - the Nyan Cat theme (http://www.nyan.cat/). The composer is unknown. This is fair use for educational
porpoises (as they say in New York).
• RINGTONE - something that sounds like a mobile phone ringtone. To be used to indicate an incoming message.
• FUNK - a funky bass line for secret agents and criminal masterminds.
• BLUES - a boogie-woogie 12-bar blues walking bass.
• BIRTHDAY - “Happy Birthday to You. . . ” for copyright status see: http://www.bbc.co.uk/news/
world-us-canada-34332853
• WEDDING - the bridal chorus from Wagner’s opera “Lohengrin”.
• FUNERAL - the “funeral march” otherwise known as Frédéric Chopin’s Piano Sonata No. 2 in B minor, Op. 35.
• PUNCHLINE - a fun fragment that signifies a joke has been made.
88 Chapter 9. Music
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
• PYTHON - John Philip Sousa’s march “Liberty Bell” aka, the theme for “Monty Python’s Flying Circus” (after
which the Python programming language is named).
• BADDY - silent movie era entrance of a baddy.
• CHASE - silent movie era chase scene.
• BA_DING - a short signal to indicate something has happened.
• WAWAWAWAA - a very sad trombone.
• JUMP_UP - for use in a game, indicating upward movement.
• JUMP_DOWN - for use in a game, indicating downward movement.
• POWER_UP - a fanfare to indicate an achievement unlocked.
• POWER_DOWN - a sad fanfare to indicate an achievement lost.
9.4 Example
"""
music.py
~~~~~~~~
# play Prelude in C.
notes = [
'c4:1', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4',
˓→'c5', 'e5',
'c4', 'd', 'a', 'd5', 'f5', 'a4', 'd5', 'f5', 'c4', 'd', 'a', 'd5', 'f5', 'a4',
˓→'d5', 'f5',
'b3', 'd4', 'g', 'd5', 'f5', 'g4', 'd5', 'f5', 'b3', 'd4', 'g', 'd5', 'f5', 'g4',
˓→'d5', 'f5',
'c4', 'e', 'g', 'c5', 'e5', 'g4', 'c5', 'e5', 'c4', 'e', 'g', 'c5', 'e5', 'g4',
˓→'c5', 'e5',
'c4', 'e', 'a', 'e5', 'a5', 'a4', 'e5', 'a5', 'c4', 'e', 'a', 'e5', 'a5', 'a4',
˓→'e5', 'a5',
'c4', 'd', 'f#', 'a', 'd5', 'f#4', 'a', 'd5', 'c4', 'd', 'f#', 'a', 'd5', 'f#4',
˓→'a', 'd5',
'b3', 'd4', 'g', 'd5', 'g5', 'g4', 'd5', 'g5', 'b3', 'd4', 'g', 'd5', 'g5', 'g4',
˓→'d5', 'g5',
'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'b3', 'c4', 'e', 'g', 'c5', 'e4', 'g
˓→', 'c5',
'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g', 'c5', 'a3', 'c4', 'e', 'g', 'c5', 'e4', 'g
˓→', 'c5',
'd3', 'a', 'd4', 'f#', 'c5', 'd4', 'f#', 'c5', 'd3', 'a', 'd4', 'f#', 'c5', 'd4',
˓→'f#', 'c5',
'g3', 'b', 'd4', 'g', 'b', 'd', 'g', 'b', 'g3', 'b3', 'd4', 'g', 'b', 'd', 'g', 'b
˓→'
music.play(notes)
9.4. Example 89
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
90 Chapter 9. Music
CHAPTER 10
NeoPixel
The neopixel module lets you use NeoPixel (WS2812) individually addressable RGB and RGBW LED strips with
the micro:bit. Note to use the neopixel module, you need to import it separately with:
import neopixel
Note: From our tests, the Microbit NeoPixel module can drive up to around 256 NeoPixels. Anything above that and
you may experience weird bugs and issues. The micro:bit can only supply 90mA to external devices, larger numbers
of NeoPixels require an external power supply with common ground.
NeoPixels are designed to work at 5V, but luckily they still function using the 3V supply of the BBC micro:bit. Please
note that the micro:bit edge connector should not be connected to anything supplying 5V.
NeoPixels are fun strips of multi-coloured programmable LEDs. This module contains everything to plug them into a
micro:bit and create funky displays, art and games such as the demo shown below.
Warning: Do not use the 3v connector on the Microbit to power any more than 8 Neopixels at a time.
If you wish to use more than 8 Neopixels, you must use a separate 3v-5v power supply for the Neopixel power pin.
91
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
10.1 Classes
clear()
Clear all the pixels.
show()
Show the pixels. Must be called for any updates to become visible.
10.2 Operations
Writing the colour doesn’t update the display (use show() for that).
print(np[0])
Interact with Neopixels as if they were a list of tuples. Each tuple represents the RGB (red, green and blue) / RGBW
(red, green,blue and white) mix of colours for a specific pixel. The RGBW values can range between 0 to 255.
For example, initialise a strip of 8 RGB neopixels on a strip connected to pin0 like this:
import neopixel
np = neopixel.NeoPixel(pin0, 8)
Set pixels by indexing them (like with a Python list). For instance, to set the first pixel to full brightness red, you
would use:
np[0] = (255, 0, 0)
Get the current colour value of a pixel by indexing it. For example, to print the first pixel’s RGB value use:
print(np[0])
Finally, to push the new colour data to your Neopixel strip, use the .show() function:
np.show()
If nothing is happening, it’s probably because you’ve forgotten this final step..!
Note: If you’re not seeing anything change on your Neopixel strip, make sure you have show() at least somewhere
otherwise your updates won’t be shown.
10.2. Operations 93
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
10.4 Example
"""
neopixel_random.py
"""
from microbit import *
import neopixel
from random import randint
while True:
#Iterate over each LED in the strip
# Assign the current LED a random red, green and blue value between 0 and 60
np[pixel_id] = (red, green, blue)
The os Module
MicroPython contains an os module based upon the os module in the Python standard library. It’s used for accessing
what would traditionally be termed as operating system dependent functionality. Since there is no operating system in
MicroPython the module provides functions relating to the management of the simple on-device persistent file system
and information about the current system.
To access this module you need to:
import os
11.1 Functions
os.listdir()
Returns a list of the names of all the files contained within the local persistent on-device file system.
os.remove(filename)
Removes (deletes) the file named in the argument filename. If the file does not exist an OSError exception
will occur.
os.size(filename)
Returns the size, in bytes, of the file named in the argument filename. If the file does not exist an OSError
exception will occur.
os.uname()
Returns information identifying the current operating system. The return value is an object with five attributes:
• sysname - operating system name
• nodename - name of machine on network (implementation-defined)
• release - operating system release
• version - operating system version
95
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Note: There is no underlying operating system in MicroPython. As a result the information returned by the uname
function is mostly useful for versioning details.
Radio
The radio module allows devices to work together via simple wireless networks.
The radio module is conceptually very simple:
• Broadcast messages are of a certain configurable length (up to 251 bytes).
• Messages received are read from a queue of configurable size (the larger the queue the more RAM is used). If
the queue is full, new messages are ignored. Reading a message removes it from the queue.
• Messages are broadcast and received on a preselected channel (numbered 0-83).
• Broadcasts are at a certain level of power - more power means more range.
• Messages are filtered by address (like a house number) and group (like a named recipient at the specified ad-
dress).
• The rate of throughput can be one of three pre-determined settings.
• Send and receive bytes to work with arbitrary data.
• Use receive_full to obtain full details about an incoming message: the data, receiving signal strength, and a
microsecond timestamp when the message arrived.
• As a convenience for children, it’s easy to send and receive messages as strings.
• The default configuration is both sensible and compatible with other platforms that target the BBC micro:bit.
To access this module you need to:
import radio
12.1 Constants
radio.RATE_1MBIT
Constant used to indicate a throughput of 1 Mbit a second.
97
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
radio.RATE_2MBIT
Constant used to indicate a throughput of 2 Mbit a second.
radio.RATE_250KBIT
Deprecated. This rate is possible with micro:bit V1, but it is not guaranteed to work on V2, so it has been
deprecated for compatibility reasons.
12.2 Functions
radio.on()
Turns the radio on.
Since MicroPython-on-micro:bit v1.1 the radio is turned on by default when the radio module is imported. In
earlier releases, to reduce power consumption until needed, this function had to be explicitly called. For those
cases radio.off() can be called after import.
radio.off()
Turns off the radio, thus saving power and memory.
radio.config(**kwargs)
Configures various keyword based settings relating to the radio. The available settings and their sensible default
values are listed below.
The length (default=32) defines the maximum length, in bytes, of a message sent via the radio. It can be up
to 251 bytes long (254 - 3 bytes for S0, LENGTH and S1 preamble).
The queue (default=3) specifies the number of messages that can be stored on the incoming message queue. If
there are no spaces left on the queue for incoming messages, then the incoming message is dropped.
The channel (default=7) can be an integer value from 0 to 83 (inclusive) that defines an arbitrary “channel”
to which the radio is tuned. Messages will be sent via this channel and only messages received via this channel
will be put onto the incoming message queue. Each step is 1MHz wide, based at 2400MHz.
The power (default=6) is an integer value from 0 to 7 (inclusive) to indicate the strength of signal used when
broadcasting a message. The higher the value the stronger the signal, but the more power is consumed by the
device. The numbering translates to positions in the following list of dBm (decibel milliwatt) values: -30, -20,
-16, -12, -8, -4, 0, 4.
The address (default=0x75626974) is an arbitrary name, expressed as a 32-bit address, that’s used to filter
incoming packets at the hardware level, keeping only those that match the address you set. The default used by
other micro:bit related platforms is the default setting used here.
The group (default=0) is an 8-bit value (0-255) used with the address when filtering messages. Conceptu-
ally, “address” is like a house/office address and “group” is like the person at that address to which you want to
send your message.
The data_rate (default=radio.RATE_1MBIT) indicates the speed at which data throughput takes place. Can
be one of the following contants defined in the radio module : RATE_1MBIT or RATE_2MBIT.
If config is not called then the defaults described above are assumed.
radio.reset()
Reset the settings to their default values (as listed in the documentation for the config function above).
Note: None of the following send or receive methods will work until the radio is turned on.
radio.send_bytes(message)
Sends a message containing bytes.
radio.receive_bytes()
Receive the next incoming message on the message queue. Returns None if there are no pending messages.
Messages are returned as bytes.
radio.receive_bytes_into(buffer)
Receive the next incoming message on the message queue. Copies the message into buffer, trimming the end
of the message if necessary. Returns None if there are no pending messages, otherwise it returns the length of
the message (which might be more than the length of the buffer).
radio.send(message)
Sends a message string. This is the equivalent of send_bytes(bytes(message, 'utf8')) but with
b'\x01\x00\x01' prepended to the front (to make it compatible with other platforms that target the mi-
cro:bit).
radio.receive()
Works in exactly the same way as receive_bytes but returns whatever was sent.
Currently, it’s equivalent to str(receive_bytes(), 'utf8') but with a check that the the first three
bytes are b'\x01\x00\x01' (to make it compatible with other platforms that may target the micro:bit). It
strips the prepended bytes before converting to a string.
A ValueError exception is raised if conversion to string fails.
radio.receive_full()
Returns a tuple containing three values representing the next incoming message on the message queue. If there
are no pending messages then None is returned.
The three values in the tuple represent:
• the next incoming message on the message queue as bytes.
• the RSSI (signal strength): a value between 0 (strongest) and -255 (weakest) as measured in dBm.
• a microsecond timestamp: the value returned by time.ticks_us() when the message was received.
For example:
details = radio.receive_full()
if details:
msg, rssi, timestamp = details
This function is useful for providing information needed for triangulation and/or triliteration with other micro:bit
devices.
12.3 Examples
# A micro:bit Firefly.
# By Nicholas H.Tollervey. Released to the public domain.
import radio
import random
from microbit import display, Image, button_a, sleep
# Create the "flash" animation frames. Can you work out how it's done?
flash = [Image().invert()*(i/9) for i in range(9, -1, -1)]
# Event loop.
while True:
# Button A sends a "flash" message.
(continues on next page)
12.3. Examples 99
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
This module is based upon the random module in the Python standard library. It contains functions for generating
random behaviour.
To access this module you need to:
import random
13.1 Functions
random.getrandbits(n)
Returns an integer with n random bits.
Warning: Because the underlying generator function returns at most 30 bits, n may only be a value between 1-30
(inclusive).
random.seed(n)
Initialize the random number generator with a known integer n. This will give you reproducibly deterministic
randomness from a given starting state (n).
random.randint(a, b)
Return a random integer N such that a <= N <= b. Alias for randrange(a, b+1).
random.randrange(stop)
Return a randomly selected integer between zero and up to (but not including) stop.
random.randrange(start, stop)
Return a randomly selected integer from range(start, stop).
random.randrange(start, stop, step)
Return a randomly selected element from range(start, stop, step).
101
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
random.choice(seq)
Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.
random.random()
Return the next random floating point number in the range [0.0, 1.0)
random.uniform(a, b)
Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b <
a.
Speech
This module makes microbit talk, sing and make other speech like sounds provided that you connect a speaker to your
board as shown below:
103
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
Note: This work is based upon the amazing reverse engineering efforts of Sebastian Macke based upon an old text-
to-speech (TTS) program called SAM (Software Automated Mouth) originally released in 1982 for the Commodore
64. The result is a small C library that we have adopted and adapted for the micro:bit. You can find out more from
his homepage. Much of the information in this document was gleaned from the original user’s manual which can be
found here.
The speech synthesiser can produce around 2.5 seconds worth of sound from up to 255 characters of textual input.
To access this module you need to:
import speech
14.1 Functions
speech.translate(words)
Given English words in the string words, return a string containing a best guess at the appropriate phonemes
to pronounce. The output is generated from this text to phoneme translation table.
This function should be used to generate a first approximation of phonemes that can be further hand-edited to
improve accuracy, inflection and emphasis.
speech.pronounce(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)
Pronounce the phonemes in the string phonemes. See below for details of how to use phonemes to finely
control the output of the speech synthesiser. Override the optional pitch, speed, mouth and throat settings to
change the timbre (quality) of the voice.
speech.say(words, *, pitch=64, speed=72, mouth=128, throat=128)
Say the English words in the string words. The result is semi-accurate for English. Override the optional pitch,
speed, mouth and throat settings to change the timbre (quality) of the voice. This is a short-hand equivalent of:
speech.pronounce(speech.translate(words))
speech.sing(phonemes, *, pitch=64, speed=72, mouth=128, throat=128)
Sing the phonemes contained in the string phonemes. Changing the pitch and duration of the note is described
below. Override the optional pitch, speed, mouth and throat settings to change the timbre (quality) of the voice.
14.2 Punctuation
Punctuation is used to alter the delivery of speech. The synthesiser understands four punctuation marks: hyphen,
comma, full-stop and question mark.
The hyphen (-) marks clause boundaries by inserting a short pause in the speech.
The comma (,) marks phrase boundaries and inserts a pause of approximately double that of the hyphen.
The full-stop (.) and question mark (?) end sentences.
The full-stop inserts a pause and causes the pitch to fall.
The question mark also inserts a pause but causes the pitch to rise. This works well with yes/no questions such as,
“are we home yet?” rather than more complex questions such as “why are we going home?”. In the latter case, use a
full-stop.
14.3 Timbre
The timbre of a sound is the quality of the sound. It’s the difference between the voice of a DALEK and the voice of a
human (for example). To control the timbre change the numeric settings of the pitch, speed, mouth and throat
arguments.
The pitch (how high or low the voice sounds) and speed (how quickly the speech is delivered) settings are rather
obvious and generally fall into the following categories:
Pitch:
• 0-20 impractical
• 20-30 very high
• 30-40 high
14.4 Phonemes
The say function makes it easy to produce speech - but often it’s not accurate. To make sure the speech synthesiser
pronounces things exactly how you’d like, you need to use phonemes: the smallest perceptually distinct units of sound
that can be used to distinguish different words. Essentially, they are the building-block sounds of speech.
The pronounce function takes a string containing a simplified and readable version of the International Phonetic
Alphabet and optional annotations to indicate inflection and emphasis.
The advantage of using phonemes is that you don’t have to know how to spell! Rather, you only have to know how to
say the word in order to spell it phonetically.
Note: The table contains the phoneme as characters, and an example word. The example words have the sound of the
phoneme (in parenthesis), but not necessarily the same letters.
Often overlooked: the symbol for the “H” sound is /H. A glottal stop is a forced stoppage of sound.
Here are some seldom used phoneme combinations (and suggested alternatives):
If you use anything other than the phonemes described above, a ValueError exception will be raised. Pass in the
phonemes as a string like this:
speech.pronounce("/HEHLOW") # "Hello"
The phonemes are classified into two broad groups: vowels and consonants.
Vowels are further subdivided into simple vowels and diphthongs. Simple vowels don’t change their sound as you say
them whereas diphthongs start with one sound and end with another. For example, when you say the word “oil” the
“oi” vowel starts with an “oh” sound but changes to an “ee” sound.
Consonants are also subdivided into two groups: voiced and unvoiced. Voiced consonants require the speaker to
use their vocal chords to produce the sound. For example, consonants like “L”, “N” and “Z” are voiced. Unvoiced
consonants are produced by rushing air, such as “P”, “T” and “SH”.
Once you get used to it, the phoneme system is easy. To begin with some spellings may seem tricky (for example,
“adventure” has a “CH” in it) but the rule is to write what you say, not what you spell. Experimentation is the best
way to resolve problematic words.
It’s also important that speech sounds natural and understandable. To help with improving the quality of spoken output
it’s often good to use the built-in stress system to add inflection or emphasis.
There are eight stress markers indicated by the numbers 1 - 8. Simply insert the required number after the vowel to
be stressed. For example, the lack of expression of “/HEHLOW” is much improved (and friendlier) when spelled out
“/HEH3LOW”.
It’s also possible to change the meaning of words through the way they are stressed. Consider the phrase “Why should
I walk to the store?”. It could be pronounced in several different ways:
Put simply, different stresses in the speech create a more expressive tone of voice.
They work by raising or lowering pitch and elongating the associated vowel sound depending on the number you give:
1. very emotional stress
2. very emphatic stress
3. rather strong stress
4. ordinary stress
5. tight stress
6. neutral (no pitch change) stress
7. pitch-dropping stress
8. extreme pitch-dropping stress
The smaller the number, the more extreme the emphasis will be. However, such stress markers will help pronounce
difficult words correctly. For example, if a syllable is not enunciated sufficiently, put in a neutral stress marker.
It’s also possible to elongate words with stress markers:
speech.pronounce("/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP.”)
14.5 Singing
Annotations work by pre-pending a hash (#) sign and the pitch number in front of the phoneme. The pitch will remain
the same until a new annotation is given. For example, make MicroPython sing a scale like this:
solfa = [
"#115DOWWWWWW", # Doh
"#103REYYYYYY", # Re
"#94MIYYYYYY", # Mi
"#88FAOAOAOAOR", # Fa
"#78SOHWWWWW", # Soh
"#70LAOAOAOAOR", # La
"#62TIYYYYYY", # Ti
"#58DOWWWWWW", # Doh
]
song = ''.join(solfa)
speech.sing(song, speed=100)
In order to sing a note for a certain duration extend the note by repeating vowel or voiced consonant phonemes (as
demonstrated in the example above). Beware diphthongs - to extend them you need to break them into their component
parts. For example, “OY” can be extended with “OHOHIYIYIY”.
Experimentation, listening carefully and adjusting is the only sure way to work out how many times to repeat a
phoneme so the note lasts for the desired duration.
14.7 Example
"""
speech.py
~~~~~~~~
Simple speech example to make the micro:bit say, pronounce and sing
something. This example requires a speaker/buzzer/headphones connected
to P0 and GND,or the latest micro:bit device with built-in speaker.
"""
import speech
from microbit import sleep
utime
The utime module provides functions for getting the current time and date, measuring time intervals, and for delays.
Note: The utime module is a MicroPython implementation of the standard Python time module. It can be imported
using both import utime and import time, but the module is the same.
15.1 Functions
utime.sleep(seconds)
Sleep for the given number of seconds. You can use a floating-point number to sleep for a fractional number of
seconds, or use the utime.sleep_ms() and utime.sleep_us() functions.
utime.sleep_ms(ms)
Delay for given number of milliseconds, should be positive or 0.
utime.sleep_us(us)
Delay for given number of microseconds, should be positive or 0.
utime.ticks_ms()
Returns an increasing millisecond counter with an arbitrary reference point, that wraps around after some value.
utime.ticks_us()
Just like utime.ticks_ms() above, but in microseconds.
utime.ticks_add(ticks, delta)
Offset ticks value by a given number, which can be either positive or negative. Given a ticks value, this function
allows to calculate ticks value delta ticks before or after it, following modular-arithmetic definition of tick values.
Example:
# Find out what ticks value there was 100ms ago
print(ticks_add(time.ticks_ms(), -100))
113
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
utime.ticks_diff(ticks1, ticks2)
Measure ticks difference between values returned from utime.ticks_ms() or ticks_us() functions, as
a signed value which may wrap around.
The argument order is the same as for subtraction operator, ticks_diff(ticks1, ticks2) has the same
meaning as ticks1 - ticks2.
utime.ticks_diff() is designed to accommodate various usage patterns, among them:
Polling with timeout. In this case, the order of events is known, and you will deal only with positive results of
utime.ticks_diff():
Scheduling events. In this case, utime.ticks_diff() result may be negative if an event is overdue:
16.1 Dependencies
• CMake
• Arm GCC
• git
• ninja
• python
• srecord
• yotta
The yotta tool is used to build MicroPython, but before that takes place additional files have to be generated by the
Makefile in preparation for the build, and additional data is added to the hex file after.
Clone the repository and change directory to it:
$ cd micropython
115
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
yotta up
make all
The resulting firmware.hex can be found in the build/ directory which can then be copied to the micro:bit.
The Makefile does some extra preprocessing of the source, which is needed only if you add new interned strings
to qstrdefsport.h. The Makefile also puts the resulting firmware at build/firmware.hex, and includes some
convenience targets.
Using tools/makecombinedhex.py you can combine the MicroPython firmware with a Python script and pro-
duce a hex file ready for uploading to the micro:bit.:
./hexlifyscript.py <script.py>
The micro:bit mounts itself as a USB mass storage device named MICROBIT. When it detects that a .hex file has been
copied to the USB drive, it will flash it, and start running the program.
REPL (Read-Evaluate-Print-Loop) allows the micro:bit to read and evaluate code in real-time as you write it.
The browser-based Python editor has built-in REPL support, that can be accessed using WebUSB. You can read more
about how WebUSB is used in the editors in this article on direct flashing from the browser in the micro:bit apps and
editors.
To use WebUSB, you will need a Google Chrome based browser and a micro:bit with firmware at version 0249 or
above.
To use the REPL:
1. Flash a Python program to the micro:bit, if you have not done so already.
2. Select Open Serial to open the REPL window.
3. Click the blue bar to Send CTRL-C for REPL or press CTRL + C on your keyboard to enter the REPL.
The Mu Editor has built-in support for REPL and even includes a real-time data plotter.
Some other common options are picocom and screen. You will need to install a program and read the appropriate
documentation to understand the basics of connecting to a device.
117
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
17.3.1 Windows
When you have installed the aforementioned drivers the micro:bit will appear in device-manager as a COM port.
17.3.2 macOS
Open Terminal and type ls /dev/cu.* to see a list of connected serial devices; one of them will look like /dev/
cu.usbmodem1422 (the exact number will depend on your computer).
17.3.3 Linux
In terminal, type dmesg | tail which will show which /dev node the micro:bit was assigned (e.g. /dev/
ttyUSB0).
Once you have found the port identifier you can use a serial terminal program to communicate with the micro:bit.
17.4.1 Windows
17.4.2 macOS
17.4.3 Linux
To connect to Debian based distributions, like Ubuntu, you might need to add yourself to the dialout group, which
grants write access to the serial device /dev/ttyACM0:
You may need to relogin in order for the changes to groups to take effect.
Using the screen program, type screen /dev/ttyUSB0 115200, replacing /dev/ttyUSB0 with the port
you found earlier.
To exit, press Ctrl-A then \ and answer Yes to the question. There are many ways back to a command prompt
including Ctrl-A then Ctrl-D, which will detach screen. All serial output from the micro:bit will still be received by
screen, the serial port will be locked, preventing other applications from accessing it. You can restart screen by
typing screen -r.
Using picocom, type picocom /dev/ttyACM0 -b 115200, again replacing /dev/ttyACM0 with the port
you found earlier.
To exit, press Ctrl-A then Ctrl-Q.
When MicroPython is built, the compiler produces an Intel Hex file containing the MicroPython firmware. Additional
data can then be added to this file to contain information about the MicroPython version, or the Python code to execute
on start-up.
The general memory layout used is:
• 0x00000000: Start of MicroPython firmware - up to 248 KBs
• 0x0003e000: Start of appended script (optional) - up to 8 Kbs
• 0x100010c0: UICR customer[16] register, start of MicroPython information - 28 bytes
Note: If you append any data or modify the Intel Hex file, please ensure the addresses of the data stored progress in
incremental order. If there is an address jump backwards DAPLink will fail to flash the file.
The User Information Configuration Registers (UICR) is a region of Non-Volatile Memory available to store user-
specific settings. The first 128 Bytes are reserved, but we can use the other 128 Bytes to store any arbitrary data.
MicroPython stores the following information, in little endian, starting from the UICR customer[16] register:
• 0x100010c0: 4-byte integer with magic value 0x17eeb07c
• 0x100010c4: 4-byte integer with value 0xffffffff
• 0x100010c8: 4-byte integer with value 0x0000000a (log base 2 of the flash page size, being 1024 bytes)
• 0x100010ca: 2-byte integer with value 0x0000 (start page of the firmware)
• 0x100010cc: 2-byte integer storing number of pages used by the firmware
• 0x100010d0: 4-byte integer with value 0xffffffff
• 0x100010d4: 4-byte integer with the address in the firmware of the version string
121
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
The yotta tool is used to build MicroPython, but before that takes place additional files have to be generated by the
Makefile in preparation for the build, and additional data is added to the hex file after.
Running the make all command executes the following steps:
• The tools/makeversionhdr.py script creates the microbitversion.h file with macros containing
build information
• Yotta builds the source and creates a bare hex file with just the firmware
• The tools/adduicr.py script adds the UICR to the bare hex
• The final hex file is placed in build/firmware.hex
• The user can optionally append a script using tools/makecombinedhex.py (or other tools)
User scripts are stored in the MicroPython filesystem and if a main.py script exists it is run when MicroPython
starts. Additional Python scripts can also be included and executed from the main.py file, or the REPL.
The Python Editor uses microbit-fs to create the filesystem and include it in the HEX file. The Python Editor must
add the filesystem to HEX files for MicroPython V1 & V2, and then combine both into a Universal HEX file to ensure
compatibility with both hardware variants.
This method of appending the script to the end of MicroPython is no longer used. Python files are now stored in the
filesystem and main.py is the program entry point.
MicroPython checks the first 2 bytes at address 0x0003e000 for a magic string to indicate if there is an appended
script. If the magic string is found, it will automatically execute the Python code stored there, unless there is a main.py
file stored in the MicroPython filesystem.
• 0x0003e000: 2 bytes “MP”
• 0x0003e002: 2 bytes, little endian integer for the length (in bytes) of the appended script (not counting this 4
byte header)
• 0x0003e004: Script stored as bytes, for MicroPython to decode using utf-8.
Contributing
19.1 Checklist
123
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
• genindex
• modindex
• search
a
audio, 73
m
machine, 81
microbit, 53
microbit.accelerometer, 62
microbit.compass, 66
microbit.display, 67
microbit.i2c, 69
microbit.spi, 70
microbit.uart, 70
micropython, 83
music, 85
n
neopixel, 91
o
os, 95
r
radio, 97
random, 101
s
speech, 103
u
utime, 113
125
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
127
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
128 Index
BBC micro:bit MicroPython Documentation, Release 1.1.0-beta.1
T
temperature() (in module microbit), 52
TextIO (built-in class), 80
ticks_add() (utime.utime method), 113
ticks_diff() (utime.utime method), 114
ticks_ms() (utime.utime method), 113
ticks_us() (utime.utime method), 113
time_pulse_us() (machine.machine method), 81
translate() (in module speech), 105
U
uname() (in module os), 95
uniform() (in module random), 102
unique_id() (machine.machine method), 81
utime (module), 113
W
was_gesture() (in module microbit.accelerometer),
63
was_pressed() (Button method), 52
width() (microbit.Image method), 59
writable() (BytesIO method), 80
write() (BytesIO method), 80
write() (in module microbit.i2c), 69
write() (microbit.spi.spi method), 70
write() (microbit.uart.uart method), 72
write_analog() (microbit.MicroBitDigitalPin
method), 57
write_digital() (microbit.MicroBitDigitalPin
method), 57
write_readinto() (microbit.spi.spi method), 70
Index 129