Accessing micro:bit Hardware

Contents

Hardware on the micro:bit PCB

On the micro:bit printed circuit board (PCB) but separate to the microcontroller chip is an assortment of hardware items that make it easy for beginners and educators to get started; including buttons, LED display matrix, accelerometer, compass, speaker and microphone.

These will all be discussed, with example code where appropriate, though not in any great level of detail. The official MicroPython for micro:bit documentation should always be referenced for further details.

This series on the micro:bit intends to explore the interfacing of many different and varying external components to the little device through its GPIO pins. With this in mind, this blog will tend to focus on the two buttons, the speaker and the LED display.

The buttons can allow the user to initiate or stop a process while the speaker and display can provide visual/audio feedback e.g. when an error condition has been detected.

Buttons

There are two buttons on the board and they are objects named as button_a and button_b in the microbit module.

These buttons are useful e.g. a button push by the user might indicate a request to read a sensor and print the result.

The method was_pressed() is used to detect if a specified button has been pressed and released. This method remembers if a button has been pressed and will return True when called regardless of time lapsed after the button push. The method will then set its state to False till the button is pushed again.

The latching of a button push makes this method very powerful.


Example:
# Demonstrates the micro:bit buttons

from microbit import button_a, button_b

while True:
    # Endless loop that looks to see if
    # any buttons have been pressed.
    A = button_a.was_pressed()
    B = button_b.was_pressed()
    if A:
        print('Button A has been pressed')
    elif B:
        print('Button B has being pressed')

Sample Output:
Button A has been pressed
Button B has being pressed
Button B has being pressed
Button A has been pressed
          

The method is_pressed() detects whether the specified button is being pushed i.e. currently held down. This function can also detect whether both buttons are being held down simultaneously.


Example:
# Demonstrates the micro:bit buttons

from microbit import button_a, button_b, sleep

while True:
    # Endless loop that looks to see if
    # any button(s) are being pressed.
    A = button_a.is_pressed()
    B = button_b.is_pressed()
    AandB = A and B # Test both buttons
    if AandB:
        print('Both buttons are being pressed')
    elif A:
        print('Button A is being pressed')
    elif B:
        print('Button B is being pressed')
    sleep(500) # Wait 500 ms

Sample output:
Button B is being pressed
Button A is being pressed
Button A is being pressed
Button B is being pressed
Button A is being pressed
Both buttons are being pressed
          

LED Display

The LED display on the front face of the micro:bit is composed of a 5 x 5 grid of red LEDs.

As an output device it is very low resolution. When writing out e.g. sensor readings it makes a lot more sense to send the output to the REPL, an external screen or a file. However the LED display is easy to use so can be a quick way to signal the user that some event, such as an error, has occurred.

The microbit  module has the pre-declared object display to control writing to the LED display. This object has the following methods:

  • display.show()
  • display.scroll()
  • display.on()
  • display.off()

The show() method, as suggested by its name, causes images to be displayed.

Syntax:
show(image, delay, wait, loop, clear)

Where:
  image : the image to be displayed.
  This can be a string, float, integer
  or iterable sequence of images[1].

  delay : the time that an item (digit of
  a number, character of a string or image
  from an iterable sequence) in ms.
  Default = 400.

  wait : if True the program will wait till
  the display animation has completed.
  Default = True.

  loop : if True the animation will repeat
  forever. Default = False

  clear : if True the display will be
  cleared after the animation is complete.
  Default = False.
          
Example 1:
from microbit import display as d
d.show('Z')

This will display the letter 'Z' and leave the display on since clear=False by default.

Example 2:
from microbit import display as d
d.show('HELLO WORLD', delay=1000, loop=True)

This will display the string 'HELLO WORLD' one letter at a time with each letter being displayed for 1,000 milliseconds (1 second). Since loop=True the animation will repeat until interrupted.

Example 3:
from microbit import display as d
d.show(1.235, delay=2000, clear=True)

This will display the float 1.235 one digit at a time with each digit being displayed for 2,000 milliseconds (2 seconds). Since clear=True the display will be cleared when the animation is completed.

The LED display can also scroll text horizontally with the display.scroll() method.


Syntax:
scroll(text, delay, wait, loop, monospace)

Where:
  text : the image to be displayed.
  This can be a string, float or integer.

  delay : the speed at which the text
  scrolls. Default = 150.

  wait : if True the program will wait till
  the display animation has completed.
  Default = True.

  loop : if True the animation will repeat
  forever. Default = False

  monospace : if True there will be no
  space between each character otherwise
  there will be a blank 1-pixel column
  between each character. Default = False.

Examples:
from microbit import display as d

d.scroll('Z')
d.scroll('HELLO', delay=300, loop=True)
d.scroll(389, loop=True, monospace=True)
          

Try the above examples, one at a time, by copying from the webpage and pasting into the microbit's REPL in the editor[2].

There are two more methods of the display object that are must knows if the micro:bit is to be used to interface external devices, sensors or components.

The LED display uses some of the GPIO pins that may be needed for other projects. These pins can be reassigned for other uses by turning the display off with the method display.off(). The display can turned back on with the method display.on().

Speaker

Mounted in the centre of the PCB is the JIANGSU HUANENG MLT-8530 speaker. Being the largest board component in footprint and height it is easily recognised. The microbit module provides the following modules and objects to generate and control sound through the speaker:

  • speaker
  • audio
  • audio.SoundEffect
  • Sound

microbit.speaker Object

  • speaker.on() Turns the speaker on.
  • speaker.off() Turns the speaker off.
  • speaker.is_on() Returns True if the speaker is on, else False.

microbit.audio Module

  • audio.play() Plays a sound. There are three basic sound options which are described below.
  • audio.stop() Stops all audio playback.
  • audio.is_playing() Returns True if audio is playing else False.

The audio.play() method is the engine room for obtaining sound effects through the speaker.


Syntax:
audio.play(source, wait=True, pin=pin0, return_pin=None)

Where:
  source : There are three types of sources available:
    (1) Built-in sounds; these are discussed below.
    (2) User created sounds; discussed below.
    (3) AudioFrame; see official documentation.

  pin, return_pin : Ignore these!
          

Built-in sounds are provided by the Sound object. The syntax is simple:


Syntax:
Sound.NAME

Where:
  NAME is one of:
    GIGGLE, HAPPY, HELLO, MYSTERIOUS,
    SAD, SLIDE, SOARING, SPRING,
    TWINKLE, YAWN

Example:
from microbit import audio, Sound
for i in range(3):
    audio.play(Sound.GIGGLE)
          

User defined sounds are possible to define with the audio.SoundEffect class. The class constructor has eight parameters, all of which are optional.


Syntax:
SoundEffect(freq_start, freq_end
             duration,
             vol_start, vol_end
             waveform, fx, shape)

Where:
  freq_start : Start frequency (Hz). Default: 500

  freq_end : End frequency (Hz). Default: 2500 

  duration : duration in ms, Max = 9999, Default: 500

  vol_start : start volume range 0..255, Default: 255

  vol_start : start volume range 0..255, Default: 255

  waveform : one of WAVEFORM_SINE, WAVEFORM_SAWTOOTH,
             WAVEFORM_TRIANGLE, WAVEFORM_SQUARE,
             WAVEFORM_NOISE.
             Default: WAVEFORM_SQUARE

  fx : Added sound effect, one of:
       FX_TREMOLO, FX_VIBRATO, FX_WARBLE, FX_NONE.
       Default: FX_NONE

  shape : Defines the move from freq_start to freq_end.
          One of: SHAPE_LINEAR, SHAPE_CURVE, SHAPE_LOG.
          Default: SHAPE_LOG

          

Example 4
# Define and play a custom sound
# on the micro:bit's speaker.
from microbit import audio
from audio import SoundEffect

mySound = SoundEffect()
# Play the default SoundEffect
audio.play(mySound)

# Define and play a custom sound
mySound.freq_start = 250 #Hz
mySound.freq_end = 3000 #Hz
mySound.duration = 9999 #ms
mySound.waveform = SoundEffect.WAVEFORM_SINE
mySound.fx = SoundEffect.FX_VIBRATO
mySound.shape = SoundEffect.SHAPE_CURVE
audio.play(mySound)
          

The sound from the speaker is very tinny but quite a variety of audio is possible with the SoundEffect class.

There are also two additional modules (separate to the microbit module); music and speech which have methods that also use the speaker. They will not be discussed here.

Accelerometer and Compass

Onboard the micro:bit but external to the processor is the ST branded LSM303AGR accelerometer and magnetometer that provides motion and magnetic field sensing. The microbit module provides the accelerometer and compass objects for exploiting the LSM303AGR feature set.

The accelerometer object has the following methods:

  • accelerometer.get_x() : in milli-g
  • accelerometer.get_y() : in milli-g
  • accelerometer.get_z() : in milli-g
  • accelerometer.get_values() : Returns x, y, z as a tuple
  • accelerometer.get_strength() : Across all three axis
  • accelerometer.set_range() : Sets the sensitivity range

These are all common type measurements and settings that can be read from or set on most commercially available accelerometer chips.

The accelerometer object also has several methods for returning 'gestures' but these won't be discussed here.


Example 5
# Demonstrate the basic functionality
# of the micro:bit's accelerometer.

from microbit import accelerometer as a
from microbit import sleep

# Every 2 seconds read the accelerometer
# values and output to the REPL.
while True:
    print('X-axis:', a.get_x())
    print('Y-axis:', a.get_y())
    print('Z-axis:', a.get_z())
    print('Strength:', a.get_strength())
    print('Gesture:', a.current_gesture())
    print()
    sleep(2000)

Output:
X-axis: -72
Y-axis: 76
Z-axis: -1072
Strength: 1078
Gesture: face up

X-axis: -1124
Y-axis: 64
Z-axis: 400
Strength: 1194
Gesture: left

X-axis: 372
Y-axis: -76
Z-axis: 916
Strength: 991
Gesture: face down
          

The compass object has the following methods:

  • compass.calibrate()
  • compass.is_calibrated()
  • compass.clear_calibration() : in milli-g
  • compass.get_x() : in nano tesla
  • compass.get_y() : in nano tesla
  • compass.get_z() : in nano tesla
  • compass.heading() : 0..360 degrees
  • compass.get_field_strength() : in nano tesla

Again, these are all common type measurements and settings that can be read from or set on most commercially available magnetometer chips.


Example 6
# Demonstrate the basic functionality
# of the micro:bit's compass.

from microbit import compass as c

print('Is compass calibrated?', c.is_calibrated())
print('X-axis:', c.get_x())
print('Y-axis:', c.get_y())
print('Z-axis:', c.get_z())
print('Field Strength:', c.get_field_strength())

Output:
Is compass calibrated? False
X-axis: 12450
Y-axis: 15750
Z-axis: -23100
Field Strength: 31562
          

In order to obtain good results from the compass it must first be calibrated; a right royal painful exercise. As a consequence the results from Example 6 will not be accurate.

For further details and examples refer to the official MicroPython for the micro:bit documentation.

Microphone

The onboard MEMS microphone (Knowles SPU0410LR5H-QB-7) provides a sound input to the micro:bit. It is a tiny gold coloured component located on the edge of the board between the main processor chip and the USB socket.

A small LED located on the front side of the board above the LED display and just right of the gold coloured touch sensitive logo is lit when the microphone is operational.

The microphone is not used to record sounds but rather it senses sound level, returning an 8-bit value i.e. in the range 0 to 255. Methods to read sound levels are to be found in the microbit.microphone object.

Sound events QUIET (transition from loud to quiet) and LOUD (transition from quiet to loud) are defined in the microbit.SoundEvent class.

It could be argued that the integration of the microphone and SoundEvent components are overly complicated. The Example 7 is a simple attempt to show how these two components work together.


Example 7
# Demonstrate the basic functionality
# of the micro:bit's microphone.

from microbit import microphone as M
from microbit import SoundEvent as SE
from microbit import sleep

# Take a sound level reading every
# two seconds and report on it.
while True:
    level = M.sound_level()
    print('Sound level is:', level)    
    if M.is_event(SE.LOUD):
        print('Its very noisy here!')
    else:
        print('All quiet here now!')
    print()
    sleep(2000)

Sample output:
Sound level is: 0
All quiet here now!

Sound level is: 140
All quiet here now!

Sound level is: 211
Its very noisy here!

Sound level is: 0
All quiet here now!
          

This module will not be discussed further in this series.