ESP32-C3 firmware for interactive treasure hunt device with RFID, OLED display, LED effects, buzzer, and touch input. Includes 3D printable STL files for the enclosure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
Minecraft Orb - Firmware
Project Overview
ESP32-C3 SuperMini-based RFID reader with OLED display, designed for the Minecraft Orb project (Giulio Hunt 2025).
Hardware
Microcontroller
- Board: ESP32-C3 SuperMini
- Form factor: Two rows of 8 pins, USB-C connector
- Framework: Arduino (via PlatformIO)
- Power: ESP32-C3 SuperMini Expansion Board with 3.7V LiPo battery (USB charging via TP4056)
Connected Components
| Component | Interface | Description |
|---|---|---|
| SSD1306 OLED | I2C | 128x64 pixel display |
| RC522 | SPI | RFID/NFC reader (13.56 MHz) |
| White LED | GPIO | Status indicator (100 ohm resistor) |
| Piezo Buzzer | GPIO/PWM | Audio feedback (passive) |
| TTP223 | GPIO | Capacitive touch sensor |
Pin Configuration
ESP32-C3 SuperMini Pinout (Top View, USB-C facing down)
Left Side Right Side
--------- ----------
GPIO5 <- Touch 5V
GPIO6 <- RC522 SDA GND
GPIO7 <- RC522 SCK 3V3
GPIO8 <- RC522 MOSI GPIO4 <- LED
GPIO9 <- RC522 MISO GPIO3 <- LCD SCL
GPIO10 <- RC522 RST GPIO2 <- LCD SDA
GPIO20 (FREE) GPIO1 (FREE)
GPIO21 (FREE) GPIO0 <- Buzzer
Detailed Wiring
| Component | Component Pin | GPIO | Notes |
|---|---|---|---|
| SSD1306 | SDA | GPIO 2 | I2C Data |
| SSD1306 | SCL | GPIO 3 | I2C Clock |
| SSD1306 | VCC | 3V3 | 3.3V power |
| SSD1306 | GND | GND | Ground |
| RC522 | SDA (CS) | GPIO 6 | Chip Select |
| RC522 | SCK | GPIO 7 | SPI Clock |
| RC522 | MOSI | GPIO 8 | SPI Data Out |
| RC522 | MISO | GPIO 9 | SPI Data In |
| RC522 | RST | GPIO 10 | Reset |
| RC522 | VCC | 3V3 | 3.3V power |
| RC522 | GND | GND | Ground |
| White LED | Anode (+) | GPIO 4 | Via 100 ohm resistor |
| White LED | Cathode (-) | GND | Ground |
| Buzzer | + (Signal) | GPIO 0 | Passive piezo buzzer |
| Buzzer | - (GND) | GND | Ground |
| TTP223 | I/O (Signal) | GPIO 5 | Touch output (HIGH when touched, GPIO0-5 required for deep sleep wake) |
| TTP223 | VCC | 3V3 | 3.3V power |
| TTP223 | GND | GND | Ground |
Software Architecture
File Structure
firmware/
├── platformio.ini # PlatformIO configuration
├── PLANNING.md # This file
├── include/
│ ├── pins.h # Pin definitions
│ ├── config.h # WiFi credentials & constants
│ └── cards.h # Card database structures
└── src/
├── main.cpp # Main firmware
└── cards.cpp # Card database (NVS storage)
Dependencies
Adafruit SSD1306- OLED display driverAdafruit GFX Library- Graphics primitivesMFRC522- RC522 RFID reader driverWiFi- ESP32 WiFi (built-in, currently disabled)Preferences- ESP32 NVS storage (built-in)
Operating Modes
- Auth Mode (startup): 5 players must scan AUTH cards in ascending ID order
- Programming Mode: Write/read quest data to MIFARE cards via serial
- Normal Mode: Scan cards to display clues; handles MORSE, INPUT, AUTH command cards
Event Loop
setup() initializes all hardware then enters auth mode. loop() calls:
checkSerial()- Process serial commandsbreatheLED()- LED animation (normal mode only)checkRFID()- Poll for RFID cardscheckTouch()- Poll touch sensor for activitycheckPowerSave()- Display timeout and deep sleep
Building & Flashing
Prerequisites
- PlatformIO CLI or VS Code with PlatformIO extension
Commands
pio run # Build firmware
pio run --target upload # Upload to board
pio device monitor # Monitor serial output
Serial Programming Mode
Connect via serial (115200 baud) and use these commands:
| Command | Description |
|---|---|
PROG |
Enter programming mode |
EXIT |
Exit programming mode |
SCAN |
Scan card and read contents |
ADD <name>|<clue> |
Write quest data to card |
HELP |
Show help |
Quest data is written directly to MIFARE Classic 1K cards (not stored in ESP32 flash).
Card Data Layout
| Sector | Blocks | Content |
|---|---|---|
| 1 | 4-5 | Name (32 bytes) |
| 2 | 8-10 | Clue part 1 (48 bytes) |
| 3 | 12-14 | Clue part 2 (48 bytes) |
| 4 | 16-18 | Clue part 3 (48 bytes) |
Total capacity: 32 byte name + 144 byte clue
Command Cards
Special card names trigger commands instead of displaying clues:
| Name | Clue Format | Description |
|---|---|---|
MORSE |
<message> |
Play clue as Morse code |
INPUT |
<answer>|<message> |
Touch input puzzle (1-10) |
Example Usage
PROG
ADD Quest 1|Go to the old oak tree near the lake
<scan card>
EXIT
Power Management (Battery Operation)
Powered via ESP32-C3 SuperMini expansion board with 3.7V LiPo battery (USB charging via TP4056).
| Feature | Timeout | Behavior |
|---|---|---|
| Display auto-off | 3 min inactivity | OLED turned off, touch/card/serial wakes it |
| Deep sleep | 10 min inactivity | All peripherals off, ~uA draw |
| Wake from sleep | Touch sensor press | Full reboot through setup() |
Timeouts configured in include/config.h (DISPLAY_TIMEOUT_MS, SLEEP_TIMEOUT_MS).
Touch sensor must be on GPIO0-5 for deep sleep wake support (ESP32-C3 limitation).
Future Development
- Write quest data directly to MIFARE cards
- WiFi connectivity
- Command cards (MORSE, INPUT)
- Deep sleep for battery operation
- Custom animations on display
- OTA firmware updates