How to Build an RFID Treasure Chest with ESP32
Tap the right NFC tag to unlock a servo latch with dramatic effects
Updated

What you'll build
In this project you will build an RFID-locked treasure chest using an ESP32, an MFRC522 NFC/RFID reader, a servo motor acting as a latch, a piezo buzzer, and an OLED display. Tapping an authorized NFC tag or card against the reader triggers a dramatic unlock sequence -- the OLED displays a key-turning animation, the buzzer plays a triumphant fanfare, and the servo swings the latch open. An unrecognized tag produces a denied animation with a descending buzz, and the chest locks itself again automatically after a configurable timeout. You can register new tags through a master-card enrollment mode, making it easy to add or revoke access without reflashing the firmware.
RFID and NFC technology is everywhere -- door locks, transit cards, contactless payments -- and this project gives you direct, practical experience with the underlying protocol. You will learn how the MFRC522 communicates with MIFARE tags over SPI, read and compare unique tag identifiers, store authorized UIDs in the ESP32's non-volatile Preferences library, and control a servo with precise angle commands. The enrollment system teaches you how to implement a simple admin workflow in firmware, including timeout handling, visual confirmation prompts, and write-protect logic to prevent accidental overwrites of the master key.
The finished treasure chest makes an excellent prop for escape rooms, classroom reward systems, geocaching, or simply keeping snacks safe from roommates. The code architecture separates tag management, servo control, display rendering, and audio feedback into clean modules, so extending the project is straightforward. You could add Wi-Fi logging to track who opened the chest and when, wire up a solenoid for a heavier-duty lock mechanism, or integrate an accelerometer to detect tampering and trigger an alarm. It is a satisfying intermediate build that covers SPI communication, access-control logic, and physical actuation in a single cohesive project. Pair it with the arcade reaction tower for a full set of interactive game props at your next event.
Wiring diagram
Wiring diagram
Components needed
Assembly
Wire lock hardware
Connect servo to GPIO26 and buzzer to GPIO25 for lock and sound feedback.
- Power servo from a stable 5V rail and share ground with ESP32.
- Do not power servo directly from a GPIO pin.
Connect RFID and status display
Wire MFRC522 on SPI and OLED on I2C (GPIO21/22).
- Keep RFID antenna area clear of metal hardware.
Pin assignments
| Pin | Connection | Type |
|---|---|---|
| GPIO 23 | rfid-reader-1 MOSI | SPI |
| GPIO 19 | rfid-reader-1 MISO | SPI |
| GPIO 18 | rfid-reader-1 SCK | SPI |
| GPIO 5 | rfid-reader-1 SS | DIGITAL |
| GPIO 27 | rfid-reader-1 RST | DIGITAL |
| GPIO 26 | lock-servo-1 SIG | PWM |
| GPIO 25 | chest-buzzer-1 SIG | PWM |
| GPIO 21 | chest-oled-1 SDA | I2C |
| GPIO 22 | chest-oled-1 SCL | I2C |
Code
#include <Wire.h>
#include <SPI.h>
#include <MFRC522.h>
#include <ESP32Servo.h>
#include <Adafruit_SSD1306.h>
#define SS_PIN 5
#define RST_PIN 27
#define SERVO_PIN 26
#define BUZZER_PIN 25
#define SDA_PIN 21
#define SCL_PIN 22
MFRC522 rfid(SS_PIN, RST_PIN);
Servo lockServo;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
byte validUid[4] = {0xDE, 0xAD, 0xBE, 0xEF};
void setup() {
Wire.begin(SDA_PIN, SCL_PIN);
SPI.begin();
rfid.PCD_Init();
lockServo.attach(SERVO_PIN);
lockServo.write(0);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
pinMode(BUZZER_PIN, OUTPUT);
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
bool valid = true;
for (byte i = 0; i < 4; i++) {
if (rfid.uid.uidByte[i] != validUid[i]) valid = false;
}
display.clearDisplay();
display.setCursor(0, 0);
if (valid) {
lockServo.write(90);
tone(BUZZER_PIN, 1800, 130);
display.println("Access granted!");
display.println("Treasure unlocked");
} else {
lockServo.write(0);
tone(BUZZER_PIN, 600, 180);
display.println("Invalid tag");
display.println("Chest remains locked");
}
display.display();
delay(700);
}
// Run this and build other cool things at schematik.ioReady to build this?
Open this project in Schematik to get the full wiring diagram, pin assignments, and deployable code for the RFID Treasure Chest.
Open in Schematik →


