Converting my Heaphones to work with Bluetooth

From a Burning Ear Cup to Hi-Fi Wireless: Building the BlueAudio Puck on an ESP32
Embedded Audio & Hardware Mod • Bluetooth Classic BR/EDR • ESP-IDF v5.5 • PCM5102A I²S DAC

From a Burning Ear Cup to Hi-Fi Wireless: Building the BlueAudio Puck on an ESP32

How a swollen battery replacement disaster on an intern keepsake led to building a pocket-sized, DSP-powered Bluetooth A2DP audio receiver using an original ESP32, an audiophile I²S DAC, and zero dongles.

#01 The Cherished Intern Keepsake Meets a Fiery End

During my engineering internship at Vega Innovations, I received a humble set of wireless headphones: an Airphone 3. While inexpensive, it was surprisingly robust. For nearly three and a half years of daily engineering work, PCB troubleshooting, and commuting, it served me faithfully across both Bluetooth and its 3.5 mm analog input without skipping a beat.

Eventually, Father Time caught up with the chemistry. After three years of constant charge-discharge cycles, the internal lithium cell stopped holding charge and puffed up into a swollen pillow.

Airphone 3 Wireless Headphones
The trusty Airphone 3: 3.5 years of dependable audio
Opening the left earcup assembly
Disassembling the left earcup containing the battery and receiver PCB

Thinking it would be an easy weekend repair, I sourced a replacement 3.7V 500mAh LiPo pouch cell from Tronic.lk and soldered it into the earcup power rails.

3.7V 500mAh Replacement LiPo Cell
The replacement 3.7V 500mAh LiPo cell from Tronic.lk
The Heat Meltdown: Almost immediately after powering on with the new cell, the factory Bluetooth SoC on the headphone circuit board began heating up uncontrollably. Within minutes, the plastic shell reached thermal runaway temperatures—it was so fiercely hot against my skull that my left ear was literally sweating!

Whether due to an internal silicone breakdown in the PMIC or an over-voltage quirk on the budget Bluetooth silicon, the integrated radio board was a legitimate safety and fire hazard. I desoldered the battery permanently and relegated the Airphone to being a dumb, passive wired headset over its 3.5 mm auxiliary jack.

#02 The Modern Smartphone Dilemma: Dongle Hell

Reverting to an analog wire introduced a frustrating modern problem: smartphones no longer have 3.5 mm headphone jacks.

Carrying fragile USB-C dongles everywhere is infuriating. They strain your phone’s charging port, get forgotten on desks, and physically tether your head to your workstation whenever you walk around the lab or fetch coffee.

The drivers inside the Airphone 3 were still in pristine mechanical shape. Rather than throwing out great acoustic hardware, I decided to engineer a dedicated, pocketable wireless bridge: The BlueAudio Puck.

#03 The Silicon Trap: Why the Original ESP32 Beats Modern Chips

When planning a modern Bluetooth audio receiver, most engineers instinctively grab Espressif’s newer microcontrollers—the ESP32-S3, C3, C5, or C6. They feature newer RISC-V or modern Xtensa cores, USB native OTG, and lower power consumption.

However, if you try building an A2DP Bluetooth audio receiver on those newer chips, you will hit a brick wall.

⚡ Why A2DP Sink Requires the Classic Dual-Core ESP32 ▼

Standard Bluetooth audio streaming from smartphones and computers relies on the Advanced Audio Distribution Profile (A2DP). A2DP runs exclusively on Bluetooth Classic (BR/EDR) physical and link layers.

  • Espressif dropped Bluetooth Classic completely on the ESP32-S3, C3, and C6 to save silicon die space and focus on IoT mesh, making them BLE-only.
  • They cannot fall back to the newer Bluetooth LE Audio standard either. LE Audio requires isochronous channels specified in Bluetooth 5.2. The S3 and C3 are locked to Bluetooth 5.0 hardware architectures.
  • Therefore, the venerable, original dual-core ESP32 (Xtensa LX6) remains the reigning king for DIY A2DP audio streaming.
Chip Series BT Radios A2DP Sink Capability Audio Verdict
ESP32 (Original) Classic BR/EDR + BLE 4.2 ✅ Full Native A2DP Sink & Source Ideal candidate for custom audio pucks
ESP32-S3 BLE 5.0 only ❌ Not supported (No BR/EDR) Cannot pair as a Bluetooth headphone
ESP32-C3 / C6 BLE 5.0 / 5.3 ❌ Not supported (No BR/EDR) Cannot sink standard mobile A2DP

#04 The Hardware Architecture: PCM5102A & Direct-Solder Sandwich

While the ESP32 has internal 8-bit DACs on GPIO 25 and 26, their dynamic range and signal-to-noise ratio (SNR) are abysmal for high-fidelity audio.

To get clean, audiophile-grade output, I paired the ESP32 with an external Texas Instruments / Burr-Brown PCM5102A 32-bit / 384 kHz I²S DAC. Rather than messy jumper wires, the pin mapping was intentionally routed so the PCM5102A module sits directly beneath the ESP32 devkit on rigid solder bridges.

ESP32 Pin Bus Signal Target Destination Function & Hardware Notes
GPIO 4 I²S BCK PCM5102A BCK Continuous bit clock line
GPIO 15 I²S LRCK PCM5102A LRCK Word select / Left-Right frame clock
GPIO 2 I²S DATA PCM5102A DIN Serial PCM audio stream (also pulses on-board LED!)
GPIO 21 / 22 I²C SDA / SCL SSD1306 OLED 128x64 display telemetry bus (0x3C address)
GPIO 33 RTC Button (BT2) Play / Pause / Pair Wakes the ESP32 from deep sleep on press

⚠️ PCM5102A Solder Jumpers: Solving the "No Audio" Trap

The PCM5102A requires specific hardware strap jumpers on its reverse side:

  • SCK Bridge Soldered: Tells the DAC’s internal PLL to generate its own master clock (MCLK) directly from BCK. This completely eliminates the need for an external MCLK line!
  • XSMT tied to 3.3V: Releases the soft-mute circuit. (Floating or pulled low results in complete silence).
  • FMT tied to GND: Selects standard I²S Philips data format.
  • GPIO 2 Strapping Note: Because GPIO 2 is a boot strapping pin, holding the board's BOOT button may be required when flashing new firmware over UART.
BlueAudio Puck ESP32 Prototype
The BlueAudio Puck: Compact ESP32 + PCM5102A receiver driving the Airphone 3

#05 Firmware Architecture: Real-Time Audio Without Stutters

Streaming audio over a microcontroller running an operating system is a real-time juggling act. If the Bluetooth radio gets starved for even a couple of milliseconds, packets drop and audio stutters.

Built from scratch on ESP-IDF v5.5.4, the firmware adheres to a strict architectural rule: Bluedroid stack callbacks are non-blocking and only enqueue.

Firmware Audio Pipeline Execution Pinned Dual-Core Model
[Bluetooth Controller / Radio Stack] ➔ Core 0
                 │ (Raw SBC Packets over ACL)
                 ▼
[Bluedroid Decoder Callback] (Instant Queue Push)
                 │
                 ▼ (FreeRTOS 32 kB Ring Buffer with 25% Prefetch Cushion)
                 │
[Audio Writer & DSP Task] ➔ Pinned to Core 1
                 │
                 ├─ 5-Band Biquad Parametric EQ Cascade (1337 µs / 360 frames)
                 ├─ Software Volume Scaling (AVRCP Synchronized)
                 ▼
[I²S DMA Controller (APLL Clocked @ 44.1 kHz)] ➔ PCM5102A DAC ➔ 3.5mm Jack

By pinning the audio writer, DSP filters, and blocking I²S calls to Core 1, the radio on Core 0 is never interrupted. Furthermore, using the ESP32’s internal Audio PLL (APLL) generates clean fractional clock dividers, producing an exact 44.1 kHz sample rate with virtually zero clock jitter.

🎛️ Integrated 5-Band Parametric Equalizer

Because budget headphone drivers often have resonant peaks or rolled-off sub-bass, the firmware includes a real-time 5-band biquad parametric equalizer.

Benchmarked on hardware, calculating all 5 stereo biquad sections takes just 1,337 µs per 360-frame audio block—consuming only ~16% of Core 1 at 160 MHz. This leaves ample CPU headroom while allowing complete acoustic correction directly in firmware!

#06 Display Telemetry, AVRCP & Paying It Forward

To make the Puck feel like a polished commercial consumer device, I integrated a 0.96-inch SSD1306 128x64 OLED display communicating over I²C:

  • Full AVRCP Metadata: Displays current track title, artist name, and playback transport state (Play/Pause). Overlong song titles automatically bounce and scroll smoothly.
  • Absolute Volume Synchronization: Changing the volume on your smartphone updates the Puck's on-screen volume bar in real-time, and vice-versa.
  • Golden Receive Power Range (RSSI): Rather than meaningless fake dBm bars, the link meter reads Bluetooth Classic's delta from the optimal RF reception window.
  • Power Management: Dynamic Frequency Scaling switches the CPU between 80 MHz and 160 MHz, transitioning into deep sleep after 15 minutes of inactivity.

Seeing how convenient and clear the audio was, I built a secondary custom unit for a friend who was dealing with the exact same missing-jack predicament on his setup:

Secondary Bluetooth Receiver Build
Dedicated standalone receiver built for a friend

#07 Conclusion & Open Source Repository

What started as an alarming near-fire on an ear cup ended with an audio receiver that delivers significantly higher audio quality and lower noise than the factory Airphone 3 ever possessed.

By leveraging dedicated hardware DACs, APLL audio clocks, and smart FreeRTOS core distribution, you can breathe new, wireless life into any vintage or favorite wired headphones without sacrificing sound quality or buying throwaway plastic dongles.

Get the Firmware & KiCad Schematics

The complete ESP-IDF v5.5 project, parametric DSP code, and KiCad PCB designs are available on GitHub.

View Repository →

Published with ❤️ by the hardware engineering community • Powered by ESP32 & FreeRTOS

No comments:

Post a Comment