micro:bit v1 with yotta – removing build warnings


Running yotta build with the micro:bit v1 C tools produces screenfulls of depreceation warnings, such as:

warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated]

This makes it hard to find the error messages with the reason why the build failed.


Tell the C++ compiler not to include depreceation warnings.


Add the compiler flag -Wno-deprecated to the CMAKE_CXX_FLAGS_INIT options in the file toolchain.cmake.

File location:


Line before:


Line after adding flag:

set(CMAKE_CXX_FLAGS_INIT           "${CMAKE_CXX_FLAGS_INIT} ${_CPU_COMPILATION_OPTIONS} -std=c++11 -fwrapv -Wno-deprecated")

extra flags to suppress other distracting warning

While we're on a roll, we can also suppress distracting warnings for array-bounds and misleading indentation by adding:

-Wno-array-bounds -Wno-misleading-indentation

to the same line.


There are layers of build tools used to transform your C code into a hex file that can be copied onto the micro:bit. I tried to understand and explain the toolchain in these blogs:



Getting started with C++ on the micro:bit v2 in Linux


This post is about getting started with programming the micro:bit v2 using C++. I use the example code from the Lancaster University GitHub for this.

We will:

  • Download the GitHub repository with the sample code.
  • Build and load the default HelloWorld example to the micro:bit, which scrolls 'HELLO WORLD!' on the LEDs.
  • Modify and build one of the other examples to use one of the micro:bit pins as an analog input. The LEDs display the voltage on this pin.

I tried to load one of the MICROBIT.hex files onto a v1 of the micro:bit with no success. This post is aimed at v2 of the micro:bit only.

Download the samples

Download the GitHub repository with the sample files produced by Lancaster University from their GitHub site here.

There are a couple of ways to do this. You can click on the green 'Code' button to download a zip file and unzip it, or you can use the 'git clone' command if you have git installed:
git clone https://github.com/lancaster-university/microbit-v2-samples

Setting up for coding

The README.md file in the repository is pretty good. There are several packages that need to be installed on your Linux installation to be able to build the example code with. The maintainers of the repository use Ubuntu, so the package installation commands use the 'apt' package manager:

sudo apt install gcc
sudo apt install git
sudo apt install cmake
sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi

gcc is the Gnu C compiler. This is used to compile the example C++ code with.

cmake is used for creating files that tell the system how to build the project.

gcc-arm-none-eabi is a version of gcc designed to run with the target hardware we are using on the micro:bit.

binutils-arm-none-eabi contains tools that build the .hex file that goes onto the micro:bit - the assembler and linker amongst other things.

If you have a different Linux distro, you may have a different command to install these packages with. I use Debian with the 'aptitude' package manager.

On the GitHub site and in the README.md file, there is some guidance on how to use a Dockerfile for installing the dependencies. I didn't use this, so can't comment.

You also need Python 3 installed, but odds on you already have this set up.

Directory structure layout

Like all GitHub repositories, the file layout seems really obvious to whoever created it, but might not be as clear to the rest of us.

In the top level directory, we have a file called build.py. This is the file that builds (clue is in the name) the MICROBIT.hex file that we will copy to our micro:bit. We will come back to this file in a moment.

In the source directory you find the file main.cpp. This is the file that we will work with. The samples directory contains - you guessed it! - the sample files that we will work with.

Hello World

The main.cpp file that comes with the GitHub repository is all set up with the classic Hello World example. All we have to do to get this running on our micro:bit is:

  • Build the code to create a MICROBIT.hex file.
  • Copy the MICROBIT.hex file to an attached micro:bit v2.

Building the code

Go to the top directory in the repository and type the command:

python build.py

After some seconds and a wall of text, the MICROBIT.hex file is created in the same directory as our build.py file.

This is the file that needs to be copied to our micro:bit.

Copying the MICROBIT.hex file to the micro:bit

One simple way to deploy the newly created MICROBIT.hex file to the micro:bit is to use a file browser, such as Nautilus. Connect the micro:bit to your PC and it should appear as a drive called MICROBIT. Double click on this to connect the micro:bit to your PC. Then drag and drop the MICROBIT.hex file onto this folder. The LED on the back of the micro:bit should flash for a few seconds and then the code will run. You will see 'HELLO WORLD' scroll across the LEDs on the front of the micro:bit.

There are slicker ways to transfer the hex file across though. Each time that the micro:bit has new code flashed to it, the connection to the PC is lost. This means that you need to double click on the MICROBIT drive each time you want to load a new hex file to connect the board, then drag over the newly created hex file. Wouldn't it be nice to automate this, so that each time you create a new hex file, it is automagically loaded to the micro:bit?

Automating loading hex files to the micro:bit

I wrote a blog post about a script I created to find and mount a micro:bit after it is connected to my laptop's USB port. Please find this post here. I aliased the script needed to find and mount an attached micro:bit in my .bashrc file as 'mm'. In LInux, we can use the 'inotifywait' command to watch the MICROBIT.hex file we create when we build the C++ project for an update. When the hex file is updated, we can tell the system to mount the attached micro:bit and write the new hex file to the micro:bit. Here's the command that I use:

while inotifywait -e close_write MICROBIT.hex ; do mm && cp ./MICROBIT.hex /media/myusername/MICROBIT ; done

You need to change 'myusername' to your user-name. You could, of course, put this into your .bashrc file with a suitable alias.

Analog input test example

The next test I did was to edit one of the sample files supplied in the 'source/samples' directory to display the voltage applied to pin 1 of the micro:bit. I am looking to interface a sensor with the micro:bit, so this is the first step in the project.

If we look in the samples directory, there are a plethora of example files. The one that we will work with is called GPIOTest.cpp. If you look through the example files, you may notice something. None of them have a main function. The main function is needed for a c++ file to execute - this is the first function that runs. Why is this?

When we run python build.py from the root directory of the repository, it looks for a main function throughout the source directory. If there is more than one, the build crashes. I found this out the hard way. So we need to add a main function to our example file. Here's what I did:

Move the sample files to a new directory under the root directory of the repository.
mv ./source/samples samples_all

I moved the file ./source/main.cpp to the samples_all directory and renamed it HelloWorld.cpp
mv ./source/main.cpp ./samples_all/HelloWorld.cpp

Then I copied and renamed the GPIOTest.cpp file to the source directory:
cp ./samples_all/GPIOTest.cpp ./source/main.cpp

Now we need to add a main function to the main.cpp file that runs the relevant analog testing function in the file. Looking through the file listing, there is a function called 'analog_test()' starting at line 61 which looks a good bet. Line 69 is:

int px = analogPins[0]->getAnalogValue() / 40;

Looks like analogPins[0] is the pin that is set up to read an analog input. So which pin is analogPins[0]?

Line 16 is:

static Pin *analogPins[] = {&uBit.io.P1};

So analogPins[0] is uBit.io.P1, which looks a lot like pin 1 on the edge connector. Worth a shot. I dug through the firmware files on the relevant repository to confirm this.

Add the following few lines to the end of your new main.cpp file:

int main() {

This runs the analog_test() function.

Now we have to build the project to generate a new MICROBIT.hex file. Go to the root directory and type python build.py.

We get an error!

This is because line 2 of the file is:

#include "Tests.h"

We need to copy this file back from our samples_all directory to the source directory, alongside our main.cpp file. The other #include ... files are found in the libraries folder in the repository.

After a wall of text, we should have a new MICROBIT.hex file, ready to load on to the micro:bit. After copying this file over, the LED on the back of the micro:bit will flash for a few seconds, then we should see about half of the LEDs on. This shows that the analog input is 'floating' at about half of the voltage of the power supply.

So, how do we test the analog input? We can test the 0 and maximum input by connecting the ground pin to pin 1. I used a pair of tweezers to do this. Probably more sensible to use some alligator clips connected by a wire. With the ground connected to pin1, no LEDs are on. With the 3V connected to pin 1, all of the LEDs are on. So far so good.

I then tested the input using a 1/2Hz 3V sinusoidal input signal.I have an Analog Discovery 2 board made by Digilent. I programmed this to create the sinusoid and also to power the board. I connected this to the micro:bit using a Kitronik edge connector. If you are powering the micro:bit through the edge connector pins, be sure to only apply 3V. The micro:bit is only designed to take 5V through the USB connector. The little board starts to get quite hot quite quickly if you inadvertantly put 5V into the 3V pin on the edge connector!

To see a short YouTube video showing testing the analog input with the sinusoidal input please click on the picture below:

Setting up a micropython editor with the BBC micro:bit v2 on Linux

This post follows on from my blog post that shows how to set up the mu-editor in Linux for v1 of the micro:bit. This blog post is here:


I couldn't get the mu-editor to work with micro:bit v2. This was frustrating as I wanted to check some existing code ran on v2 of the micro:bit as well as start to use some of the new feautures on board.

I solved this by following a tip from a comment on my first post. This recommended using a different editor and following some setup instructions for that editor.

I will call this editor the PythonEditor as this is the name of the project's GitHub site:


The PythonEditor can be used online at:


Python Editor can also run offline. Initially, the editor would not recognise any micro:bits that were attached to my laptop. The information that I needed to follow to get PythonEditor working is here:


In case this site is removed, I replicate this information below and add one or two tips of my own.

I use <user> to represent whatever user name you are using. I use Debian 10 on a Lenovo X260 and X230.

Create a udev rule to get the micro:bit to be recognised

Create the file:


with this content:

SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", MODE="0664", GROUP="plugdev"

To create this file you need to be root or use the sudo command. I created and edited the file using vim:

sudo vim /etc/udev/rules.d/50-microbit.rules

Add <user> to plugdev group

To add your username to the plugdev group:

sudo usermod -aG plugdev <user>

To have this change recognised by the system, we need to restart the udev rules:

sudo udevadm control --reload-rules 

The webpage I followed to get this far says to log out and back in. I did not do this and things worked out.

Using PythonEditor online.

The online PythonEditor only works in Chrome for me. The editor now connected with micro:bit v1 and v2 and would program them. The first time that I flashed code to the micro:bit v2 took a while, with a message saying that the initial flash could take a while, but subsequent flashes would be faster. This is the case. I suspected that the first flash copied a micropython hex file to the micro:bit.

Using PythonEditor offline

The PythonEditor source code can be downloaded from GitHub and run offline. The instructions on how to do this are on the GitHub site, linked at the start of this post. This is how I run the PythonEditor. If we look in our downloaded GitHub repository, in the folder:


we find two .hex files:


I suspected that copying the v2.hex file to the micro:bit v2 was necessary before it would work with either of the editors.

So I took my spare micro:bit v2, connected it and tried to look at it with the serial connection on the PythonEditor. Nothing - a blank screen. I dragged and dropped the microbit_micropython-v2.hex file onto it using the Nautilus file explorer. After the requisite 10 seconds or so of flashing on the micro:bit as it loaded the hex, I tried again with the serial connection on PythonEditor and saw this:

PythonEditor serial connection with micro:bit v2

I see something similar when I click the REPL button on the mu-editor. I also get a REPL when I use the cu command I talked about in my earlier blog:

cu -l /dev/ttyACM0 -s 115200

So copying over the .hex file is a necessary step. PythonEditor does this for us if we haven't done it already.

So now I have some tools to program micropython on the micro:bit v2.

mu-editor with micro:bit v2

I can get this working with v2 of the micro:bit after getting PythonEditor up and running. But it is not stable for me. Sometimes it works, sometimes it doesn't. If I can figure out a reliable way of making this run, I'll edit this post.

There is some cryptic information in this post, which says that the UART buffer needs to be cleared to get the mu-editor to work.


I like the mu-editor and hope that I can get it up and running. Right now, I am relying on a single tool to program the micro:bit v2.

Summary of how to get micro:bit v2 working with a micropython editor

  • Create the udev rule.
  • Add <user> to plugdev group.
  • Add .hex file to the micro:bit

To do

I use the uflash or pyboard scripts with v1 of the micro:bit to enable me to use e.g. vscode to edit micropython and have a script automagically load updated code to the micro:bit. So far I have not gotten anything like this set up for the micro:bit v2. I would like this. I've gotten used to the idea that setting up programming environments requires tenacity.

Setting up mu-editor with the BBC micro:bit v1 on Linux

I recently set up an installation of Debian 10 and set up a tool chain for programming the BBC micro:bit with micropython. I'd forgotten some of the stumbling blocks I had the last time I did this, so am recording them here. Hopefully, this post will help you avoid them.

I use <user> to represent the user name that I log in with.

The instructions in this blog get you set up to work with the micro:bit v1 using mu-editor.

Part 2 shows how to set up a different editor that works with both v1 and v2 of the micro:bit under Debian. The link for part 2 is at the end of this post. I tried and failed to get mu-editor to work reliably with the micro:bit v2.

Install mu-editor

Use your package manager! In my case:

sudo aptitude install mu-editor

Using the package manager installs a bushel of python3 libraries, which you may not like. I tried the clean method of setting up a virtual environment and downloading the mu repository from GitHub. I ended up trying to install various dependencies that have other dependencies... In the end I gave up and used the package manager. One line. Installed.

Many people use apt-get instead of aptitude. I think both commands use the same libraries under the hood.

Finding the micro:bit

Which port does the micro:bit mount under? In my case /dev/ttyACM0. One way to find the port is with this command:

sudo dmesg | grep tty
[  135.410510] cdc_acm 1-6:1.1: ttyACM0: USB ACM device

The last line of the output gives the game away. /dev/ttyACM0 it is.

Setup permissions

We need to add our user name to the dialout group in /etc/group

When I first setup Debain and then tried to connect to a micro:bit on port /dev/ttyACM0 using Debian 10, I could only do this as root. Why?

ls -al /dev/ttyACM0


crw-rw-rw- 1 root dialout 166, 0 Jan 5 16:13 /dev/ttyACM0

This indicates why we can access the port using sudo - the port is owned by root. It also shows why adding the non-root user to the dialout group allows access without being root. I added my user account to the dialout group in /etc/group using:

sudo usermod -a -G dialout <user>

Enabling the micro:bit to mount under /media/<user>

I still could not connect with the micro:bit using a serial port monitor without being root.

The micro:bit is mounted under /media/<user>/MICROBIT.

ls -al /media/<user>
drwxr-x---+  2 root  root  4096 Jan  5 12:44 <user>

This shows that the directory that the micro:bit is mounted on is owned by root. I needed to change the owner and group of this directory to <user>.

sudo chowner /media/<user>
sudo chgrp /media/<user>

Now I can mount the micro:bit under /media/<user>/MICROBIT. I found I had to get this set up for mu-editor to allow me to program the micro:bit and use the REPL.

I wrote a blog post a few years ago presenting a bash script to find and mount or dismount a micro:bit here.

Terminal monitors

I came across the cu terminal monitor. To install and use with the micro:bit:

sudo aptitude install cu
cu -l /dev/ttyACM0 -s 115200

Hit ctrl-c and you get a REPL. The way to exit it is using the cryptic characters:


The tilda character '~' stands for <escape> in this instance.

The nice people at micropython produced a script called pyboard.py which finds a connected micro: bit and opens a terminal to display the output from the micro:bit. This tool is detailed at: http://docs.micropython.org/en/latest/reference/pyboard.py.html.

gtkterm is another useful serial terminal monitor which runs in its own GUI. Install using:

sudo aptitude install gtkterm

micro:bit v2 issues

The above all works for micro:bit v1. When I tried to flash some code to the micro:bit v2 using the mu-editor, I get this pop-up:

I can now run the latest mu-editor from the mu GitHub repository at: https://github.com/mu-editor/mu. However, I still got the same error when trying to use it with a micro:bit v2.

To run the latest version, download the GitHub repository, then type:

python run.py

in the downloaded mu directory. I guess that installing mu-editor using aptitude also installed all of the necessary dependencies to enable the GitHub version to run. The GitHub version is 1.1.0.alpha.3. The version installed using aptitude is 1.0.2.

I tried programming the micro:bit v2 using pyboard.py. This also failed.

After posting this blog with these issues, Mark left the comment at the end of this post that helped me get a different editor working with v2 of the micro:bit. The comment came the same day that I posted the blog! I was well chuffed as I didn't realise that anybody reads my blog posts, let alone the same day as I posted them. I guess a lot of people are searching for how to get micro:bit v2 running right now.

So I wrote a new post detailing how to setup and run a micropython editor with v2 of the micro:bit:


micro:bit c toolchain explained, part 2. yotta, file locations

December 2020: I wrote this post when only v1 of the micro:bit existed. I haven't yet checked to see if the contents are still valid for the toolchain used to program v2 of the micro:bit.

This article follows on from part 1 of my attempt to explain the chain of tools used to build your C code into something that can run on the BBC micro:bit. In this part, I will cover the yotta build tool and how the make build tool is used as the top level component.

Here's the final tool chain. Admire the beauty.

Offline tool chain for building an executable from C code for the micro:bit

So what is yotta and why do companies choose names like 'yotta' and 'ninja' for their products when this will make it hard for us to find them on the web?


Yotta is another build tool. Yotta takes the build file module.json and the configuration files target.json and config.json. Yotta produces the build file for cmake called CMakeLists.txt. If you read part 1 of this explanation of the micro:bit C tool chain, you will be getting used to the idea that one build tool creates the build file for the build tool underneath it. It took me a while to get my head around this. The reason for using these layers of build tools is that there are many other files than the ones that we write to pull into the project to enable our C code to be built to run on the micro:bit hardware.

In your yotta examples directory, which I represent with <yotta_examples> below, have a look in the file <yotta_examples>/yotta_targets/bbc-microbit-classic-gcc/target.json. Almost at the end of the target.json file, you will see where yotta tool is configured to produce a build file for CMake:

"toolchain": "CMake/toolchain.cmake",
  "scripts": {
    "debug": [

Here ends the description of build tools used to create the hex file that goes onto your micro:bit from the source C code.


This section is a bit of an extension/digression. The 'make' tool is not used in the programming stack for micro:bit. I use it to automate building and loading a hex file to a micro:bit.

Make is the Grandad of build tools. I often use this tool for building C projects outside of micro:bit programming. ninja may be faster for large C projects, but make is fast enough for my projects and has proven reliability.

The build file for make tool is called makefile, or sometimes Makefile. Linux does not distinguish between the two names, but Windows will. Typing 'make' at the command line will cause the contents of makefile to be processed by the make tool. You will be used to the idea of a build file being processed by a build tool by now.

I use make to automate building the binary and loading it onto my micro:bit. Here's a listing of a typical makefile for one of my projects:

	yt build
	# script to mount a microbit
	~/data/infolab2/progs/scripts/microbit_mount.sh mount
	cp ./build/bbc-microbit-classic-gcc/source/microbit-c-combined.hex /media/bill/MICROBIT/

yt build obviously builds the project. The line after the comment checks to see if the micro:bit is mounted and if not, mount it. The final line copies the newly generated hex file to the mount point for the micro:bit, which is specified in the script microbit_mount.sh.

I use a script to mount the micro:bit, as this is unmounted after flashing the new code. I use Linux; this may not be necessary with Windows. Details on the script I use can be found on my blog post. The micro:bit is mounted at /media/bill/MICROBIT. You need to change the mount point in the makefile to the location that you choose to mount your micro:bit.

Accessing Smartbox Grid 3 using Python and win32gui


Smartbox's Grid 3 communication software creates two windows containing the words 'Grid 3' in their titles, even though you can only see one. If you are trying to interact with this software using your own program, you need to make sure to access the window that you intend to.


I wrote some Python code to detect the use of Grid 3 or Tobii's Communicator software for this project, to visually show when somebody who uses eyegaze technology interacts with the software.

This post concentrates on the issue I had with finding the correct window that Grid 3 runs in. Grid 3 runs under Windows.

I use the pywin32 library to access the win32gui library. This library allows me to find which window is running the software that I want to monitor. However, after using this library to find the 'grid 3' window, my code kept on telling me that nothing was changing in the window, when I could clearly see something was. To make matters more confusing, the code seemed to run fine on one machine and not another.


Please find the the parts of the Python script needed to explain my solution below. All of the script is on my GitHub site.

import logging
import win32gui

    format='%(asctime)s.%(msecs)03d %(message)s',

COM_SOFTWARE = ['grid', 'communicator']
IGNORE = ['grid 3.exe', 'users']

def find_window_handle(com_software=COM_SOFTWARE, ignore=IGNORE):
    ''' Find the window for communication software. '''
    toplist, winlist = [], []

    def _enum_cb(window_handle, results):
        winlist.append((window_handle, win32gui.GetWindowText(window_handle)))

    win32gui.EnumWindows(_enum_cb, toplist)
    for sware in com_software:
        # winlist is a list of tuples (window_id, window title)
        logging.debug('items in ignore: {}'.format([item.lower() for item in ignore]))
        for window_handle, title in winlist:
            #logging.debug('window_handle: {}, title: {}'.format(window_handle, title))
            if sware in title.lower() and not any (x in title.lower() for x in ignore):
                logging.info('found title: {}'.format(title))
                return window_handle
    logging.info('no communications software found for {}'.format(com_software))

The critical debugging line is the commented out line 24:

logging.debug('window_handle: {}, title: {}'.format(window_handle, title))

When uncommented, and running the logging in debug mode, this listed out two windows that contained 'Grid 3' as part of their title, even though only a single Grid 3 window was visible. Even with just the 'Users' screen up, before launching a grid communication window, the logging.debug line returned two windows containing the name 'Grid 3' in their title:

grid: [(66532, 'GDI+ Window (Grid 3.exe)'), (197532, 'Grid 3 - Users')]

When running one of the Grids (for testing I used the Super Core grid), the software still tells me there are two windows with 'grid' in the title:

grid: [(66532, 'GDI+ Window (Grid 3.exe)'), (263256, 'Grid 3 - Super Core - .CORE')]

For this example, I could take the second window found and be done. However, to be robust, I created an IGNORE list, containing strings that are in the window titles that I do not want to use.

In the code example above, line 25 looks for the correct string to be in the window title and also checks that none of the strings in the IGNORE list are in the title:

if sware in title.lower() and not any (x in title.lower() for x in ignore):

This only passes the title for the window that I am interested in - the one containing the communication grid.


I use a Windows 10 virtual machine running in VirtualBox, with Debian Linux as the host. I also test on a separate Windows 10 only PC. I use a virtual machine for Windows for development as I run Linux on my laptop. The virtual machine allows me to create a static and controlled testing environment with only the software that I am working on in it. I double test on a stand alone Windows 10 machine in case the virtual environment somehow effects the software.

In this case, my script seemed to run well on one system and not another. I now suspect that sometimes the window that I was interested in was the only one generated by Grid 3 and at other times, the extra spurious Grid 3 window was generated as well. This spurious window was then selected by the software.

Using a microbit to control a servo motor

Subtitle: Making things move a microbit at a time

In this post I explain how I set up and operated a small servo motor that runs directly from the same 2xAAA battery pack that powers my microbit. I then explain how to operate a servo motor that requires a 5V power supply from the same microbit, using a transistor as a voltage level converter for the control signal.


I set up a small servo motor for a project to make an automated guinea pig feeder. Details on how to use this are here. Naturally, mistakes were made. I will detail the hardware setup, explain the control signals for the servo and show where the software can be found.

Hardware: SG51R servo motor

I used a Tower Pro SG51R servo motor, which runs from the same 2xAAA battery pack as the microbit. The battery pack, microbit and servo motor can be seen in the photo below. I slotted the microbit into a Kitronik edge connector.

2xAAA battery pack, microbit in a Kitronik edge connector and a SG51R servo motor

I got my SG51R servo motor from the Pi Hut here.

Why use this servo motor?

The SG51R works using a 2xAAA battery pack as the power supply, while many other servo motors require a higher voltage than 2xAAA batteries produce. This means it can run direct from the same battery pack used to power your microbit.

The manufacturer's website says that this servo motor requires 4.8V to operate. However, it works fine with the 2.4V or so that we get from the 2xAAA rechargeable battery supply I use to power the microbit. This is great, as it means I don't need to use a different voltage supply to power the servo motors with.

The servo has three wires for power and control. The black wire is for ground, the red wire for the voltage supply and the orange wire is the control signal.

The wires from the Kitronik edge connector to the servo motor connector can be seen in the photo below. I used D0 as the pin to output the servo motor control pulses on. The labels on the microbit are guides as how to use the microbit for the guinea pig feeder project.

The photo below shows how the wires from the microbit connect to the servo motor plug. Black is ground, red is positive voltage, yellow is the signal, from pin D0 on the microbit.

Wires from the microbit on the left, servo motor connector on the right

A servo typically responds to a control signal of a pulse between 1 ms and 2 ms long within a 20ms period. 180° needs a 1 ms pulse.

So what does that look like? The software I wrote to drive the servo motor is at the end of this article. I put an oscilloscope onto the signal pin. Here's what it looks like:

Servo motor controller pulses

We see a positive pulse every 20 ms. Remember that these pulses go from ground to the battery voltage (about 2.4 V in this plot). We will revisit this polarity when we talk about driving a 5 V servo motor later in this post. The width of this pulse sets the angle of the servo motor. The pulse must occur within the same 20 ms window, just how much of this window it takes up changes.

From the data sheet for the SG51R:

This servo is pulse controlled. This means that supplying a pulse will move it to a particular angle. In this case 0° is a 1.5 ms pulse, 90° a 2 ms pulse and -90° is a 1ms pulse. This may not be set by your controller by default or give you the full range of movement as such you may wish to try up to 2.25 ms and as low as 0.75ms. Be aware that if you go to far you can break the servo.

Using my 'scope, I could see that the servo motor responds to pulses with a width from 0.57 ms to 2.58 ms. Remember that the window that these pulses occur in remains as 20 ms wide. Just the width of the control pulse changes to take up more or less of this 20 ms.


Initially I carefully crafted beautifully structured micropython code in classes. Then ran out of memory, so ripped out all of the classes and bludgeoned the code to fit into the memory of the microbit.

I did, of course, find example software elsewhere on the 'net to get started and apologise that I can't remember which site I found this on to give proper credit.

The code can be found in the file called feeder.py on my GitHub site at: https://github.com/hardwaremonkey/microbit_projects

5V servo motor MG90D

Maybe you need a more powerful servo motor for your application. In this case, you will probably need one that requires a higher voltage than we get from the battery pack for the microbit. This section explains how to control a servo motor that is running from a separate power supply using a battery-powered microbit.

The mg90d is a servo motor that requires a higher voltage than the microbit can supply to operate. I ran it at 5V from a power supply. So how do we set up our microbit to control this?

I used a 2n2222 transistor to interface the microbit with the servo motor control wire. The control signal from the microbit goes to the base of the transistor. There is a 1K Ohm current limiting resistor in between this signal from the microbit and the base of the transistor. The signal going to the base of the transistor switches the transistor on and off.

The collector of the transistor connects to the 5V power supply through a 100 Ohm resistor.

Remember: We are only using the transistor to change the voltage level of the control signal. The voltage for the servo motor comes directly from the +5V power supply.

When the control signal from the microbit goes high, the transistor turns on. When the control signal goes low, the transistor turns off.

Find the wiring diagram below. The images come from Fritzing, though I made the diagram in Inkscape.

Circuit layout showing how to power and control a 5V servo using a microbit and a 2N222 npn transistor

There is one catch with this circuit - the control signals become inverted. You might ask - why not tap the signal from the emitter of the transistor, not the collector, then the signal would not be inverted. However, doing this produces an output signal going to the servo motor of lower voltage than the signal coming into the base of the transistor. Which defeats the object. There is about a 0.6V drop between the base and emitter of a typical bipolar transistor.

The simple answer is to invert the control signal coming from the microbit. I did this. See the oscilloscope grab below, showing the inverted control signal from the microbit in yellow and the non-inverted control signal going to the servo motor in blue. Note the different voltage levels. The signal from the microbit is around 2.4 V in amplitude and the signal going to the servo is about 5 V in amplitude.

Inverted controller signal from microbit is yellow, signal from transistor emitter to servo is blue

I put the micropython code needed to generate both a non-inverted and an inverted pulse below so you can see the simple trick needed to invert the pulse.

   def set_ms_pulse(self, ms_on):
        # pin.write_analog(1023) is constant on pulse
        # (1023 * ms_on / 20) gives a pulse of length ms_on
        self.pin.write_analog(1023 * ms_on / 20)

    def set_ms_pulse_invert(self, ms_on):
        ''' Gives inverted logic servo control pulse. '''
        self.pin.write_analog(1023 - 1023 * (ms_on / 20))

This worked to operate the 5V servo motor. The transistor allows us to drive the servo motor using the output of a battery powered microbit.

Another component that allows us to drive a device requiring a voltage that is not compatible the part that generates the control signal is an opto isolator. This is a story for another day.

As always, comments are welcome.

Getting the login screen on hotel WiFi using Linux


I can see that I am connected to the hotel WiFi on my laptop, but the login screen does not come up on my browser. So I cannot access the Internet.

My laptop is connected to a private IP address on the hotel network, but I cannot access the login page on a browser to get access to the world wide web

I run Debian 10, using the i3 tiling manager. I use wicd as my network manager and Firefox as the browser.

My mobile phone automagically connects to the hotel WiFi and brings up the login screen. So I know that the WiFi is working and allows access to the Internet.

How do I get the WiFi login screen on my laptop?

Solution - short answers

Using iproute


ip route

Example output:

default via dev wlp3s0 dev wlp3s0 proto kernel scope link src

Look at the first line 'default via'. Put the value, or whatever you have for that value in the first line, into your browser address bar. This should take you to the login screen.

Using /etc/resolv.conf

Look in the file /etc/resolv.conf after connecting to the WiFi and type the private IP address in this file into your browser.

To see the contents of this file, type:

more /etc/resolv.conf

Here's the output I got. Yours will probably have a different content:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)

When I put the private IP value ( in this example) into Firefox, the login screen appeared.

Victory looks like this - the hotel login page

Hopefully, one of these methods works for you. I put an expanded explanation and the background story below. I like background stories. Makes me feel like I'm not the only one who has trouble figuring things out.

I use a VPN when accessing the world wide web. This adds a layer of security when using public networks.


Our internet connection use a domain name system(DNS) server to find out where to go to get the contents for the web addresses we ask it to access. The file /etc/resolv.conf contains the IP addresses of the DNS servers in use by the current connection. This file is automatically created when you set up a new connection.

Looking at the contents of /etc/resolv.conf after I connected with the hotel WiFi, I recognise the IP addresses and as Google DNS addresses. This makes sense. Google will have a database of what website is where if anybody does.

The IP addresses to are reserved for private network addresses.

The IP address of in the file /etc/resolv.conf is one of the addresses reserved for private networks. So this looks to be the local access point. This makes sense. The IP address for the login page is a private address on the hotel network, not accessible on the world wide web where anybody could have a go at logging in to the hotel WiFi.

Putting this IP value ( into Firefox has us directed to the local login page.

I finally got to grips with this during the Covid 19 pandemic. I spent some time quarantining in a hotel in Rio de Janeiro before joining a survey ship to work offshore Brazil.

It works, then doesn't the next time you use it

Try clearing the browser cache.

Disable any VPN you are using while connecting, then re-enable the VPN.

I hope this post is of use to others. I welcome any comments and corrections.

BBC micro:bit guinea pig timed feeder instructions

This blog post is the instructions on how to use a timed servo motor circuit that I lashed up as part of a guinea pig feeder for a friend.

The hardware details can be found here: here

Software is on my GitHub site here

The need

A friend wanted something to open a box of food to feed his guinea pigs. The box needs to open after an adjustable time.

I can think of no more noble cause to focus on than feeding our furry friends.

After a period of procrastination and confusion I supplied the hardware and software detailed in this post. The mechanical components that the device will operate are up to my friend to make. He is a highly experienced mechanical engineer. I am but a lowly electronics tech.

Between the two of us, the guinea pigs will be fed!


The microbit counts down for a preset amount of time. The remaining time is indicated on the LEDs on the microbit. At the end of the pre-set time, the servo motor lever moves 90 degrees. The two positions of the servo motor are shown in the pictures below.

The timer is adjusted using the A and B buttons as detailed in the Instructions section below.

Servo motor position while the timer is in operation
Servo motor position once the timer completes the countdown

Instructions for use

The A button adds 12 minutes to the timer. An extra LED will light up for each press of the button. The B button decrements 12 buttons from the timer. An LED will turn off for each press of the button. The photograph below shows two lit LEDs on the microbit, indicating 24 minutes or less are left on the timer.

The two lit LEDs indicate that 24 minutes are left until the servo motor is activated

The last timer setting is recorded to the memory on the microbit. When the board is reset, it will start counting down from this time. So, if you set the timer to 2 hours (10 LEDs lit), on resetting, you will see 10 LEDs lit up and the board will take 2 hours to trigger the servo motor.

The reset button on the back of the board restarts the board. Please see the photograph below which shows the position of this button.

Underside of the microbit with the rest button indicated, next to the battery connector

Hardware description

The components of the system are shown in the picture below. On the left is a AAA battery pack containing 2 x AAA batteries. I use battery packs with a switch, which I get from eBay. The microbit is in the centre, slotted into a kitronik microbit edge connector. This edge connector allows the signal pins of the microbit to be connected to the servo motor using female to male jumper cables . The cables are designed for the 0.1" pins and sockets found on the edge connector and the cable connected to the servo motor.

AAA. battery pack, microbit, servo motor

The full assembly including cabling is shown in the photo below.

AAA battery pack (right), microbit and edge connector board (centre), servo motor (top), connectors (right)

A close up photo showing how the cables from the edge connector and the servo motor connector are connected is shown below. The black/brown wires are ground, the red wires are the battery voltage and the yellow wire is the PIN0 signal line.

Pins from cables connected to the Kitroniks edge connector on the left, sockets connected to the servo motor on the right

The photo below shows how the cables connect to the pins on the Kitronik edge connector.

Cables connected to the Kitronik edge connector. Yellow goes to 0, black to 0V, red to 3V.

BBC micro:bit wrist holders

With my handshake project, a microbit and AAA battery pack need to be worn on the wrist. They can be vigorously shaken. I don't want the equipment flying off! So what can I use that will hold the microbit and batteries safely in place and is comfortable and safe to wear?

I tried a couple of armband holders aimed at iPods recently. Both of them are suitable for housing a BBC microbit and a AAA battery pack. Prior to this, I used a wrist holder that I made myself.

The advantages of repurposing an iPod arm band holder instead of making one yourself are:

  • Saves you the time of making one.
  • The clear plastic cover makes it easy to clean.

Please find photographs of the armband holders I tried out as wrist holders containing a microbit and AAA battery holder below. First a top-tip!

Velcro tabs to secure armband straps

Whichever armband you re-purpose to be a wrist holder, as the wrist is narrower than your arm, the end of the strap will no longer stick down. The end will flap free. As this end of the strap has the hook velcro on it and the rest of the strap is the loop kind, the strap will no longer stick down to itself. You need to make some double sided hook velcro tabs. See the photo below.

Double sided hook velcro tabs

These are lengths of sticky back hook velcro, stuck back to back. Place them on the loop velcro to enable the strap to stick to itself when used on the wrist.

TuneBelt Armband for iPod touch 4G

The TuneBelt iPod touch 4G armband holder can be used to hold a microbit and AAA battery pack as shown in the photo below. Use some double sided velcro hook 'gender bender' strips to allow the strap to stick to itself when used on the wrist.

iPod touch 4G arm band in use as a microbit and AAA battery pack wrist holder
TuneBelt iPod touch 4G used as a microbit and AAA battery pack holder, front view

arm band in use as a microbit and AAA battery pack wrist holder

TuneBelt Sport Armband iPod touch 4G box

igagdgitz iPod classic armband holder

Larger than the iPod touch 4G holder. Costs about twice as much - about £10 from eBay. The build uses thicker neoprene. The rear panel folds down to allow easy installation and removal of the microbit and battery holder. This is made from a decent thickness of neoprene and is held securely in place with velcro on three sides.

The strap is longer and bulkier than the iPod 4G holder . If you know you are going to use this arm band as a wrist holder, it would be worth trimming the strap down. Then you would rely on the velcro double-sided tabs to stick the strap down unless you sewed some hook velcro on to replace the tab that you had cut off when shortening the strap.

iPod classic arm band in use as a microbit and AAA battery pack wrist holder
igadgitz iPod classic holder, front view, containing BBC microbit and AAA battery holder. There are two velcro tabs near the plastic to enable the strap to latch onto itself when worn on the wrist.

Rear view, showing fold down flap which allows acccess to the interior