GalMakes

ESP323D PrintingIoTSensors

Avatar Music Box

This project creates a music box that automatically plays different songs when you place various NFC tags on the reader. Each tag contains a small piece of data telling the ESP32 which track to play.

17/11/2025
4-6 hours
Intermediate
Avatar Music Box

Avatar Music Box - The mighty protector

As my boy started to grow and his passion for music grew even stronger each day, we eventually traded the click-clack of the keys for the sound of our mobile devices. Soon, his demands shifted: he had his own favorite song list, and each one absolutely had to be played five times before we could move to the next. The order was random, of course, and he fiercely insisted on control of the very next song. At the start, it was cute, but after some time, my wife and I found ourselves with no ability to do anything else besides being his own private, utterly exhausted D.J.

Design

I wanted to give Michael the ability to choose his own songs and feel in control of his listening experience. The solution was the Avatar Music Box, a system designed to play a specific song whenever a unique, physical avatar representing that track was placed on the device. To make this magic happen, the project uses several core electronic modules. The heart of the system is the ESP32-C3 Super Mini, which acts as the brain, processing input from the NFC reader. I paired this with the PN532 NFC Reader and embedded NFC Ntags inside small avatars that I have 3D printed, giving each physical object a unique digital ID. When Michael places an avatar on the box, the PN532 reads the tag's ID and transmits this data to the ESP32. The ESP32 then tells the DFPlayer Mini a compact MP3 module with its own amplifier to play the corresponding song file stored on an SD card. This allows for rich, dedicated sound output through a small speaker. For power, a Dual 18650 lithium-ion battery ensures the box is completely portable and can play many songs throughout the day without needing an external supply, controlled by a simple rocker switch. Finally, two push buttons were added for volume control, and an internal LED provides visual confirmation to the boy that the avatar has been correctly detected, making the entire experience intuitive and independent.

Circle Path

Electronic diagram maker

Circuit Diagram

Project Steps: Build Your own Avatar Music Box

1. Modules testing

I have connected the MVP elements, ESP32, DFPlayer, speaker, NFC reader to see that all modules are working fine and the connection are stable, I have create short code that can handle the tag detection, I used I2C protocol as I found it best for this project, low assumably steps (4 wire), and the most documentation on the web, other protocol have other benefits see the table below.

To set the module protocol there is config guide on the board. NFCMusicalBox

ModeProsConsBest For4# of wires
UARTEasy, stable, universalSlower, uses Serial pinsBeginners & simple NFC reading4
I²CAllows multiple devices on the same busUnstable on long wires, needs pull-ups (depends on the module)Sensor-heavy projects, pin-limited boards4
SPIFastest, reliable, best performanceMore pins, sensitive wiringAdvanced NFC, card emulation, fast operations6

2. 3D Model and printing

I had a vision in mind but didn’t see it clear so I asked GPT to create an image of this box, and it worked quite well. it helped me think on some small details that I didn't have in mind like small stroke lines and the location of cut between the two box parts. Modeling in Blender

I tried to same some time with the creation of the 3D module of the box by using MalerLab by MakerWorld, it worked pretty well and it was looking like I can just print it. after downloading the object I same issue with the texture and when there is functionality like buttons and part maybe this tool is not there yet, but for simple modeling its doing wonderful job. 3D Model

Try image to 3D MakerWorld

So I have to go and module it, for the speakers holes I still wanted a cat so I asked GPT to create image of a cat that is made by dots, I think this image convert is to SVG and used it to cut holes in the model 3D Model 3D Model 3D Model 3D Model

3. Assembly

After printing the box parts, I had to connect all the items together, some patient and good music help trough the process.

Hardware Setup

  • PN532 NFC Reader connected via I2C (pins 8, 9)
  • DFPlayer Mini connected via serial (pins 0, 1)
  • Two buttons for volume control (pins 5, 6)
  • LED indicator for playback status (pin 4)
  • SD card in DFPlayer with numbered MP3 files (001.mp3, 002.mp3, etc.)

AvatarBoxAssembly

4. The Code

This section provides a focused overview of the core functions that power the project, giving you a clear understanding of how the main logic works without overwhelming you with every implementation detail. If you’d like to dive deeper, explore the full source code, or better understand how all the components connect together, you can visit the Full Project Guide

System Behavior

When a tag is placed:

  • ESP32 detects the tag UID
  • Reads data on the tag (page 4)
  • Extracts the song number
  • Plays the corresponding MP3 file
  • LED turns ON

When the tag is removed:

A 2-second grace period The grace period mechanism allows songs to keep playing for 2 seconds after tag removal, preventing abrupt stops if the tag shifts slightly.. After that → playback stops.

Operating Modes

the device have 3 different mode to support from single application song play and tag maintenance

PLAY_MODE (default) - Automatically plays songs when tags are detected WRITE_MODE - Programs new tags via serial commands READ_MODE - Displays what song number is stored on a tag

Core Functions

Music Playback Functions

void playSong(int trackNumber) { dfPlayer.play(trackNumber); setLED(true); state.isSongPlaying = true; }

Plays the song number stored on the NFC tag, turns on an indicator LED, and updates the system state.

void stopSong() { dfPlayer.stop(); setLED(false); state.isSongPlaying = false; }

Stops the currently playing song, turns off the indicator LED, and updates the system state.

Volume Control
void checkVolumeButtons() { bool upPressed = (digitalRead(VOLUME_UP_PIN) == LOW); if (upPressed && !buttons.lastUpState) { adjustVolume(1); } }

Monitors two physical buttons to increase/decrease volume, with debouncing to prevent accidental multiple presses.

NFC Read & Write Operations

Writing Data to NFC Tags
void writeSongNumber(uint8_t songNum) { uint8_t data[4] = {'S', 'O', 'N', songNum}; nfc.ntag2xx_WritePage(4, data); }
  • Creates a 4-byte data packet: 'S', 'O', 'N', and the song number (1-99)
  • Writes this to page 4 of the NFC tag's memory
  • Activated via serial command: write 15 programs tag for song #15
Reading Data from NFC Tags
int readSongNumberFromTag() { uint8_t data[4]; nfc.ntag2xx_ReadPage(4, data); if (data[0] == 'S' && data[1] == 'O' && data[2] == 'N') { return data[3]; // Returns song number } return -1; // Tag not programmed }
  • Reads 4 bytes from page 4 of the NFC tag
  • Checks if the first 3 bytes are 'S', 'O', 'N' (indicating valid data)
  • Returns the song number (1-99) or -1 if the tag is not programmed
NFC Memory Map Graphic (ASCII) +------- NFC TAG MEMORY PAGE 4 ------+ | BYTE0 | BYTE1 | BYTE2 | BYTE3 | +-------+-------+-------+------------+ | S | O | N | Song # | +------------------------------------+ Example: [53] [4F] [4E] [05] Meaning: S O N Track 5

Continuous Tag Detection

void checkNFCTag() { bool tagDetected = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100); if (tagDetected) { int songNumber = readSongNumberFromTag(); playSong(songNumber); } }

Polls for NFC tags every 200ms, reads the song number, and starts playback automatically.

5. Unsovled issue

During development, I ran into a strange behavior: NFC tags with even numbers would not play any songs, while odd-numbered tags worked perfectly.

My first guess was an SD card formatting issue, so I reformatted the card using FAT32 with 32KB clusters:

# 1. List disks diskutil list # 2. Unmount the SD card diskutil unmountDisk /dev/disk2 # 3. Format as FAT32 with 32KB clusters sudo newfs_msdos -F 32 -c 64 -v MUSIC /dev/disk2 # (-c 64 → 64 sectors × 512 bytes = 32KB) # 4. Eject diskutil eject /dev/disk2

But this didn’t fix the issue. I added debug logs, tested different MP3 files, tried other sketches that play audio directly from the DFPlayer… still nothing. The pattern stayed the same:

  • Tag 1 → plays track 1
  • Tag 2 → no playback
  • Tag 3 → plays track 2
  • Tag 4 → no playback
  • Tag 5 → plays track 3
  • …and so on.

In short: only odd-numbered tag values trigger audio, and the DFPlayer shifts the track number.

At some point, the number of investigation hours I had allocated for this task simply ran out. So for now, I’m leaving this as an open issue in the project.

If you’re building your own Avatar Music Box, follow the pattern above — or even better, solve the mystery and share your solution with me so we can close this chapter together.

Thanks for reading!

Required Tools

  • Soldering Iron
  • Wire Strippers
  • 3D Printer
  • Hot Glue Gun
  • MultimeterOptional