Welcome to the Microbit Course

The Internet of Things has dawned upon us, allowing different devices to connect and share information. This has led to a large rise in the use of embedded devices everywhere, from cars to door locks to traffic lights. In this course, we will use micro:bits to interact with the environment around us and connect devices together in order to create our own mini IoT.

Installation Instructions

Regular download instructions

Installation using pip for other systems

What are Microbits?

Microbits are tiny programmable computers that are very easy to setup and use properly. With many different types of sensors and possible outputs, microbits are very versatile and can be a great starting point for a hardware based group project!

Using LEDs

We will first start our journey with microbits through learning how to use the LEDs located on the microbits. If you look carefully, you can see that the 25 LEDs are arranged to form a 5x5 grid.

Let's meet the first function we will use to interact with the microbits: display.scroll()

Before we start typing what message we want to scroll across the LEDs, we need to first import the microbit libraries that we have installed.

from microbit import *
                    

Now, we can use the display.scroll() function in order to slowly scroll a message across the screen (remember to not delete the import line we added earlier):

from microbit import *

display.scroll('I <3 Hackonnect!')
                    

Try to scroll different messages across the screen! Of course, scrolling messages can be useful, but sometimes we want to display images on the screen. Because there are only 25 LEDs the types of images we are able to display are slightly limited.

First, let's look at how we can use prebuilt images given to us in the microbit library:

from microbit import *

display.show(Image.HEART)
sleep(2000)
display.show(Image.SILLY)
sleep(2000)
display.show(Image.RABBIT)
sleep(2000)
display.clear()
                    

There are three new functions we are using here, display.show(), display.clear() and sleep(). It's fairly obvious what these three functions do: one shows an image, one clears the image shown away from the LED screen and the last one puts the microbit to sleep for a certain amount of time. Do note that the number you put into sleep should be the time you want your microbit to sleep for in milliseconds. Try playing around with the prebuilt images; yu can find the entire list of prebuilt images here.

We can also make custom images to show on the 25 LEDs. As seen below, we will need to type out a 5x5 grid of numbers ourselves and save it in a variable. The numbers 0-9 indicates the brightness you want each LED to be at, with 9 being the brightest and 0 turning the LED off. Once we are done making the variable, we can use that variable as the argument of display.show() in order to show our custom image.

from microbit import *

square = Image('99999:'
  '95559:'
  '95059:'
  '95559:'
'99999')

# You can also write this as the following, as long as you use a colon to separate each row

square = Image('99999:95559:95059:95559:99999')
display.show(square)
sleep(2000)
display.clear()
                    

Displays do not have to be static either, we can have different animations that run on the microbit screens. To do this, simply use a list of images as the argument for display.show(). You can customise the delay between each image and indicate whether you want the animation to loop or not:

from microbit import *

large_square = Image('99999:90009:90009:90009:99999')
medium_square = Image('00000:09990:09090:09990:00000')
small_square = Image('00000:00000:00900:00000:00000')
square_list = [large_square, medium_square, small_square]
display.show(square_list, loop=False, delay=1000)
display.clear()
                    

Sometimes, you don't want to change the entire LED screen; you only want to manipulate the brightness of one pixel. Luckily, you are also able to do this through using the display.set_pixel(x_coordinate, y_coordinate, brightness) function. The coordinates are 0 indexed, with the top-left-hand corner being (0, 0) and the bottom-right-hand corner being (4, 4). You can also get the brightness of a particular LED through using display.get_pixel(x_coordinate, y_coordinate).

from microbit import *

display.set_pixel(0, 0, 7)
sleep(1000)
display.scroll(display.get_pixel(0, 0))                
                    
Microbit Buttons

To the left and to the right of the LEDs, there are two buttons you can see. They are called button_a and button_b respectively. You can use the is_pressed() function in order to see if a button is being pressed. Because of how if statements work, when you need to see if both buttons are pressed, that has to be the first if statement as shown below:

from microbit import *

while True:
  if button_a.is_pressed() and button_b.is_pressed():
    break
  elif button_a.is_pressed():
    display.show('A')
  elif button_b.is_pressed():
    display.show('B')
  else:
    display.show(Image.HAPPY)
display.show(Image.SAD)
sleep(2000)
display.clear()
                    

Another function that may come in handy is get_presses() that checks how many times the button was pressed while the microbit is asleep:

from microbit import *

display.scroll('START!')
sleep(5000)
presses = button_a.get_presses() + button_b.get_presses()
display.scroll(str(presses))
                    

You can also see if the button was pressed while the microbit is asleep using was_pressed()

from microbit import *

display.show('?')
sleep(1000)
if button_a.was_pressed():
  display.show(Image.HAPPY)
else:
  display.show(Image.SAD)
sleep(1000)
display.clear()
                    
Sensors on the Microbit

The microbit has various different sensors that we can use in our group projects. For example, we can get the surrounding temperature (in degrees Celsius) easily using the function temperature()

from microbit import *

display.scroll(str(temperature()))
                    

You can also see how long the microbit has been running in milliseconds using running_time()

from microbit import *

sleep(2000)
display.scroll(str(running_time()))
                    

As you can see, the running_time() is slightly higher than 2000 milliseconds. This is because when the microbit runs each function, it takes a bit of time to process the instruction and understand how it will react. The microbit also has an accelerometer built in, allowing you to measure the force in milligrams between -+2000. Use accelerometer.get_x(), .get_y() and .get_z() (on the 3 different directions). You can also use get_values() to get all three values as once as a tuple. After you flash the program into the microbit, click on the REPL button. You will be able to see the three accelerometer values get printed constantly as you tilt your microbit around.

from microbit import *

while not button_a.is_pressed() and not button_b.is_pressed():
  sleep(50)
  print(accelerometer.get_values())
                    

Your microbit is also to recognise different types of gestures such as tilting to the left and shaking the microbit from these values:

from microbit import *

while not button_a.is_pressed() and not button_b.is_pressed():
  sleep(100)
  print(accelerometer.current_gesture())
                    

The available gestures are: up, down, left, right, face up, face down, free fall, 3g, 6g, 8g and shake. You can also use accelerometer.is_gesture(gesture_name), accelerometer.was_gesture(gesture_name) and accelerometer.get_gestures(), similar to what we did earlier with the buttons. Microbits can also act as a compass, measuring the magnetic field strength on the x, y and z axis. We can test this in a similar way to how we tested the accelerometer.

from microbit import *

while not button_a.is_pressed() and not button_b.is_pressed():
  sleep(50)
  print(str(compass.get_x()) + ' ' + str(compass.get_y()) + ' ' + str(compass.get_z()))
  print(str(compass.get_field_strength())
                    

To use these values as a compass however, we need to calibrate the compass first. Follow the instructions displayed on the microbit in order to calibrate the compass. Use compass.heading() to get the heading of the compass after you calibrate it. The program below gives you an example of how the compass could be used. The screen is refreshed every 100ms, or 0.1s. Through converting the angle (compass.heading()) to a specific clock hour, we can represent the directions through different clocks. Try it out yourself and see how it works.

from microbit import *

compass.calibrate()
display.scroll('DONE!')
while not button_a.is_pressed() and not button_b.is_pressed():
  sleep(100)
  clock = ((15 - compass.heading()) // 30) % 12
  display.show(Image.ALL_CLOCKS[clock])
display.clear()
                    
Connecting Microbits using Radio

Microbits don't need to act as separate entities. In fact, you can have different microbits communicating with each other using radio. Before we are able to use the radio function of microbits, we need to import and additional radio library:

from microbit import *
import radio
                    

First of all, the radio must be turned on in order for the microbit to send and receive any messages.

from microbit import *
import radio

radio.on()
                    

As you might have guessed, you can also turn the radio off using radio.off(). There are many different ways you can configure the radio using radio.config(). The default settings are shown below:

radio.config(length=32, queue=3, channel=7, power=6, address=0x75626974, group=0, data_rate=radio.RATE_M1MBIT)

When setting up your radio, you really don't need to include everything in there. For more information about what each of these settings mean, you can visit this link. YOu can always reset the settings using radio.reset(). The most common setting you will be changing is the channel of the radio. Like different frequencies on AM and FM radios, using different radio channels helps the microbit to know which channel they should be listening into for instructions.

from microbit import *
import radio

radio.on()
radio.config(channel=68)
radio.reset()
radio.off()
                    

Radios are actually very easy to use. But remember, each message is broadcasted to every other microbit out there using the same channel. It's a good idea to use a unique channel for you microbits. To send messages, simply use radio.send(). To receive messages, simply use radio.receive(). Test this program out with a partner, changing the channel your radio is using so that you are not interfering with any other groups' radio messages. Can you figure out what this program does?

radio.config(channel=7)

while True:
  sleep(50)

  if button_a.was_pressed():
    display.show(Image.HAPPY)
    radio.send('A')
  elif button_b.was_pressed():
    display.show(Image.SAD)
    radio.send('B')

  message = radio.receive()

  if message == 'A':
    display.show(Image.HAPPY)

  if message == 'B':
    display.show(Image.SAD)
                    
Making Sound

Another cool thing the microbit is able to do is to produce a variety of different sounds. However, this requires the microbit to be connected to a speaker or earphone (or any other audio output device). Using crocodile clips, connect the 0 and 1 numbers shown on the gold strip on the bottom of your microbit to an audio output device like the speaker we have provided you with or your personal earphones.

First of all, we need to import the libraries again:

from microbit import *
import speech
                    

We can use speech.say() in order to make the microbit say things:

from microbit import *
import speech

speech.say('Hackonnect is the best.')
sleep(1000)
speech.say('I agree.')
sleep(1000)
                    

Of course, in order to make sounds that cannot be described by words, we need another method. For this, we can use phenomes with the pronounce() function. Phenomes are the different components that make up a sound. You can translate regular English into phenomes using the translate() function. You can also make the microbit sing by adding the pitch in front of your phenome using the sing() function as seen below. Unless you have a solid grasp on how phenomes work, we strongly recommend against using this in your group projects. It is still very fun and stupid to make weird noises with this however:

from microbit import *
import speech

speech.pronounce('/HEH5EH4EH3EH2EH2EH3EH4EH5EHLP')
# You can also use translate in order to translate English into Phenomes
speech.pronounce(translate('Aww, I\'m so sorry!'))
sleep(1000)
# We can also use different pitches with sing.
sing('#115DOWWWW')
                    

There are much easier ways to play music on the microbit. This requires us to import another library:

from microbit import *
import music
                    

Here's how the music.play() functions recognises which musical note a string represents: NOTE + OCTAVE : DURATION. For example, "a4:2" means that the note A is played on the 4th octave for 2 ticks.

from microbit import *
import music

music.play('a4:2')
sleep(1000)
                    

You can set the tempo of your music using music.set_tempo():

music.set_tempo(ticks = 4, bpm = 120)

When you are constructing your musical masterpiece, you can insert a list of musical notes as the argument to music.play() in order to play multiple notes is succession. Can you figure out what this code plays?

from microbit import *
import music

music.play(['e3:2', 'd3:2', 'c3:2', 'd3:2', 'e3:2', 'e3:2', 'e3:4', 'd3:2', 'd3:2', 'd3:4', 'e3:2', 'e3:2', 'e3:4', 'e3:2', 'd3:2', 'c3:2', 'd3:2', 'e3:2', 'e3:2', 'e3:2', 'e3:2', 'd3:2', 'd3:2', 'e3:2', 'd3:2', 'c3:4'])
sleep(1000)
# Stop all music that is playing
stop()
                    

Spend some time playing around with the speech and music modules. Please be aware that these are still in alpha and can be very unstable.

Exercise 1

Using the knowledge we have learnt so far, try to create a device that can show the current temperature or act as a compass depending on which button you press on the microbit. Copy the following code and insert your code after "#Add your code here":

from microbit import *

# Using the knowledge we have learnt so far, try to create a device that can
# show the current temperature or act as a compass depending on which button
# you press on the microbit.

compass.calibrate()
while True:
  sleep(50)
  # Add your code here
display.clear()
                    

As an extension task instead of using buttons, allow the user to use gestures to determine whether they want to see the current temperature or use the microbit as a compass.