Welcome to Part 1 of the MicroPython series! We'll teach you the basics of MicroPython on the micro:bit, and show you how to make some cool electronic gadgets while you're at it!
CODE TYPE: MICROPYTHON
SKILL LEVEL: BEGINNER
If you haven’t heard of a micro:bit, it’s a small handheld microcontroller created by the BBC for learning programming and electronics. It’s commonly used in educational environments all over the world to introduce STEM (Science, Technology, Engineering & Mathematics) to primary and secondary schools. It’s great for beginners because it can be programmed with a variety of block-based programming platforms like Scratch and Microsoft MakeCode. In this project, we’ll actually be using MicroPython – a compact version of Python that allows newbie programmers to get their hands on text-based programming in an easy-to-use environment.
Don’t be fooled into thinking this is a basic board though – if you’re looking for a challenge, the micro:bit can interface with all sorts of electronics much like an Arduino. We’ll get into that in Part 2! So, if you’re flicking through DIYODE looking for a place to kickstart your programming or electronics journey, this is it! Let’s get into it!
GETTING STARTED
First, we’ll need to get ourselves a micro:bit! Jaycar, Altronics, Core Electronics and many other electronic retailers in Australia sell the micro:bit kit, which also includes a handy battery pack for making your micro:bit fully portable.
We’ve included some places you can purchase the kit.
Shopping List:
The BBC micro:bit Go Starter Pack is available from the following retailers:
SETUP
We’ll first install the Mu code editor, which is a downloadable IDE (Integrated Development Environment) that’s beginner friendly and ready to work with micro:bit right out of the box. Head to https://codewith.mu and download it!
Once it’s installed, you may need to select “BBC micro:bit” from the Select Mode screen. Then, simply plug in your micro:bit to a USB port with a micro-USB cable. We’re all set, so let’s get started!
YOUR FIRST PROGRAM
Let’s write some code! Why not start by displaying an image on the micro:bit? To begin, you’ll need to type this line of code at the top of your Python file to ensure that MicroPython imports the Python code responsible for controlling the micro:bit:
from microbit import *
Note that Micropython (like regular Python) runs all code in a file from top-to-bottom, so ensure to put all your code below the module imports (the line we just wrote), otherwise the micro:bit won’t understand the code we are trying to run. Now we write the code we want our micro:bit to run!
display.show(Image.ASLEEP)
sleep(5000)
display.show(Image.SMILE)
Let’s break it down. Our first line of code uses a function called “display.show()” which allows us to provide an image and have the micro:bit set the 5x5 red LEDs on its underside to the image we provided. Here’s a quick – but incomplete – list of pre-defined images we can display:
We picked the “ASLEEP” image so we could depict the micro:bit waking up with a cute animation! In our code, we then wait for five seconds with the “sleep()” command. Notice that we are using units of milliseconds, so five seconds = 5000ms. Using milliseconds is done in a number of programming languages to allow for finer control when dealing with actions that need to be ran at very specific times. After we’ve waited five seconds, we display the “HAPPY” image.
Our program is all done! Let’s upload and test it on the micro:bit! Save the .py (Python) file on your computer, and then press the Flash button within the Mu editor. Depending on the size of your program, this may take some time.
You’ll see the yellow light blinking on your micro:bit to let you know it’s uploading. Voila! The micro:bit should immediately run our program. Now, why not have a play around and change the program? Try changing the images it shows or adding another image to the sequence!
RESPONDING TO THE USER
Okay, displaying images is cool and all, but what else can we do? The micro:bit has two pushbuttons either side of the LED display that we can use in our code! Let’s make a simple program that points an arrow on the LED display to the last button we pressed.
from microbit import *
while True:
if button_a.was_pressed():
display.show(Image.ARROW_W)
if button_b.was_pressed():
display.show(Image.ARROW_E)
If you don’t have a lot of experience with code, the “while True:” line at the top of our code might seem a little odd. A “while” loop in Python repeats until the condition after it isn’t met – that is, it isn’t true. Since our condition is a constant value of True, there is no way the loop can end and thus it repeats indefinitely!
This is handy for us because we need to continually check if a button is pressed – not just once. In our program, it’s important that the code in our while loop is indented (pressing Tab on your keyboard) because MicroPython needs to understand what code is in it and what isn’t! In our while loop, we have two “if” statements that allow us to run code if a condition is met.
For example, let’s take a look at the first “if” statement. We are calling the function “button_a.was_pressed()” which returns True or False depending on whether the button was pressed by the user since we last ran this function. So, if we have pressed the button, it returns True and we run the code which is indented in the “If” statement. In this case, we are displaying an arrow pointing West (to the left). The code is exactly the same for the right button (Button B), except we use button_b instead of button_a and ARROW_E instead of ARROW_W. Once again, hit “Upload” at the top of the Mu editor to get it running on your micro:bit.
Once it’s running, see if you can spot some potential improvements that you could make to the program. How about only displaying the arrow for a second or two before clearing the display, instead of leaving each arrow on the display indefinitely? Or, why not mimic a car dashboard with flashing indicator lights? Make the arrows blink on and off when a button is pressed!
Troubleshooting:
Can’t get your code to work? We know, it’s frustrating! Fear not, we have a quick troubleshooting guide if your micro:bit isn’t cooperating!
- Your code may have an error! If the code successfully uploads but the micro:bit displays a long error message beginning with “Line”, check your code. You may have left a rogue bracket or misspelt a command. You can view the entire error message by clicking on “REPL” at the top of the Mu editor.
- If your “Flash” button in Mu is greyed out and can’t be clicked on, make sure that you don’t have the REPL or Plotter window open by accident – just click on their buttons at the top of the Mu editor to close them.
- Make sure your micro:bit is plugged in and is recognised. Try plugging in the micro:bit to your computer again and checking whether Windows (or whatever operating system you’re using) picks it up. If not, try to use a different micro-USB cable or a different USB port.
- Finally, give the micro:bit a reset by pressing the small button next to its power port. This will restart the micro:bit and will let it have another go at running your program.
Build 1: Morse Code Generator
A micro:bit isn’t just great for introducing coding to beginners, it’s also awesome for getting into electronics! In this section, we’ll show you how to make a simple Morse Code generator with an electronic buzzer circuit! Your micro:bit has a number of gold pins on the board, which can be used to interface with electronic components (Similar to an Arduino). In our guide, we’ll only be using the large pins with rings above them for sake of simplicity.
Parts Required: | Jaycar | ||
---|---|---|---|
micro:bit Go Starter Pack | XC4320 | ||
Small Alligator Clips | WC6010 | ||
Passive Piezo Buzzer | - |
You could also buy an Edge Connector for the micro:bit which expands out the pins on the bottom of the board and allows you to use them with more circuits and other components. We’ll talk about why this might be useful later in this guide!
The micro:bit has five large gold pins, two of which are power pins – 3V and GND. 3V always provides a 3V (+) power line while GND is the ground (-) connection for your circuits. Never connect these directly to each other – this is what’s known as a short-circuit! It could cause all sorts of damage to your micro:bit from the high current flow.
The other three pins (0, 1 and 2) are GPIO (General Purpose Input/Output) pins that can be controlled with code either to output a voltage or read the voltage on that pin. Very handy! When in output mode, we can set a pin to either be “HIGH” (3V) or “LOW” (0V). This is a digital output as we can set a pin to one of two states. In Input mode, we can read the voltage of an external component connected to a pin and use that reading in our code. With our buzzer program, we will be rapidly turning on and off the digital pin 0 on the micro:bit to create an audible tone!
Alright, enough small talk – let’s get to it! You’ll need the following components: Hooking up the buzzer is straightforward! Using an alligator clip, connect the golden pin ‘0’ on the micro:bit to the positive lead of the buzzer. The positive lead is most commonly the longer lead or the side marked with a plus.
Then, using an alligator clip, connect the negative side of the buzzer to the ‘GND’ golden pin on the micro:bit. Awesome, now let’s write some code to turn our micro:bit into a Morse code generator using the buzzer we connected!
from microbit import *
import music
#The length (in ms) of a dot
dot_length = 100
while True:
#Sending a dot
if button_a.was_pressed():
music.pitch(440,dot_length)
#Sending a dash
if button_b.was_pressed():
music.pitch(440,dot_length * 3)
#Leave a space for the next character
sleep(dot_length)
What’s all this? Dot length?!? Music.pitch!? - Don’t worry, we’ll walk you through it! First off, let’s talk a little bit about Morse code. Morse code uses specific arrangements of short and long pulses (typically referred to as “dots” and “dashes” respectively) to signify a specific letter in the English alphabet. The actual duration of the dots and dashes aren’t so important as the ratio between their durations. A dash should – ideally – be three times the length of a dot!
We say “ideally” because a human manually transmitting Morse code will never get the timing absolutely perfect. But never fear, our micro:bit is here! We can precisely control the duration of our buzzer pulses using the music.pitch() function. In our code, notice we have defined a variable called dot_length. That’s the number of milliseconds we allow each “dot” (short pulse) to be. You can change this variable to configure how fast our code transmission should be!
Passive vs. Active
When sourcing your buzzer for this project, make sure it is a “passive” and not an “active” buzzer. A “passive” buzzer requires a quickly changing voltage wave to make sounds with it, while an “active” buzzer only requires a steady voltage (3V) to make a sound. We’re using a passive buzzer because we can use code on the micro:bit to make our own sounds with our own pitches. To tell what type a buzzer is, look underneath it. A passive buzzer will typically have its green circuit board exposed, while an active buzzer will be sealed with black resin.
When we press button A, we tell the micro:bit to generate a 440Hz tone using the music library – make sure you import the library. We’ve used 440Hz, which represents the pitch of the buzzer tone – the note A above middle C in a music terms. The micro:bit then waits for the time specified for dot_length – in our case, 100 milliseconds (a tenth of a second) - and turns off the buzzer again. Voila – we just payed a “dot” in Morse code!
The same effect happens when we press Button B, however, we turn on the buzzer for three times the length of our “dot” - this results in a “dash”! Because we referenced our dot_length variable again, it doesn’t matter what it is, because our dash will always be three times as long. For each loop of our while loop, we also make sure to wait the length of a dot. This will make sure that if we did send any type of signal, we wait a dot length before we can send another one – as Morse code specifies.
If you want to expand on this activity, mess around with the pitch! Put different numbers into the “pitch” argument and see how it affects the tone! Why not try and make a song with different pitches when a button is pressed?
Build 2: Automatic Temperature Meter
Parts Required: | Jaycar | ||
---|---|---|---|
micro:bit Go Starter Pack | XC4320 | ||
Small Alligator Clips | WC6010 | ||
Male-to-Male Dupont Wires | WC6027 | ||
9 x 47Ω or 50Ω resistors* | RR0540 | ||
3 x 5mm Green LEDs* | ZD0170 | ||
3 x 5mm Yellow or Orange LEDs* | ZD0169 | ||
3 x 5mm Red LEDs* | ZD1785 | ||
Solderless Breadboard | PB8815 |
* Quantity required, may be sold in packs.
The micro:bit has a plethora of onboard sensors, so let’s put one of them to use! Here in Australia, the weather is not always the friendliest of forces so it’s useful to know if the temperature outside is safe. We’re going to design a basic temperature meter that automatically displays what degree of sweltering the environment temperature is!
If the temperature is 25°C or below, we’ll illuminate a bank of green LEDs. If it’s anywhere from 25°C to 30°C, we’ll turn on the yellow LEDs – it’s starting to get hot! If it’s anything above that, we’ll illuminate the red LEDs – you don’t want to be outside too long in that heat.
First, let’s design the circuit we’ll use for our temperature display. We’re going to use three LEDs for each temperature level, and so we’ll end up with nine LEDs total. LEDs are a great, handy way to add a bright source to a project, but it’s important to run them properly. If we connect the LEDs directly to a power source, the LEDs might draw too much current and burn out. So, we need to add appropriate resistors to reduce the current flow.
It’s important that we add a resistor to every LED we add to the circuit to prevent one LED from eating up more current than it’s supposed to! Each of these LEDs will run best at 20mA (milliamps), so we need to choose an appropriate resistor value that will limit the current to this amount. We won’t go into the details of how to choose an appropriate resistor, but for the purposes of this guide, we’re going to use resistors of (or close to) 50Ω (Ω = Ohms). 47Ω Resistors are very common, so we’re going to use them!
Inserting LEDs
We’ll first add the LEDs to our breadboard to create our display. We spaced each bank of LEDs apart and ensured that all LEDs we inserted face the same way. You can do this by making sure that the flat side of the LEDs faces to the right.
CONNECTING LED ANODES
The positive side of the LEDs (“anodes”) need to be connected to all LEDs of the same colour. We used solid-core jumper wire to do this, but feel free to use regular Dupont wires and push them in to connect all of the LEDs together.
ADDING RESISTORS
We’re now going to add a 47Ω resistor in series with every LED on our board. It’s alright if you can’t get resistors that are exactly 47Ω, anything from 40Ω to 60Ω ohms should do the trick. Our 47Ω resistors have the colour bands Yellow, Purple, Black, Gold and Brown (see the images here).
If you’re alright with having dimmer LEDs, feel free to go up to 150Ω! Whatever resistors you are using, connect the right side of each LED to the blue negative line of the breadboard with it. Resistors aren’t polarised so don’t worry about the direction you insert them.
CONNECTING THE LEDS
It’s now time to connect the LEDs to the micro:bit! We need to connect the positive lead of each LED in every bank of colours together. This means that if we power one LED, every LED the same colour will illuminate at the same time. Using Dupont or jumper wires, connect the longer lead of the LEDs together. Then, add one end of a Dupont wire to each LED colour and to the blue negative rail on the breadboard. You should have four wires coming off the breadboard, all of which need to be connected to the micro:bit, as follows:
Use alligator clips to connect the Dupont wires to the Arduino on its golden pins. If you get stuck hooking up the circuit, we’ve provided the circuit schematic and the breadboard layout to refer to.
WRITING THE CODE
Alright, our display is all hooked up and ready to roll! Let’s get some code onto our micro:bit. Here’s the code we wrote for the temperature display, which you can download from our website to save you having to retype it:
from microbit import *
def illuminateLight(illuminate_index):
lights = [pin0, pin1, pin2]
for index, light in enumerate(lights):
if index == illuminate_index:
light.write_digital(1)
else:
light.write_digital(0)
while True:
temp = temperature()
if temp < 25:
illuminateLight(0)
elif temp < 30:
illuminateLight(1)
else:
illuminateLight(2)
sleep(100)
Let’s check out the code. We’ll come back to the first couple lines of code in a second, but for now, let’s discuss the While loop we’ve written. The micro:bit has an inbuilt function called “temperature()” that returns the current temperature of the micro:bit in degrees Celsius (°C). After we’ve received the temperature, we assign it to our “temp” variable and begin checking what temperature we have reached. If it’s below 25 degrees, we illuminate our green bank of LEDs. If not, we check if the temperature is 30 degrees or below and, if so, illuminate our yellow bank of LEDs. Otherwise, we illuminate our red LEDs. We’ve written the code checking the temperature like this to ensure that all values are handled correctly – no matter how cold or hot it is, the meter will still work correctly! After we’ve illuminated the LEDs according to the current temperature, we wait for a tenth of a second (100 milliseconds) before doing it again.
If you’re wondering why we’re using the numbers 0, 1 and 2 instead of something like “green”, “yellow” and “red”, these numbers are used in the function at the top of the file. In Python, it’s possible to define “functions” that run specific pieces of code whenever the function is called. We wrote a function called “illuminateLight” that also defines a parameter called “illuminate_index”. A parameter is an additional piece (or pieces) of information that can be provided to a function. Our “illuminate_index” could be one of the numbers we talked about – 0, 1 or 2!
So, what does our function do? Unsurprisingly enough, given an index, it will illuminate one bank of LEDs on our temperature display.
The reason why we’ve written a function for it is that we must also turn off all the other LEDs when we light one colour up! This is harder than it sounds.
At the beginning of our function, we create a List containing the three digital pins on the micro:bit – the 0, 1 and 2 golden pins we connected to the micro:bit. After that, we start a loop, iterating (or “enumerating”) over this list. If this pin has the same index as our “illuminate_index”, we light up that bank of LEDs by writing 1 to it. If not, we turn it off by writing 0 to it. What this means practically is that the bank of LEDs with the index we passed to the function is lit up (by supplying them with 3 Volts), while all others are turned off.
TESTING
After uploading the code to our micro:bit, you should find that the temperature meter works great! We connected our micro:bit to a phone powerbank and put it in the fridge for about a minute. Sure enough, the green LEDs illuminated to say that the temperature was below 25°C. To test the red LEDs, we put the micro:bit outside - which was a particularly unpleasant 33°C at the time of writing! Sure enough, after about 30 seconds, the red LEDs illuminated to let us know that it was sweltering outside!
WHERE TO FROM HERE?
Our temperature display might be cute, but it isn’t exactly the most accurate thing in the world! We only have three banks of LEDs that can be lit to display three different values. To add more, you could buy an Edge connector for the micro:bit that can “break out” the smaller golden pins for use with a breadboard or circuits. This expands your controllable pins from 3 to a whopping 19! You could hook each pin to one LED which will create a much smoother display. For example, by using ten LEDs, you could display the range of temperatures between 20°C and 30°C!
You’re no doubt busting to make more awesome micro:bit inventions, so we aren’t stopping here! Next month, we’re going to get into some more advanced uses with micro:bit including interfacing with electronics and programming the Bit:Bot to patrol your work area!