BBC micro:bit
Happy Clappy McRoboFace

Introduction

This page is a write-up of the main part of a slightly larger project that Luca put together for open evening this year. It makes use of two nice micro:bit accessories and needs two micro:bits communicating by radio.

In the first image, the micro:bit on the left is connected to a Pimoroni Enviro:bit. This board has a colour sensor, a temperature and pressure sensor and an analog sound sensor. We are just using the sound sensor here. The micro:bit on the right has a 4tronix McRoboFace wired up and an external power supply so that it can run at full dazzling brightness. The McRoboFace is smiling.

micro:bit circuit

A single clap, thump on the table or loud noise near the first micro:bit and then the McRoboFace changes to show a frown,

micro:bit circuit

A double clap is required to return the smiling face.

On the evening, we had the micro:bit with the Enviro:bit away from the one with the McRoboFace but with a line of sight so the results could be seen. Luca also used a Pimoroni Noise:bit to say 'happy' or 'sad', with a third micro:bit receiving the radio instructions.

Programming - Sending

This is the basic outline for the program for the Enviro:bit with the library included in the script. There's no reason not to do this if this micro:bit just has to send messages at the right time.

from microbit import *
import radio


chnl = 10
radio.config(channel=chnl)
radio.on()

offset = 580

def read():
    return max(0, pin2.read_analog() - offset)

def wait_for_double_clap(timeout=1000, spread=500, sensitivity=75):
    sensitivity = 105 - sensitivity

    clap_one_time = None

    start_time = running_time()
    while running_time() - start_time < timeout:
        if read() > sensitivity:
            while read() > sensitivity:
                pass
            sleep(100)
            if clap_one_time is not None and running_time() - clap_one_time < spread:
                return True
            else:
                clap_one_time = running_time()

    return False

def wait_for_clap(timeout=1000, sensitivity=75):
    sensitivity = 105 - sensitivity

    start_time = running_time()
    while running_time() - start_time < timeout:
        if read() > sensitivity:
            return True

    return False

smile = True
display.show(Image.HAPPY)
while True:
    if smile:
        if wait_for_clap():
            smile = False
            radio.send("f")
            display.show(Image.SAD)
    else:
        if wait_for_double_clap():
            smile = True
            radio.send("s")
            display.show(Image.HAPPY)
    sleep(10)    

Programming - Receiving

This is the basic program for the micro:bit with the McRoboFace.

from microbit import *
import neopixel
import radio


chnl = 10
radio.config(channel=chnl)
radio.on()

n = neopixel.NeoPixel(pin12, 17)

colours = {
    "off":(0,0,0),
    "red":(255,0,0),
    "orange":(255,165,0),
    "yellow":(255,255,0),
    "green":(0,255,0),
    "blue":(0,0,255),
    "indigo":(75,0,130),
    "violet":(138,43,226),
    "purple":(255,0,255),
    "white":(255,255,255),
}
parts = {
    "nose":[14],
    "eyes":[15,16],
    "mouth":list(range(14)),
    "all":list(range(17)),
    "smile":list(range(6)),
    "frown":[0] + list(range(5,10)),
    "oh":list(range(10)),
    "straight":list(range(10,14)) + [0,5]
}


def all_off():
    for i in range(17):
        n[i] = (0,0,0)

def get_colour(colour):
    return colours.get(colour, (0,0,0))

def get_part(part):
    return parts.get(part,[])

def light(part,colour):
    c = get_colour(colour)
    p = get_part(part)
    for i in p:
        n[i] = c  

def smile():
    light("all", "off")
    light("eyes","green")
    light("nose","green")
    light("smile","green")
    n.show()

def frown():
    light("all", "off")
    light("eyes","red")
    light("nose","red")
    light("frown","red")
    n.show()
    

  
smile()

while True:
    s = radio.receive()
    if s is not None:
        if s=="s":
            smile()
        elif s=="f":
            frown()
    sleep(50)

Next Steps

In the second program, the lines that import and configure the radio, along with the while loop at the end are the core of any program you might use to respond to the radio messages sent from a sensor that sends character strings when it changes state.

This forms a basic network and it is easy to add nodes as long as you stick to the same radio channel. Each time a node is added, it can do something different, be in a different part of the room or 'installation'. It makes sense to put a speaker near to the robot face and use speech or sound to add to the personality of the face.

An RTC node could be added to give time signals that could be spoken by the speaker node or displayed across 2 or 4 micro:bits in the network.

The Scroll:bit (or Scroll pHAT HD) is quite a convenient display for a network like this and touch input from the Touch:bit (or Touch pHAT) would add to the network's capability. All of these are Pimoroni accessories. The ones that are made for the Raspberry Pi both run on the 4tronix Bit:2:Pi.