Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


This is the official public repository for a battery-free prototyping platform with CircuitPython for the Adafruit Metro M0 Express. This repository contains all the sources needed to get started using CircuitPython without any batteries!

Project Overview


Batteries are bad for the environment, and many embedded applications do not rely on a constant flow of energy. However, just connecting an energy-harvesting source to a microcontroller does not fully solve the problem. Energy from harvested sources is not constant and maybe not enough to continuously run the device, so we have to buffer some energy (typically in a capacitor). When a certain amount of energy is collected, the system activates for some seconds.

It would be problematic if the program would start from the beginning every time the system restarts. Going into a sleep mode might also be problematic, as you never know when the energy returns.

This work focuses on continuing a Python application where it left off when the system restarts after a power failure, called intermittent-computing We achieve this without any involvement from the user or any modifications to the Python code!

All the magic happens internally in our modified version of the CircuitPython interpreter (added as a submodule in software/BFree-core), which works together with our BFree shield. Everything is entirely open-source and accessible through this GitHub repository.

The above figure presents: (A) the BFree hardware shield; (B) example Python code executed on the Adafruit Metro M0 Express board with the BFree shield; (C) the BFree shield with Adafruit Metro M0 Express board running a battery-free temperature measurement station; (D) the BFree system in the wild.

How it works

For the user (maybe you!), the intermittent-computing aspect is entirely invisible. Internally, the modified CircuitPython interpreter communicates with the BFree shield and decides when to make a so-called "checkpoint." A checkpoint is a snapshot of the program at that point. When the system runs out of power and eventually starts back up, this is the point where the program will resume. The system always continues from the last successful checkpoint. A checkpoint is created by sending the state of the interpreter (such as the current position in the program, the value of the variables, the state of the peripherals, etc.) to the BFree shield, which stores it in non-volatile memory (FRAM). For more details, please check out the complete paper here.

Getting Started

To ditch all the batteries for your next CircuitPython project using BFree you need five things:

  1. An Adafruit Metro M0 Express board
  2. A working BFree shield programmed with the software in software/nvm-controller.
  3. A build of the modified CircuitPyhton interpreter BFree-core)
  4. An energy harvesting source (such as a small solar panel)
  5. A buffer capacitor

The BFree shield is a simple shield-like PCB that mainly holds an MSP430 microcontroller onboard FRAM for non-volatile storage and energy harvesting circuitry. The modified CircuitPython interpreter (BFree-core) can be built and uploaded the same way as the vanilla CircuitPython. For this, we would like to refer you to the excellent CircuitPython build instructions. Don't forget to use instead of

Building the Hardware

All the EAGLE design files and a component list needed to build the BFree shield are availible in (hardware/BFree-shield)[hardware/BFree-shield].

Building the BFree Shield Software

The BFree shield sofware is build using MSP430-gcc. To build it install the msp430-gcc toolchain in /opt or change the msp430-toolchain.cmake file to point to the toolchain. Navigate to software/nvm-controller/; then it's as simple as running:

$ ./configure
$ cd build && make

And an elf file named NVM-Controller.elf will be generated in software/nvm-controller/build/ which you can upload to the BFree shield using an MSP430 programmer, or using a MSP430 LaunchPad.

Building the BFree Core Software

Note: BFree Core has to be compiled using arm-gcc version 9! (not any higher version), this is due to a limitation in the original CircuitPython project To build the BFree version of CircuitPython, navigate to BFree-core and execute the following.

$ git submodule update --init --recursive
$ cd ports/atmel-samd
$ make BOARD=metro_m0_express

A firmware.uf2 file will be generated in ports/atmel-samd/build-metro_m0_express/ which can be uploaded to the Metro M0 Express board by flashing it using the UF2 Bootloader.

Note that this is Beta software, so it's recommended to only flash BFree core if you also own a J-Link programmer to recover the device if a bug occurs that prevents the system from entering the bootloader mode!

How to Operate BFree

Just like a regular Metro M0 Express with CircuitPython!

There is just one caveat when using peripheral devices (such as a sensor) that have a state that is reset when the system reboots. BFree can not know this, it will restore the peripheral interface (such as SPI), but it will not reinitialize the device. Therefore the only change you need to make to your Python code if you have such a peripheral is to add the reinitialization just before the usage of the device. An example of this can be seen in the LoRa application

List of Known Issues

List of all known issues is listed in the Issues list of this project. If you found a bug or you would like to enhance BFree: please contribute - we look forward to your pull requests!

How to Contribute to this Project

We look forward to your contributions, improvements, additions and changes. Please follow the standard GitHub flow for code contributions. In macro terms this means the following.

  1. Fork the master branch of this repository; make sure that your fork will be up to date with the latest master branch.
  2. Create an issue here with a new feature or a bug report.
  3. Perform changes on your local branch and push them to your forked clone.
  4. Create a pull request referencing the issue it covers and wait for our response.

Frequently Asked Questions

How to Cite This Work

The results of this project have been published in a peer-reviewed academic publication (from which all technical figures in this file originate). Details of the publication are as follows.

To cite this publication please use the following BiBTeX entry.

author = {Kortbeek, Vito and Bakar, Abu and Cruz, Stefany and Yildirim, Kasim Sinan and Pawe\l{}czak, Przemys\l{}aw and Hester, Josiah},
title = {BFree: Enabling Battery-Free Sensor Prototyping with Python},
journal = {Proc. ACM Interact. Mob. Wearable Ubiquitous Technol.},
year = {2020},
month = dec,
volume = {4},
number = {4},
articleno = {135},
numpages = {39},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {}


This research project was supported by Netherlands Organisation for Scientific Research, partly funded by the Dutch Ministry of Economic Affairs and Climate Policy, through TTW Perspective program ZERO (P15-06) within Project P4, and by the National Science Foundation through grants CNS-1850496, CNS-2032408 and CNS-2038853. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

BFree was designed at Northwestern University in the US and Delft University of Technology in the Netherlands, whose both support is also greatly acknowledged.


Copyright (C) 2020-2021 TU Delft Embedded and Networked Systems Group/Sustainable Systems Laboratory.

MIT Licence. See license file for details.