# 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 driver
- `Adafruit GFX Library` - Graphics primitives
- `MFRC522` - RC522 RFID reader driver
- `WiFi` - ESP32 WiFi (built-in, currently disabled)
- `Preferences` - ESP32 NVS storage (built-in)

### Operating Modes

1. **Auth Mode** (startup): 5 players must scan AUTH cards in ascending ID order
2. **Programming Mode**: Write/read quest data to MIFARE cards via serial
3. **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:
1. `checkSerial()` - Process serial commands
2. `breatheLED()` - LED animation (normal mode only)
3. `checkRFID()` - Poll for RFID cards
4. `checkTouch()` - Poll touch sensor for activity
5. `checkPowerSave()` - Display timeout and deep sleep

## Building & Flashing

### Prerequisites
- PlatformIO CLI or VS Code with PlatformIO extension

### Commands

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

- [x] Write quest data directly to MIFARE cards
- [x] WiFi connectivity
- [x] Command cards (MORSE, INPUT)
- [x] Deep sleep for battery operation
- [ ] Custom animations on display
- [ ] OTA firmware updates
