O'Reilly logo

Programming with MicroPython by Nicholas H. Tollervey

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 4. Adafruit Circuit Playground Express

Star Trek is one of my favourite science-fiction universes.

Upon reflection, a big reason for its appeal is that Star Trek’s fictional technology is generally a force for good. It facilitates progress (technology is used to help others), a humane and open-minded outlook (technology allows characters to live, work, and communicate with each other despite physical, physiological, and cultural differences), and fearless exploration of our universe (they fly around in spaceships!).

One of my favourite Star Trek technologies is the “tricorder,” a device used by Mr. Spock, Bones, and others to sense the environment, make computations, and react to things with flashing lights or strange chirruping noises that obviously make perfect sense to citizens in the 23rd century.

I’ve often thought it’d be cool to own such a device.

With Adafruit’s Circuit Playground Express, my dream has come true. Even better, it’s fun to imagine Mr. Spock programming such a device in Python.

The tricorder is a classic example of an enchanted device, although not for magical reasons. The imagined technology of the 23rd century is so advanced to our primitive eyes that we react to it in the way Arthur C. Clarke suggests: it’s indistinguishable from magic. The Circuit Playground Express is the antidote to such misplaced wonderment. Because it is tricorder-ish, it’s packed full of sensors and modes of feedback. It lives up to its name: it’s a playground for quickly learning about how embedded devices work so you too can explore strange new worlds, seek out new life and new civilizations, to boldly go where no Python programmer has gone before!

It is because of the hard work of Adafruit, who make embedded development fun and a source of wonder, that Python programmers can emulate Spock, Bones and those personnel in the red uniform that always get shot while on planet-bound expeditions.

As with the previous boards, there are two ways to interact with the device: via code stored on the onboard flash filesystem and via the REPL.

As before, when you plug the device into your computer via a micro USB cable, it’ll appear as a flash storage device, and you gain access to the REPL in exactly the same way as with the PyBoard and micro:bit.

The Hardware

There are two versions of this device: an older version based upon the ATmega32u4 microprocessor that’s not capable of running MicroPython, and the more powerful, newer version that uses the ATSAMD21G18 ARM Cortex M0 microprocessor. It is this latter version that we will be using in this book.

Just like a Star Trek tricorder, the Circuit Playground Express is packed full of input (sensing) and output (signalling) features. In Figure 4-1, if you look at the side of the board with the components on it, you’ll see they’re labelled and sometimes given names.

A picture of Adafruit's Circuit Playground
Figure 4-1. Adafruit’s Circuit Playground Express is packed full of inputs and outputs.

If you hold the device with the components facing towards you and with the micro USB port at 12 o’clock, you’ll notice a green LED immediately to the socket’s left. Around the edges are 14 pads that make it easy to connect the device to other stuff via alligator clips. Each pad is labelled (for example, some are power-related pads labelled 3.3 V or GND). Those pads not related to power are capable of capacitative touch sensing (i.e., just like the micro:bit’s pins 0, 1, and 2, they detect if they have been touched).

In the six o’clock position is the power connector into which you can provide between 3.5 V to 6.5 V DC. The board automatically regulates such voltage down to 3.3 V. The power connector works especially well with a 3 x AAA battery holder, although other options, such as lithium ion or lithium polymer batteries, could be used.

Just within the pads are 10 NeoPixel LEDs. These are extraordinarily cool since you can assign each LED an RGB colour and light it up. That’s over 16 million shades of colour, so you can make blinkenlights on steroids! These NeoPixels are a great way to indicate status: red for danger, green for safety; throbbing slowly to indicate peace, flashing quickly for urgency. The NeoPixels are assigned numbers from 0–9, with position 0 to the left of the USB port and below the power LED, with the other positions counting up in an anti-clockwise direction.

In the central area of the device are three push buttons labelled A, B, and RESET. The A and B buttons are used for arbitrary on/off user interactions, whereas the reset button obviously reboots the board.

There’s also a slide switch just above the battery connector (at six o’clock). It has a small nub to move to the left or right. Once in a certain position, it remains in that position (in contrast to push buttons that are only “on” when they’re pressed down). Just like the buttons, the slide switch is used to indicate arbitrary on/off user input but whose state must remain persistent.

On either side of the reset button are devices for working with infrared light: a transmitter (on the left) and receiver (on the right). This allows the device to communicate with other Circuit Playground Express boards in line of sight and within range. Put simply, communication works in the same way as your TV remote control.

There are lots of environmental sensors on the board. Just above button A is an analog light sensor that can be used to measure the brightness of the ambient light. Just above button B is a thermistor, a sort of resistor that changes its resistance depending on the ambient temperature, thereby allowing the temperature to be measured. Between the infrared transmitter and receiver and just below the reset button is a three-axis accelerometer that allows the measurement of the gravitational force applied in X, Y and Z directions. Consequently, not only can gravity be sensed but also tilt, motion, and gestures. Below button B is a small microphone to detect audio levels by turning sound waves into electrical signals that we can, in turn, measure.

That’s quite a lot of ways for the device to sense its environment!

Another component that is useful for output is just below button A. The very small black box is actually a miniature speaker. The Circuit Playground Express wouldn’t be like a tricorder without the ability to make bleeps, bloops, and whistles for signalling status. It’s also possible to play very simple melodies, although don’t expect great audio quality, since it sounds like one of those annoying bleeping birthday cards.

Finally, in case you were wondering, the ATSAMD21G18 microcontroller is the chip just above the reset button. It runs at 48 MHz with 256 KB of onboard flash memory and 32 KB of RAM. The board also has a hefty 2 MB of additional flash memory storage.

Of all the boards covered in this book, the Circuit Playground Express has the most diverse and immediately available onboard input and output capabilities. As the name suggests, it’s a great platform for playful sensing, detecting, and feedback—just like a tricorder.

Developer Setup

Adafruit uses a fork of MicroPython called CircuitPython.1

CircuitPython is developed as free software by Adafruit, and it welcomes contributions from the wider community. It tracks the major releases of MicroPython rather than following everything on the upstream MicroPython master branch. Work is ongoing and marked as “beta”, meaning most APIs will be stable if not bug free. Adafruit makes a number of MicroPython-capable boards; and by using CircuitPython, it’s able to ensure that the APIs remain consistent across its range of devices. If you learn to program the Circuit Playground Express with CircuitPython, then you’ll be able to transfer your skills and knowledge to any other Adafruit board that runs CircuitPython.

The Circuit Playground Express may not come with CircuitPython flashed onto it. Also, given the ongoing development of the project, you should flash the latest version of the CircuitPython firmware onto the device in order to get the latest bug fixes and features.

It’s very easy to update the Circuit Playground Express thanks to a bootloader called UF2. You simply put the device into bootloader mode then drag .uf2 files onto the device.

At time of writing, the builds of CircuitPython for all Adafruit’s boards are created as releases on GitHub. You’ll need to download the latest UF2 version for the Circuit Playground Express.

To put the device into bootloader mode, connect it to your PC and double-tap the reset button. Once the bootloader is active, the small red LED will fade in and out, the onboard NeoPixels will turn green,2 and the device will show up as a USB mass storage device called CPLAYBOOT.

Copy the .uf2 file onto the drive, and, once complete, restart the board. It should reappear as a USB mass storage device called CIRCUITPY.

That’s it! If you encounter any problems, or you want to explore other ways to update the device, check out the comprehensive instructions on the Adafruit website.3

The final (optional but recommended) step is to copy the Adafruit CiruitPython drivers bundle onto the device. It provides useful CircuitPython libraries for interacting with the hardware. The libraries are of two sorts: foundational (used to provide critical functionality) and drivers (built on top of the foundational libraries to provide access to sensors and other peripherals). The latest release of the bundle can be downloaded from the project’s GitHub repository. Copy the contents of the downloaded ZIP file onto the device and import the modules as you would any Python library.

Just as with the PyBoard, when you plug the device into your computer, you will see it as a USB mass storage device. If you create or update the main.py file on this filesystem, the code therein will be run on startup.4 Connect to the Python REPL on the device in exactly the same way as with the PyBoard.

The following REPL-based example makes the red LED labelled D13 toggle twice a second:5

>>> from board import D13
>>> import digitalio
>>> import time 
>>> led = digitalio.DigitalInOut(D13)
>>> led.switch_to_output()
>>> while True:
...     led.value = not led.value
...     time.sleep(0.5)

As with all versions of MicroPython, use CTRL-C to interrupt the infinite loop at the end of the preceding example.

Congratulations, you have the Circuit Playground Express set up and ready to go! We’ll cover how to make use of the board’s many features in later chapters. The documentation for CircuitPython can be found at https://circuitpython.readthedocs.io/.


If you’re feeling adventurous, you could build CircuitPython from source in order to get the bleeding-edge fixes and new features.

The source code for CircuitPython is hosted on GitHub and is labelled as a fork of the main MicroPython repository. Clone the CircuitPython repository and ensure that you have the gcc-arm-none-eabi compiler installed on your machine. How you do that is down to your operating system and beyond the scope of this book, although it should be relatively simple if you use a package manager to install the compiler.

Assuming that you have the compiler toolchain and the source code, drop into your operating system’s shell. Change the directory into the atmel-samd subdirectory of the repository that you just cloned. Next, use the familiar make command to build the firmware:

make BOARD=circuitplayground_express

The board related argument identifies the Circuit Playground Express’s microprocessor as the target. If the build is a success, you’ll find a firmware.bin file in the build-cplay_m0_flash subdirectory.

This file needs to be converted to the uf2 format with a utility created by Microsoft and hosted on GitHub. Simply pass in the path to the firmware.bin file and use the -o flag to specify the output name. The following Linux based example is typical:

$ ./uf2conv.py firmware.bin -o firmware.uf2
Converting to uf2, output size: 410624, 
  start address: 0x2000
Wrote 410624 bytes to firmware.uf2.

It is the firmware.uf2 file that must be copied onto the device as per the earlier instructions.

1 In software, a fork is when developers take a copy of the source code from one project and start independent development that doesn’t get merged back into the original project.

2 If the NeoPixels turn red, then the bootloader couldn’t start. Try another USB cable.

3 If you find yourself using an Adafruit device that isn’t part of the Express family of boards, you’ll have to use a command-line utility called bossac to update CircuitPython. This is fully explained on the referenced web page.

4 CircuitPython also allows you to use the name code.py as an alternative to main.py.

5 Remember, Python’s time.sleep function uses seconds to measure duration.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required