Unofficial fan project. Not affiliated with or endorsed by SAINTCON or UtahSAINT.
LCD Closeup (ST7789V 240Γ320)2Γ (480Γ640)
Towers (11 IR Stations)
Touchscreen badge: tap or drag directly on the badge LCD. Click a tower below to walk up to its IR beacon:
Tap the badge screen to register a handle, then click any tower above to receive its IR beacon.
5-Way Joystick (SW2)Hold or Tap
Move: ββββ or WASDβ’Center: Enter / Space / E
Incidents Companion
Plug virtual I2C minibadges into the 4 PCB slots (U9, U10, U13, U14) for gear buffs, or send solo IR beacons:
First boot: use β/β + A (Z / Enter) to choose a class, avatar, and handle on the badge.
Badge Config Web Page (www/)
In WIFI CONFIG mode, the badge starts its own Wi-Fi AP and serves www/ via microWebSrv. Form posts route directly into the running MicroPython firmware:
AP Offline β press SELECT β DOWN Γ2 ("WIFI CONFIG") β SELECT on the badge (takes ~4s), or click Start WIFI CONFIG.
http://192.168.4.1/200 OK
Minibadges (I2C2 Bus)
main.py polls 5 I2C2 addresses (SCL=22, SDA=21) and sends brightness (0x02) + HC score (0x01) to 0x29..0x42:
Plug in one or more virtual minibadges above to watch live I2C2 brightness, score, and status polls.
Lock, NFC & Solo Trade
Menu: spin the dial (drag ring or A/D) and let go to open a scene.
Combo / Build: pull shackle (Z/Space) to check a dialed code or build a ready module.
Trading:A/D picks a part, W/S sets count; trades run automatically.
Game: steer with the dial.
Press Back (SW3, X/Esc) to return to Menu.
Lock Shackle & Shim Sensors
Registration & vCard (ST25R95 Tag)72 / 159 bytes
Virtual NFC Unlock Tags (Read Tag Scene)
Solo "Museum Bot" Trade (Trading Scene)
Trading needs at least 1 part β earn parts from rewards (e.g. Insert Shim, a combo, or a tag).
Virtual I2C Minibadge (0x28)
Unregistered badges boot to Ready for VCard Programming β click Write Registration vCard above to unlock the main menu.
Enigma, Plugboard & Challenge
At-Home Challenge: open the upstream
Code Sheet.pdf
and
Saintcon2019BadgeChallenge.pdf
(plus Badge Instructions.pdf).
From DIRECTIONS:, press S then K to open ENIGMA EMULATOR, which walks through 5 setup screens (K advances each step): Machine (A=3 / D=4 Rotor), Set Rotors (A/D picks slot, W/S sets 1β9 or BETA/GAMMA), Set Rings (A/D picks slot, W/S sets AβZ for 01β26), Start Pos. (A/D picks slot, W/S sets AβZ), and Plugboard (wire jumper pairs below, then press K to start encoding). Type the ciphertext on AβZ to decode.
Scene Exit / Save: in Enigma Emulator (and Rotor Settings), hold any key 3 seconds to go back. In Games (Snake), steer with WASD and press K to exit. In Challenge Info, envelopes unlock at levels 1, 5, 9, and 13: from EXIT, press W to jump to the newest unlocked envelope, use A/D to move left/right between unlocked envelopes, press K to scroll the selected envelope's message, or press S then K on EXIT. In Custom Message, use W/S (char), A/D (cursor), O (backspace), and K to save & exit. In Minibadge Control and Exit Menu (Animations), use W/S to cycle and K to return to Menu.
Enigma Note: in 3-rotor mode with rotors IβVIII this matches a real three-rotor Enigma, except that the firmware's middle rotor can step twice if you start on both notches (e.g. rotors I II III at AEV β BGW instead of BFW). Its 4-rotor mode (thick reflector B + Beta/Gamma) and rotor IX are its own, not a real M4 or real rotors.
Plugboard Jumper Wires (J3 / J4)0 / 10 wires
Click or tap two letters to connect them with a jumper wire; click a wired letter to remove its wire. Run Factory Test runs the build-table test: press every key AβZ, Reset Badge returns, and your progress is kept.
Minibadge & UART Chain
I2C2 minibadges: none attached (MINIBADGE CONTROL sets OFF, ON, or Pattern 1β4 in EEPROM). UART1 side headers run in standalone at-home mode (all 9 messages and ring animations unlock directly on the badge).
Ready β use W / S + K to open ENIGMA EMULATOR, GAMES (Snake), CHALLENGE INFO, CUSTOM MESSAGE, MINIBADGE CONTROL, or EXIT MENU (Animations).
LED Board Controls
Button SW1 (PB2) & Boot Pad (TP1 on PB0)Mode 0: Ring
8-LED Binary Aid (D1..D8 on PORTA)PORTA = 0x00
0D1Β·b7
0D2Β·b6
0D3Β·b5
0D4Β·b4
0D5Β·b3
0D6Β·b2
0D7Β·b1
0D8Β·b0
Front vs. back LED positions (KiCad Saintcon2020MainBoard.kicad_pcb):Front (F.Cu):D1 (PA0, top-right), D2 (PA1, bottom-right), D3 (PA2, bottom-left), D4 (PA3, top-left).
Back (B.Cu, mirrored as seen when turning the board over):D5 (PA4, top-left), D6 (PA5, bottom-left), D7 (PA6, bottom-right), D8 (PA7, top-right).
No file in the repository specifies an LED colour (every schematic/PCB value is LED), so they are drawn in neutral warm white.
How bytes map to LEDs: one letter is one byte (D1..D8 above are ordered MSB b7 to LSB b0). In main.cpp:499-506, every non-zero byte in messages[8][19] has its top bit (0x80) set, and the loop at main.cpp:526-532 (for (int x = 0; x < NUMLEDS - 1; x++)) writes bits 0..6 onto LEDS[7 - x] (D8..D2), leaving LEDS[0] (D1) at 0 (0x00 marks the end of a message).
Test Pads TP1 (PB0) & TP2 (PB1)TP1 pull-up=OFF (0 pulses since reset) β’ TP2=LOW
Because //DDRB |= 1<<TP1PIN; is commented out at main.cpp:89, TP1 (PB0) stays an input; the PORTB |= 1<<TP1PIN; and PORTB &= ~(1<<TP1PIN); code at main.cpp:385-401, 540-556 only toggles the internal pull-up resistor on input TP1 (1..8 times for modes 0..7 before pausing). TP2 (PB1) is configured as output low at boot (main.cpp:87) and is never pulsed. LONGPRESSTIME and set_sleep_mode(SLEEP_MODE_PWR_DOWN) are configured at boot (main.cpp:29, 77-79), but the firmware never calls sleep_mode() or sleep_cpu().
KiCad Boards & Minibadge Holders
The upstream README.md states that the badge holds 17 minibadges (+V and GND power only β no communication lines). In Hardware/, MinibadgeHoldersPanel.kicad_pcb has 13MinibadgeHolder plus 4MinibadgeHolder90 boards; Saintcon2020MainBoard.kicad_pcb has 7 slots, Saintcon2020VerticalBoard.kicad_pcb has 6 slots, and Saintcon2020HorizontalBoard.kicad_pcb has 4 connectors. Some footprints in the .kicad_pcb files carry the Saintcon2020Ball: prefix.
Links: Upstream Repo β’
assembly video β’
Minibadge Tutorial videos:
Part 1,
Part 2,
Part 3.
Minibadge Notice: This is the HITB Minibadge 2017 (HITBUTT_Minibadge/HITB_Test.ino), a conference minibadge β not the main 2017 SAINTCON badge. The main 2017 badge's firmware is not in this repository.
Capacitive Touch Pads (ADCTouch on A3 & A2)value0=0 β’ value1=0
Press and hold either pad directly on the board picture, use the hold buttons below (or keys 1/A and 2/B), or hold both together:
If you press Reset while holding a pad, that pad reads as resting until the next Reset with it released, as the sketch sets its rest value at boot.
No save data needed:HITB_Test.ino calibrates ref0 and ref1 in setup() and does not read or write EEPROM.
Links: HITBUTT_Minibadge/ β’
MinibadgeTutorial/.
Stand-in Kiosk (Museum Companion) Clue Notepad
USB Bootloader Active: The badge is waiting for a firmware file in the RP2040 ROM USB bootloader and all 52 LEDs are off. Click Reset Badge to leave the bootloader and start the notepad.
Stand-in Kiosk: No kiosk software or clue data is published upstream. For each save, this stand-in picks a hidden Suspect, Attack, and Room at random; the 10 clues and the Accuse check belong to this stand-in, while the badge firmware only stores and displays the elimination and win masks it is sent over serial.
First Boot & Wipe Save: On a fresh save or after Wipe Save, the firmware initializes its save flash and runs its own Red β Green β Blue LED test, which never ends by itself; click Reset Badge to start the notepad.
Clue Kiosk & Accusation0 / 10 clues β’ 0/21 S, 0/21 A, 0/10 R cleared
Click Visit a Kiosk to light eliminated Suspects, Attacks, and Rooms in Green. When you deduce the remaining unlit Suspect, Attack, and Room, choose them above and click Accuse. After each Visit the new clue blinks on the badge for about 15 seconds; leave the badge buttons alone until it ends.
Skip Game (Ends Game at Once & Shows Answer)
Firmware Serial LogCursor: Anonymous
(Serial idle β click Visit a Kiosk, Read Badge State, or Ping Badge)
The firmware's reply has no end marker, so a few bytes from memory can follow it (shown escaped).
Ambient Light Sensor (I2C 0x29)
When the sensor at I2C address 0x29 reports low light (1..100), the firmware turns off all 52 LEDs until the room brightens.
Hold Button While Resetting
At power-on, holding SELECT enters the RP2040 ROM USB bootloader, and holding DOWN runs the Red β Green β Blue LED self-test loop. Holding UP at boot has no special behavior.
How Winning Works & Notes
How Winning Works: Each clue replaces the badge's saved Green elimination masks, so the stand-in sends the combined masks of all clues collected so far. The firmware's flash save stores the clue status word and the Suspect, Attack, and Room masks in one flash sector, and your Suspect and Attack cursors in a second sector. Sending the winning message blinks the winning Suspect, Attack, and Room in Red for about 15 seconds (Mode 1) and unlocks four LED animations (Modes 2β5: Fast Rainbow, Slow Rainbow, Random Sparkle, and Random Fill, cycled with UP and DOWN; SELECT does nothing in those modes as the firmware ignores it).
1. Board Drawing: Drawn from a photo of a real 2022 badge (no CAD files are published), so positions are approximate; row 14 of Suspects reads Pali(?) in the photo and is marked with (?). 2. Stand-in Kiosk: No kiosk software or clue data is published upstream. 3. Clock & Timer: The emulated RP2040 runs at an 8 MHz CPU clock with a 1:1 hardware timer; if your computer is slower, badge time slows down rather than dropping work. 4. Column Order: Mapping the first 21-LED group to left column Suspects and the second 21-LED group to right column Attacks/Exploits follows the cursor and message order and has not been checked on hardware.
Emulator Controls
Display & Firmware Mode
Pet Time Multiplier (`emu_set_speed`)
Execution & Core Lifecycle
Solo Game β’ Physical "Nut" NFC Dispenser
Register a handle on the badge, then tap a Sorting Hat Nut to join a faction and Telecom Nuts to unlock the 31-node map.
NFC Tag & Capture
Hardware State
BUTTON MASK0x00 (IDLE)
LCD BACKLIGHT255 / 255 (100%)
LED CHAIN (GPIO 3)20 WS2812B (D1βD20)
STORAGE KEY (YEAR/MODE)localStorage Synced
Not saved: browser storage unavailable
About
Unofficial fan project. Not affiliated with or endorsed by SAINTCON or UtahSAINT.
SAINTCON is Utah's annual cybersecurity and hackers conference, celebrated for its custom hardware badges and conference-wide badge games.
This is a fan-made hardware emulator of the badge by compukidmike.
Privacy: All badge progress (simulated 512-byte EEPROM/NVS) is saved in your browser only (localStorage, isolated per year and mode) β no cookies, no analytics, and no external CDNs.