Badger 2040

A nearly-3 inch E-Ink display bolted onto a Raspberry Pi 2040 with 5 buttons, a LED, and 2 MB of RAM, made by Pimoroni. It can run on battery or USB power, and has ports and pads you can attach things to.

Where to get it


Useful Docs


Command line access

Use MicroPython's mpremote:

  • Note that you can't use this and Thonny at the same time.
  • There doesn't seem to be a way to mount a folder on the Badger and edit/copy things on it, but you can do the reverse. So the workflow is going to have to be:
    • Write code
    • Run build script
      • Script copies files to Badger and resets it, then opens console
# get a console on the device
# list files at the root folder
mpremote ls


  • [ ] Use mpremote to construct a Makefile or Rakefile deploy toolchain to the Badger.

Using Thonny

Ubuntu Setup

I used pipx to install Thonny locally, and I had to add my user to the dialout group since Badger 2040 was mounting on /dev/ttyACM.

First steps

Turn off the simplified interface. You can barely do anything in this interface beyond the basics.

File Management

There's no rename on the Badger 2040. Name your file correctly, go into the directory in Thonny's file browser (don't just flip it open), and Upload the file from your computer.

While Badger 2040 is plugged in

The dev cycle I've been using is:

  • Reset connection to Badger 2040 using Thonny Stop/Restart.
  • In the console, run import launcher.
  • Do stuff until it crashes. You can get print statements and exceptions in the console.

If you're not using the default launcher, use import <filename minus .py>.

Targeting a single file

This seems to be a smoother approach:

import sys
del sys.modules['<filename minus .py>']
import <filename minus .py>

This means you can skip import launcher and target just your program.


Badger 2040 has its own version of JPEGDEC for decoding JPEGs on Pi 2040 devices:


Decoding goes directly to the display:

import jpegdec
import badger2040
display = badger2040.Badger2040()
jpeg = jpegdec.JPEG(display.display)
jpeg.decode(x_target, y_target)

Saving compatible JPEG graphics

GIMP on Linux by default will not make graphics the JPEG parser MicroPython on the badge likes. Run them through ImageMagick, then upload them to the badge. No other conversion needed, just in and out:

convert image-orig.jpg image.jpg

Activity LED

All the docs say you can change the Activity LED's state but neither the REPL nor the actual code that ships with the Badger 2040 seem to be able to do that:


You're very likely going to be modifying the files in examples to start. This means you'll be using the Launcher that comes with the Badger 2040 firmware.

Data Formats

You get JSON reading, no YAML.


You can't use the streaming JSON interface since opened files in MicroPython aren't streamable. Read the file into memory, then parse it:

with open("my_file.json", "r") as file:
  data = json.loads(

Where is "Push A and C to Exit Launcher" controlled?

This is in (

Running a timer or a clock

Extracted from

import time
import machine
import badger2040
except RuntimeError:
rtc = machine.RTC()
# set the clock to a reasonable default value
year, month, day, wd, hour, minute, second, _ = rtc.datetime()
if (year, month, day) == (2021, 1, 1):
    rtc.datetime((2022, 2, 28, 0, 12, 0, 0, 0))
while True:
    # get the clock value
    year, month, day, wd, hour, minute, second, _ = rtc.datetime()
    # do stuff here
    # avoid updating the display unless you absolutely have to!
    # even fast updates are costly