Skip to main content
Planet Zephyr

The BBC Microbit V2 and OpenThread

By March 31, 2023No Comments

This is an initial posting about early progress I have made with the BBC Microbit V2 and OpenThread. Nordic Semiconductor has posted some good example code for the NRF52840 dongle and development kit. These examples involve the Zephyr operating system and work pretty well. In particular, the echo server example is easy enough to build and deploy on an NRF52840 dongle or XIAO NRF52840 board. This can then be controlled over IPv6 as I mentioned in a previous post.

Compiling the same code for the BBC Microbit V2 initially did not work. Setting the board type to nrf52833dk_nrf52833 (the same IC that is in the Microbit) allows compilation to work but flash programming the device is difficult. I was looking for a way to do this by setting the board type to bbc_microbit_v2. The code would build, flash but not run. It seems that the configuration files for the Microbit V2 in Zephyr do not enable the 802.15.4 radio required by the Thread network. I discovered that this could be enabled by adding an app.overlay file to the project root directory with the following contents:

/ {
	chosen {
		zephyr,ieee802154 = &ieee802154;
&ieee802154 {
	status = "okay";

Compiling, flashing and running the echo_server example worked after adding this.

The next part of the journey was to add some Microbit specific I/O. I thought it would be nice to control the onboard LED matrix over the network. The echo_server code is a little complex and perhaps daunting for people starting out. I modified it a little so that a beginner could concentrate on a single C file which would handle UDP packets and I/O. This file is called usb_processor.c and is shown below:

#include "matrix.h"

int initIO()
    int ret=0;
    return ret;
void udp_send_receive(uint8_t *buffer, uint32_t len)
    // Message is assumed to be at least 4 bytes long (a kluge for now!)
    // print the message out for debugging purposes
    if (len)
        int index=0;
        while(index < len)
            printk("%x ",buffer[index]);
    // pass some data back to the sender

The function initIO configures I/O devices (the LED matrix in this case – see matrix.c in the github link provided below). The function udp_send_receive is called when a UDP packet is received. In this primitive example, the first two bytes are treated as row and column bit masks for the LED matrix. The values are passed on to matrix_put_pattern. Just before returning, two characters are placed in the return packet just to verify that communications is bidirectional.

The NodeJS code that sends data to the Microbit is shown below:

var udp=require('dgram');
// -------------------- udp client ----------------

var buffer = require('buffer');

// creating a client socket
var client = udp.createSocket('udp6');

//buffer msg

  console.log('Data received from server : ' + msg.toString());
  console.log('Received %d bytes from %s:%dn',msg.length, info.address, info.port);
//sending msg
var data = Buffer.from([0x1f,0x0,0x32,0x33]);

    } else{
        console.log('Data sent !!!');

The IPv6 address of the Microbit has been hard-coded for now (working on network discovery next). The payload received by the Microbit is prepared in the data Buffer object. The first byte selects which rows are to be activated in the LED matrix (there are 5 of them). The second byte is selects which columns are active. In the case of columns, a ‘0’ in a particular bit activates that column.

Code (such as it is) is over here on github

A closing note for now: This is tricky stuff to set up and get working. I should probably put together a post that details the entire process of setting this up and running. In the meantime, if you have questions send me an email

Benjamin Cabé