MicroBit Remote Development
 
Bluetooth Communication
 

The source code of all examples can be downloaded from a link in the right side bar.

Bluetooth communication is supported by the application processor of the micro:bit, but the Bluetooth protocol is not fully implemented in the current version of MicroPython. Bluetooth communication is only available between two micro:bit devices (here called nodes). But the good news is that the code is extremely simple compared to programming with the standard Bluetooth API. Typically both nodes must call radio.on() to establish a Bluetooth link (no Bluetooth paring is necessary, there is no server-client hierarchy). Either of them may send a string message any time by calling radio.send(msg) and the message is buffered in the other node's receiver buffer, where it can fetched by calling radio.receive(). If the buffer is empty, None is returned.

 
 

 

green

Example 1: Two persons exchange number information

 

Aim:
Establish a two-way communication where each person can select a number by pressing the A button that increase the number by 1 (until 9 and then 0 again). By pressing the B button, the selected number is sent to the partner node where it is displayed during 1 second. There it is prefixed by a colon to tag it as data received number.

Program:

# Node.py

import radio
from microbit import *

radio.on()
n = 0
display.show(str(n))
while True:
    # number selection
    if button_a.was_pressed():
        n += 1
        if n == 10:
            n = 0
        display.show(str(n))
    # send message
    if button_b.was_pressed():
        radio.send(str(n))
    # receive message
    rec = radio.receive()
    if rec != None:
        display.show(":" + rec)  
        sleep(1000)
        display.show(str(n))  
    sleep(10)
            

Remarks:
During the developing phase the two micro:bits may be attached to two computers or the program is downloaded one after the other from the same computer and then executed with separate power supplies. It is not important which device is powered first, as soon as both devices are powered, the communication link is established. (This is quite different and much simpler than a client-server scenario.)

 

 

green

Example 2: Realtime sensor data collection

 

Because there is no way to receive data on a PC from the micro:bit via Bluetooth, the acquired data are first transferred from the data collecting micro:bit (that may be completely stand-alone) to an micro:bit that acts as an intermediate agent .

The idea is the following: A Python program running in TigerJython starts the agent program in a MBM terminal window. The agent receives measurement values as text lines from the Bluetooth link and print them out in the terminal window. The PC program captures the lines with getDataLines() and process the data.

Aim:
Acquire x-axis acceleration every 50 ms and trace them in realtime in a graphics window.

Program:

# DataAcquisition.py

import radio
from microbit import *

radio.on()
display.show("D") 
t = 0
T = 5
dt = 50  # ms
while not button_b.was_pressed():
    v = accelerometer.get_x()
    data = str(t) + ":" + str(v)
    print(data)
    radio.send(data) 
    t += (dt / 1000)
    sleep(dt)
display.show(Image.NO)    
# DataAgent.py

import radio
from microbit import *

radio.on()
display.show('A')
print("starting") # Triggers data display
rec = ""
while True:
    rec = radio.receive()
    if rec != None:
        print(str(rec))
    else:
        sleep(10) 




# DataTracer.py

from mbm import *
from gpanel import *
import time

def init():
    clear()
    drawGrid(0, 10, -1000, 1000, "darkgray")

makeGPanel(-1, 11, -1200, 1200)

run("DataAgent.py")
enableDataCapture(True)
startData = False

title("DataTracer")
init()
tOld = 10
while not isTerminalDisposed():
    data = getDataLines() # empty if nothing received
    if startData:
        for s in data:
            z = s.split(":")
            t = float(z[0]) % 10
            v = float(z[1])
            if t < tOld:
                init()
                pos(t, v)
            else:
                draw(t, v)
            tOld = t
    else:
        for s in data:
            if s == "starting": # got from agent
                startData = True
       
title("Finished")

 

microbit21

Typical output of DataTracer

Remarks:
To start capturing lines in the terminal (REPL) window, enableDataCapture(True) is called. From now on, all lines in the terminal window are copied into an internal buffer (a list of strings). The content of the line buffer is returned by calling getDateLines() and the buffer is cleared.

As soon as the data capture is enabled, all REPL data is captured that also includes user information written to the terminal window. We must wait in the data receiving loop until the agent sends a "starting" message that signals the start of time/value information.

If you want capture sensor data by a PC from a micro:bit front end that collects the data and sends them over the serial line to the data tracer, exactly the same DataTracer program can be used, but DataAgent has to be modified as follows:

# DataAgent.py

from microbit import *

display.show("D") 
t = 0
dt = 50  # ms
print("starting")  # signal that data transmission starts
while not button_b.was_pressed():
    v = accelerometer.get_x()
    print("%6.2f:%d" %(t / 1000, v))
    t += dt
    sleep(dt)
display.show(Image.NO) 
This scenario can also be useful if the micro:bit is used as data acquisition front end to a Raspberry Pi.