From Badge team
Jump to navigation Jump to search

If your badge has been hit by ransomware, see how to enter Safe mode.


On this page you'll find all the hints, tips, datasheets, secret codes and assorted stuff you'll need to hack the SHA2017 Badge!

Badge presentation

Please see the talk (slides) we gave during SHA for a nice overview on how we managed to pull this project off.

Before the event

You can try out some micropython using the Badge Emulator

Getting started!

Please remember the badge project is a huge volunteer effort - please approach it as a hacker, not as a consumer :). Lots of things can still be improved, and your help is much appreciated! This still holds true August 2019!

Just got your badge and want to get going?

Safe mode

If you can no longer boot your badge due to accidental or malicious software on your badge, don't panic. Recent firmware has a Safe Mode, which you can use to uninstall broken or malicious software. Press the Reset button (on the back) while holding the Start button (on the front). Keep holding the Start button while the badge boots up. It should be obvious that it is now in safe mode. Installed software will not be able to start services or execute any code until started from the launcher. The badge will not go to sleep. This will drain the battery, so only use it for as long as you need to in order to remove the problem application. Then press the Reset button once again (without holding the Start button) to return to normal operation.

If this doesn't work, you may not have recent enough firmware. In which case, go to the Badge Bar and use our automated reflashing station (which will lose all your applications and settings) and then update to the latest firmware over the air. If you can't get to the Badge Bar or you have left the event already, follow the instructions further down on how to check out the firmware from github and reflash it yourself.





  • Screenprotector?
  • 3D printable case case
  • Laser cut case

Expansion Boards

Repository of scarves

  • Proto-board
  • At-least one more project in the works . .
Expansion port


  • Weatherproofing? Nailpolish seems to do the trick. Switches on the back will probably be unusable after applying it...

Plastik70 from Kontakt Chemie works ok (cover switches, USB and SD card slot with tape before spraying it)


Currently we have three flash-able Firmware flavours . .

For the SHA2017Badge/MicroPython firmware we also have an Emulator to try out some code before you put it on your badge.


TLDR: Clone and follow the instructions there to flash a new version.

Interacting with the badge

You can use your favourite serial terminal client or user the builtin monitor.

make monitor

Close using CTRL + ]

An alternative is to use screen.

screen /dev/ttyUSB0 115200

Close using CTRL + a :quit

On MacOS-based systems you might need to install an USB to UART bridge VCP driver from first before you can connect to the badge:

screen /dev/tty.SLAB_USBtoUART 115200

Close using CTRL + a :quit

Installing on non Debian-based systems

For specific issues read the ESP-IDF Windows Setup Guide Mac OS Setup Guide or Linux Setup Guide

Compiling and using the Badge Emulator

For the SHA2017-specific firmware, not (yet) for the generic firmware.

To use the emulater, you must first build it:

cd micropython/unix

To get an interactive shell:


To start a .py file:

./micropython <filename>.py

Using Micropthon

For the sha2017-specific firmware, connect to the badge with a micro USB cable and use your favourite serial client, we recommend To switch to a 'clean' environment without sleep timers, open the micropython REPL by entering 'repl' on the mpfshell shell and execute 'import shell'.

For the generic firmware, this will not work, and you should use ./

This example code displays some graphics and text.

You can enter the program below, line by line on the serial client. Or you can create a file named, and follow the upload instructions below.

import badge
import ugfx



ugfx.thickline(1, 1, 100, 100, ugfx.WHITE, 10, 5), 30, 50, 50, ugfx.WHITE)

ugfx.string(150, 25, "STILL", "Roboto_BlackItalic24", ugfx.WHITE)
ugfx.string(130, 50, "Hacking", "PermanentMarker22", ugfx.WHITE)
len = ugfx.get_string_width("Hacking", "PermanentMarker22")
ugfx.line(130, 72, 144 + len, 72, ugfx.WHITE)
ugfx.line(140 + len, 52, 140 + len, 70, ugfx.WHITE)
ugfx.string(140, 75, "Anyway", "Roboto_BlackItalic24", ugfx.WHITE)


Read more at the MicroPython and modules page.


To talk to the e-ink display, the high-level uGFX library that comes with the firmware is the easiest way to get started. A more low-level API is available under components/badge/badge_eink.h if you need it (e.g. for advanced hacks like greyscale imagery).

Creating your first app

Developers can easily create their own MicroPython apps which we refer to as eggs, and to get you started we've produced a tutorial in which you'll create a Hello World egg.

Once you have become familiar with the basics of egg development, there is a a MicroPython badge API reference.

Publishing eggs can be done on the hatchery at, or directly to the badge itself via USB if you are not ready to share your code with the world. We have a step-by-step guide to USB deployment for first-time developers which should allow you to get your egg working on your badge.

Your egg has to contain a file called "". This is the file that is opened whenever someone starts your app from the launcher.

It is possible to use a separate file as your main application by putting "from <APP_NAME> import <FILE_NAME>" where you replace spaces with underscores (_). For example "my awesome" becomes "my_awesome_program".

Should you want to run background tasks while the user is not using the badge you can add a file called "" to your app. More information about services can be found in the next section.


What is a service?

A service is a small program bundled with an app which allows apps to execute background tasks while the badge shows the splash / home screen.

How can I create a service?

A service is a small program included with an app as a separate Python file, from which a couple of functions are executed. The file should be called “” and it should be bundled with your app files. Please do not put any globally placed code in this file. Instead place you code in functions!

To use services you also need a service descriptor called "service.json". This is an example for such a file:

   "wifi": {
   "rtc": false,
   "loop": true,
   "draw": false


- apiVersion: always set this to 2, other values will cause badges to ignore your service
- wifi(setup/loop): set to true if you only want your service to run whenever wifi is available
- rtc: set to true if your app needs the RTC to be configured (set to the correct date/time)
- loop: set to true to enable execution of a loop() task (you can also add your own tasks to the scheduler, see the "virtual timers" section
- draw: set to true to include your service in the draw loop

What does a service script look like?

Each service script contains three functions: setup, loop and draw. Each of this functions is called by the splash application at different moments.

void setup( void )

The setup function is called directly after wakeup and is to be used to initialize the service.

next loop()

The loop function of your service is ran as a task in the "virtual timer" scheduler. The return value of this function determines the time until the next time it executes (in milliseconds). The function may be called sooner than the chosen time though.

About sleeping: Please keep in mind that the badge should sleep as much as possible to avoid draining the battery. Any value less than 30000 causes the badge to stay awake. For apps that don't need to stay awake we suggest sleeping at least 5 minutes to allow the background updates to function correctly.

[next, height] draw( y, sleep=2 )

This function is called just before the screen is updated and allows your service to add information or widgets to the homescreen. The x and y coordinates provided to you are the location of the bottom-left corner of the location designated to your service. You may use the full width of the screen. The return value should be set to the amount of pixels used by your information string or widget. The next widget will be drawn upwards from coordinate (x+height, 0).

Should you decide not to use the location appointed to you then please return 0. Also note that conflicts between multiple services can occur if you place your content at an arbitrary place on the screen. Because of this I suggest you to never do that. Unless of course the purpose of your app is overriding existing elements like the nickname.

The "next" return value should be set to the amount of milliseconds before a redraw is needed. This is at least 1000ms and may in some cases be more than your chosen value.

The sleep argument, if present, must have a default value set. Otherwise it will not work on older firmware. It will be True if this draw is just before going to sleep, or False otherwise. Older firmware does not supply this argument.

NVS settings

Category Key Type Allowed values Default value Description
badge wifi.ssid String SHA2017-insecure SSID of WiFi network
badge wifi.password String Password of WiFi network
badge setup.state u8 0, 1 and 2 0 Setup state:

0 = Setup not completed 1 = Setup completed, show sponsors 2 = Setup completed

owner name String Nickname shown on the splash screen
splash header.invert u8 0 and 1 0 Invert color of header
splash header.hws u8 0 and 1 0 Hide header while sleeping
splash header.hbws u8 0 and 1 0 Hide battery while sleeping
splash sleep.duration u8 30 - 255 60 Duration of deep sleep between wakeups in seconds
batt vmin u16 3500 Battery voltage when empty in mV
batt vmax u16 4100 Battery voltage when full in mV
splash bat.volt.drop u16 5200 Since we are measuring the voltage of the LiPo after a polyfuse, we need to calibrate the battery readings a bit that the splash screen shows. Offsets from 5200 will result in offsets in the splash. This should automatically calibrate when the badge stops charging.
splash ntp.timeout u8 40 Amount of times the badge will try to connect to the WiFi network to set the RTC
splash bpp.count u8 5 Amount of wakeups from deepsleep that will trigger the BPP system to be started
splash timer.interval u16 500 Interval of service loop timer in ms
splash timer.amount u8 10 Amount of times the timer loop will execute before the badge goes back to sleep