Overview

The Adafruit CRICKIT for micro:bit is a very nifty add-on. With it, you can extend the capabilities of the micro:bit to include additional inputs/outputs, capacitive touch input, servo control and DC motor control.

These functions can be accessed via the Arduino IDE with the following tutorials:

This guide presents using CRICKIT functions via MicroPython. MicroPython was started by author Damien George to allow Python programming on microcontrollers like the micro:bit. CircuitPython is a fork of MicroPython that Adafruit started to make Python on microcontrollers easier for beginners. Unfortunately, CircuitPython will not fit onto the limited memory of the micro:bit. 

There are significant differences between MicroPython and CircuitPython. This tutorial focuses on using MicroPython on micro:bit with an Adafruit CRICKIT robotics controller attached.

Parts

BBC micro:bit

PRODUCT ID: 3530
The British Invasion is here! No, not music...microcontrollers! New to the USA is the newest and easiest way to learn programming and electronics - the BBC...
$14.95
IN STOCK

Adafruit CRICKIT for micro:bit

PRODUCT ID: 3928
Sometimes we wonder if robotics engineers ever watch movies. If they did, they'd know that making robots into slaves always ends up in a robot rebellion. Why even go down that...
$29.95
IN STOCK

USB A/Micro Cable - 2m

PRODUCT ID: 2185
This is your standard USB A-Plug to Micro-USB cable. It's 2 meters long so you'll have plenty of cord to work with for those longer extensions.
$4.95
IN STOCK

5V 2A (2000mA) switching power supply - UL Listed

PRODUCT ID: 276
This is a FCC/CE certified and UL listed power supply. Need a lot of 5V power? This switching supply gives a clean regulated 5V output at up to 2000mA. 110 or 240 input, so it works in...
$7.95
IN STOCK

A breadboard and some parts are used to demonstrate certain functions - feel free to only get the parts you may want to use for your project.

1 x Half Breadboard
Half-size breadboard
1 x Micro Servo
Tiny little servo can rotate approximately 180 degrees
1 x DC Motor
Toy / Hobby Motor - 130 Size
1 x 10K potentiometer
Breadboard size trim pot
1 x LEDs
Diffused 5mm LED Pack - 5 LEDs each in 5 Colors - 25 Pack
1 x Breadboard Buttons
Tactile Button switch (6mm) x 20 pack

Installing MicroPython on the micro:bit

We highly recommend you install the Mu Python editor. Mu has versions for PC, mac, and Linux, it is open source / free, and it is tailored to learning and microcontrollers such as the micro:bit and others.

Download Mu

Download Mu from https://codewith.mu. Click the Download or Start Here links there for downloads and installation instructions. The website has a wealth of other information, including extensive tutorials and and how-to's.

Starting up Mu

It would be best to plug your micro:bit into your computer before starting Mu, as the Mu menu changes depending on which board it detects on startup.

For Mu starting up in micro:bit mode, you should get a display like this.

The menu bar looks like the one below:

If you are familiar with Mu with CircuitPython, you are not seeing strange things. There are buttons on the menu that are different than when Mu is in CircuitPython (Adafruit) mode.

The first time you start Mu, you will be prompted to select your 'mode' - you can always change your mind later. For now please select BBC Microbit!

The current mode is displayed in the lower right corner of the window, next to the "gear" icon. If the mode says Adafruit or something else, click on that (or the leftmost menu icon Mode and then choose BBC Microbit in the dialog box that appears.

Installing MicroPython

Mu will install MicroPython for you. It is not intuitive that it does so, but it does work.

Create a new blank file/program. Ensure your micro:bit is plugged in to your computer's USB port and recognized with Mu being in Microbit mode.

Click the Flash icon shown at left. 

The text in the lower left will say "Flashing MicroPython (or untitled") to the micro:bit. The micro:bit yellow LED should be flashing during this process.

Then Mu will say "Finished Flashing" in the lower left corner of its window.

MicroPython is now on your micro:bit.

The flash drive that shows up on plugging your micro:bit into the computer will NOT change at all, re. you cannot tell if MicroPython is installed on your board by looking at the flash drive representing the micro:bit (unlike CircuitPython which changes the drive name to CIRCUITPY, this does NOT happen with MicroPython).

 

Loading Programs

Loading MicroPython programs onto the micro:bit is different than with CircuitPython also. this will be explained next when we create a MicroPython program for Crickit.

The Seesaw Driver

To use the CRICKIT with MicroPython, you will need the Adafruit seesaw.py driver code loaded onto the board in addition to your user program named main.py.

The seesaw driver code is below. You can use the Download function to put it on your computer. The best location to download seesaw.py depends on your operating system. 

Place the file seesaw.py into your mu_code folder, which might be in:

  • C:\Users\YourUserName\mu_code on Windows
  • /Users/YourUserName/mu_code on macOS

Putting it in the mu_code folder makes it much easier to copy the files onto the micro:bit on the next page.

# Adafruit Seesaw / CRICKIT driver for MicroPython
# MIT License by Adafruit Industries Limor Fried
# Copy onto the micro:bit with main.py using Mu Files icon
from microbit import i2c
import struct
import time

_SIGNALS = (2, 3, 40, 41, 11, 10, 9, 8)
_PWMS = (14, 15, 16, 17, 19, 18, 22, 23, 42, 43, 12, 13)
_SERVOS = (17, 16, 15, 14)
_MOTORS = (22, 23, 19, 18)
_DRIVES = (13, 12, 43, 42)
_TOUCHES = (0, 1, 2, 3)
_ADDR = 0x49

reg_buf = bytearray(2)
pwm_buf = bytearray(3)

def _read(reghi, reglo, n, delay_s=0.01):
    reg_buf[0] = reghi
    reg_buf[1] = reglo
    i2c.write(_ADDR, reg_buf)
    time.sleep(delay_s)
    return i2c.read(_ADDR, n)

def _write(reghi, reglo, cmd):
    reg_buf[0] = reghi
    reg_buf[1] = reglo
    #print("sswrite: ", [hex(i) for i in reg_buf+cmd])
    i2c.write(_ADDR, reg_buf+cmd)

# t is between 1 and 4
def read_touch(t):
    return struct.unpack(">H", _read(0x0F, 0x10+_TOUCHES[t-1], 2))[0]

def pwm_write(pwm, val):
    pwm_buf[0] = _PWMS.index(pwm)
    pwm_buf[1] = val >> 8
    pwm_buf[2] = val & 0xFF
    _write(0x08, 0x01, pwm_buf)

def set_pwmfreq(pwm, freq):
    pwm_buf[0] = _PWMS.index(pwm)
    pwm_buf[1] = freq >> 8
    pwm_buf[2] = freq & 0xFF
    _write(0x08, 0x02, pwm_buf)

# signal is between 1 and 8
def analog_read(signal):
    return struct.unpack(">H", _read(0x09, 0x07+signal-1, 2))[0]

def pin_config(pin, mode, pull=None, val=None):
    if pin >= 32:
        cmd = struct.pack(">I", 1 << (pin - 32))
        cmd = bytearray(4) + cmd
    else:
        cmd = struct.pack(">I", 1 << pin)
    if 0 <= mode <= 1:
        _write(0x01, 0x03-mode, cmd)
    if pull is not None and 0 <= pull <= 1:
        _write(0x01, 0x0C-pull, cmd)
    if val is not None and 0 <= val <= 1:
        _write(0x01, 0x06-val, cmd)


def init():
    i2c.init()
    while not _ADDR in i2c.scan():
        print("Crickit not found!")
        time.sleep(1)
    reg_buf[0] = 0x7F
    reg_buf[1] = 0xFF
    i2c.write(_ADDR, reg_buf)

# s is between 1 and 4
def servo(s, degree, min=1.0, max=2.0):
    set_pwmfreq(_SERVOS[s-1], 50)
    val = 3276*min + (max-min)*3276*degree/180
    pwm_write(_SERVOS[s-1], int(val))

# d is between 1 and 4
def drive(d, frac, freq=1000):
    set_pwmfreq(_DRIVES[d-1], freq)
    pwm_write(_DRIVES[d-1], int(frac*65535))

# m is 1 or 2
def motor(m, frac, freq=1000):
    m -= 1  # start with 1
    pin1,pin2 = _MOTORS[m*2:m*2+2]
    set_pwmfreq(pin1, freq)
    set_pwmfreq(pin2, freq)
    if frac < 0:
        pin1, pin2 = pin2, pin1
    pwm_write(pin1, 0)
    pwm_write(pin2, abs(int(frac*65535)))

# signal is between 1 and 8, val is 0 or 1
def write_digital(signal, val):
    pin_config(_SIGNALS[signal-1], 1, 0, val) # output, pullup, value

# signal is between 1 and 8
def read_digital(signal):
    pin = _SIGNALS[signal-1]
    pin_config(pin, 0, 1, 1) # input, pullup, pullvalue
    ret = _read(0x01, 0x04, 8)
    b = 0
    if pin > 32:
        b = 4
        pin -= 32
    b += 3 - (pin // 8)
    return (ret[b] & 1<<(pin % 8)) != 0

Testing CRICKIT's Features

Connections

We can test connections using the parts in the diagram below. Feel free to omit anything you do not wish to control, this example shows testing a number of things to give you an idea what can be done.

Signals

Signal 2 to LED (long lead +), LED (short lead -) to GND (breadboard common ground)

Signal 7 to leg of switch, opposite diagonal switch leg to ground

Signal 8 to Potentiometer middle pin. Ground to one outer pin, 3.3V to the other outer pin.

Servo

Servo connected to Servo block port 1, darkest wires facing towards micro:bit slot

Motor

Motor connected to Motor port 1 (color connections do not matter)

Plug in the micro:bit and Power

The micro:bit unfortunately fits into Crickit in either orientation but only one is correct. See the board markings which says "Micro:bit LED grid facing this way" - ensure the micro:bit LEDs face the direction shown.

Use a 5 volt 2A power supply plugged into the barrel jack of the Crickit. Ensure the tiny switch next to the barrel jack is in the On position. The green LED on CRICKIT with the smiley face (shown below) shows that CRICKIT is happy with its power supply.

Do not try to power the Crickit through the micro:bit USB jack (but you can connect it to a computer for communications).
Do not try to power the Crickit through the micro-USB jack on the Crickit marked "Seesaw ONLY", that jack is not for power and it is very rarely used.

An Example: the Test Program

The following MicroPython program tests the CRICKIT and micro:bit:

  • The Motor drive
  • The Digital In on the Signals block
  • The Digital Out on the Signals block
  • The Analog In on the Signals block
  • Servo drive on the Servo block

The code also has a demonstration of the Drive block setting various levels not used here.

The following capabilities are currently not written into the seesaw.py driver:

  • Sound (this does not need a driver, use the standard micro:bit sound pin 0 to output sound to the CRICKIT amplifier).
  • NeoPixel control via micro:bit pin 16 (use the default micropython NeoPixel driver and use pin #16!)
  • Stepper motor control on either the Motor or Drive blocks. (We wanted to keep things simple)

Code

Click download to get the main.py file below via the tutorial GitHub repo. Save the file as main.py in your mu_code folder mentioned on the previous page.

# main.py - code to test the Adafruit CRICKIT board with
# the BBC micro:bit and MicroPython (NOT CircuitPython)
# MIT License by Limor Fried and Mike Barela, 2019
# This code requires the seesaw.py module as a driver
import time
import seesaw

seesaw.init()
while True:
    # Touch test - check with the Mu plotter!
    print("Touch: \n(", end="")
    for i in range(1, 5):
        print(seesaw.read_touch(i), end=", \t")
    print(")")

    # analog read signal test - assumes analog input pin 8
    print("Analog signal:\n(", end="")
    print(seesaw.analog_read(8), end=", \t")
    print(")")

    seesaw.write_digital(2, 0)  # Assumes LED on Signal pin 2
    time.sleep(0.1)
    seesaw.write_digital(2, 1)
    time.sleep(0.1)

    if seesaw.read_digital(7):  # Assumes button on Signal pin 7
        print("pin high")
    else:
        print("pin low")

    # Servo test - assumes servo on Servo position 1 on CRICKIT
    seesaw.servo(1, 0, min=0.5, max=2.5)
    time.sleep(0.5)
    seesaw.servo(1, 90, min=0.5, max=2.5)
    time.sleep(0.5)
    seesaw.servo(1, 180, min=0.5, max=2.5)
    time.sleep(0.5)

    # Drive test
    # seesaw.drive(1, 0.2)
    # seesaw.drive(2, 0.4)
    # seesaw.drive(3, 0.6)
    # seesaw.drive(4, 0.8)

    # motor test - assumes a DC motor on CRICKIT Motor 1 terminals
    seesaw.motor(1, 1)
    time.sleep(0.5)
    seesaw.motor(1, 0)
    time.sleep(0.5)
    seesaw.motor(1, -1)
    time.sleep(0.5)
    seesaw.motor(1, 0)

    time.sleep(0.1)

Moving the Code to the micro:bit

Click the Mu Files icon. Your files that are in your mu_code folder will show up to the right. Using your cursor, drag seesaw.py to the left pane. Then do the same for main.py. This will copy the files onto the micro:bit. 

The code should run. It might take a reset of the micro:bit and/or CRICKIT (both have reset buttons on them) to work. 

To use the REPL to see the output of the code, click the Files icon once more to close that window, then click the REPL button. The program output can now be viewed. If the code isn't running and you've reset the boards, press on the keyboard to do a soft reboot.

When you copy the files onto the micro:bit using Mu, they will NOT appear on the flash drive that appeared when the micro:bit was plugged into your computer. This is normal for MicroPython, you cannot see the files on the drive unlike CircuitPython.

Use

The program will continually be testing various functions as a demonstration. The LED will blink, the servo will turn, and the motor will turn on and off.

Values for the capacitive touch pads, the potentiometer, and the status of the switch will be printed out in the REPL window.

This guide was first published on May 15, 2019. It was last updated on May 15, 2019.