# Minecraft Orb - Firmware

An ESP32-C3 powered interactive treasure hunt device. Players scan RFID cards to reveal clues, solve Morse code puzzles, and complete touch-based challenges. Quest data is stored directly on MIFARE Classic 1K cards.

Built for the **Giulio Hunt 2025** project.

## Hardware

| Component | Model | Interface | GPIO |
|-----------|-------|-----------|------|
| Microcontroller | ESP32-C3 SuperMini | - | - |
| Display | SSD1306 128x64 OLED | I2C | SDA=2, SCL=3 |
| RFID Reader | RC522 (13.56 MHz) | SPI | SCK=7, MOSI=8, MISO=9, CS=6, RST=10 |
| LED | White (100 ohm resistor) | PWM | 4 |
| Buzzer | Passive piezo | Tone | 0 |
| Touch Sensor | TTP223 capacitive | Digital | 5 |

Power is supplied via the **ESP32-C3 SuperMini Expansion Board**, which supports 3.7V LiPo battery with USB charging.

```
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
```

## Building & Uploading

Requires [PlatformIO](https://platformio.org/).

```bash
pio run                     # Build
pio run --target upload     # Upload via USB-C
pio device monitor          # Serial monitor (115200 baud)
```

## How It Works

### Startup: Authentication

On power-up, the device requires **5 players to scan their AUTH cards in ascending order** (IDs 1 through 5). Each card must have higher ID than the previous one. An out-of-order scan resets the sequence.

AUTH card clue format: `PlayerName|ID|WelcomeMessage`

Once all 5 authenticate successfully, the quest begins.

### Quest Mode

Players scan RFID cards to reveal clues on the OLED display. There are three types of quest cards:

**Regular cards** — Display the card name and clue text on screen.

**MORSE cards** — The clue is played as Morse code through the buzzer and LED. Dots and dashes are shown on the display but the text itself stays hidden.

**INPUT cards** — A touch-based number puzzle. Players press the touch sensor N times to enter a code (1-10). The answer auto-submits after 3 seconds of no input. Correct answers reveal a message; wrong answers show an error.

Card clue format for INPUT: `answer|message` (e.g., `5|The treasure is under the bridge`)

### Programming Cards

Connect via serial (115200 baud) and enter programming mode:

```
> PROG
>>> Entered programming mode

> ADD Quest 1|Go to the old oak tree near the lake
Scan card to add as 'Quest 1'...
<scan card>
OK: Card programmed as 'Quest 1'

> SCAN
<scan card>
Card UID: 12:AB:34:CD
Name: Quest 1
Clue: Go to the old oak tree near the lake

> EXIT
```

| Command | Description |
|---------|-------------|
| `PROG` | Enter programming mode |
| `EXIT` | Leave programming mode |
| `SCAN` | Read card UID and contents |
| `ADD name\|clue` | Write quest data to next scanned card |
| `HELP` | Show commands |

### Card Data Layout (MIFARE Classic 1K)

| Sector | Blocks | Content | Size |
|--------|--------|---------|------|
| 1 | 4-5 | Card 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 bytes name + 144 bytes clue. Uses default MIFARE key A (0xFFFFFFFFFFFF).

## Battery Operation

The device supports battery power via the ESP32-C3 SuperMini Expansion Board with a 3.7V LiPo cell. USB charging is handled by the board's TP4056 circuit (green LED = charging, LED off = full).

Power saving features:

| Event | Timeout | Behavior |
|-------|---------|----------|
| Display auto-off | 3 min inactivity | OLED turned off, any interaction wakes it |
| Deep sleep | 10 min inactivity | All peripherals powered down (~uA draw) |
| Wake | Touch sensor press | Full reboot through startup sequence |

Timeouts are configurable in `include/config.h` (`DISPLAY_TIMEOUT_MS`, `SLEEP_TIMEOUT_MS`).

The touch sensor must be on GPIO 0-5 for deep sleep wake to work (ESP32-C3 hardware limitation).

## Project Structure

```
firmware/
├── platformio.ini          # Build configuration
├── include/
│   ├── pins.h              # GPIO pin assignments
│   ├── config.h            # Timeouts, card limits, NVS keys
│   └── cards.h             # Card data structures
└── src/
    ├── main.cpp            # Firmware: init, event loop, display, RFID, audio, power
    └── cards.cpp           # NVS card database, MIFARE read/write operations
```

## Dependencies

| Library | Version | Purpose |
|---------|---------|---------|
| Adafruit SSD1306 | 2.5.x | OLED display driver |
| Adafruit GFX | 1.12.x | Graphics primitives |
| MFRC522 | 1.4.x | RC522 RFID reader |
| Preferences | built-in | ESP32 NVS storage |

## License

Part of the Giulio Hunt 2025 project.
