ESP32 DevKitC v4 Bluetooth audio relay. iPhone -> ESP32 (A2DP sink) -> JBL Charge 5 + Tangerine EDGE (dual A2DP source). Dual mirrored ring buffers for in-sync output, auto-reconnect on boot.
147 lines
4.8 KiB
Markdown
147 lines
4.8 KiB
Markdown
# BikeAudio — Setup Guide
|
|
|
|
iPhone → ESP32 DevKitC v4 → JBL Charge 5 + Cardo Packtalk Edge (wireless, no latency concern)
|
|
|
|
---
|
|
|
|
## 1. Arduino IDE Setup
|
|
|
|
### Install Arduino IDE
|
|
Download from https://www.arduino.cc/en/software (version 2.x)
|
|
|
|
### Add ESP32 Board Support
|
|
1. Open Arduino IDE → Preferences
|
|
2. Add this URL to "Additional boards manager URLs":
|
|
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
|
|
3. Tools → Board → Boards Manager → search "esp32" → install "esp32 by Espressif Systems" VERSION 2.0.17
|
|
IMPORTANT: Use 2.0.17, NOT 3.x — the Bluetooth stack has regressions in 3.x
|
|
|
|
### Board Settings (Tools menu)
|
|
Board: ESP32 Dev Module
|
|
Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS) <-- CRITICAL
|
|
Upload Speed: 921600
|
|
CPU Frequency: 240MHz
|
|
Flash Frequency: 80MHz
|
|
Flash Mode: QIO
|
|
Flash Size: 4MB (32Mb)
|
|
|
|
---
|
|
|
|
## 2. Install Libraries
|
|
|
|
### Option A — Arduino IDE Library Manager
|
|
1. Sketch → Include Library → Manage Libraries
|
|
2. Search "ESP32-A2DP" → install by Phil Schatzmann
|
|
3. Search "arduino-audio-tools" → install by Phil Schatzmann
|
|
|
|
### Option B — Manual (if Library Manager version is outdated)
|
|
Download ZIPs from:
|
|
https://github.com/pschatzmann/ESP32-A2DP/archive/refs/heads/main.zip
|
|
https://github.com/pschatzmann/arduino-audio-tools/archive/refs/heads/main.zip
|
|
Sketch → Include Library → Add .ZIP Library → select each ZIP
|
|
|
|
---
|
|
|
|
## 3. First Time Pairing (do this once)
|
|
|
|
The order matters.
|
|
|
|
1. Forget JBL Charge 5 and Cardo from your iPhone Bluetooth settings
|
|
(iPhone must NOT be connected to them — ESP32 needs to claim them)
|
|
|
|
2. Put JBL Charge 5 in pairing mode
|
|
Hold the Bluetooth button until you hear the pairing sound
|
|
|
|
3. Put Cardo Packtalk Edge in pairing mode
|
|
Hold the phone button for 3 seconds until LED flashes
|
|
|
|
4. Open BikeAudio.ino in Arduino IDE, plug in ESP32 via USB, flash it
|
|
|
|
5. Open Serial Monitor (115200 baud) — you'll see:
|
|
[JBL] Connecting...
|
|
[JBL] Connected
|
|
[CARDO] Connecting...
|
|
[CARDO] Connected
|
|
[SINK] Advertising as 'BikeAudio'...
|
|
|
|
6. On iPhone → Settings → Bluetooth → connect to "BikeAudio"
|
|
|
|
7. Play audio — both JBL and Cardo should output simultaneously
|
|
|
|
After first pairing, all three devices remember each other.
|
|
On next boot, everything reconnects automatically within ~10 seconds.
|
|
|
|
---
|
|
|
|
## 4. Daily Use (after first pairing)
|
|
|
|
1. Power on ESP32 (USB powerbank on bike, or small LiPo)
|
|
2. Turn on JBL Charge 5
|
|
3. Power on Cardo helmet
|
|
4. iPhone auto-reconnects to "BikeAudio" (or tap it in BT settings)
|
|
5. Play music/nav audio — both speakers play
|
|
|
|
No buttons, no app, no wires.
|
|
|
|
---
|
|
|
|
## 5. Customization
|
|
|
|
Edit these lines at the top of BikeAudio.ino:
|
|
|
|
#define SINK_NAME "BikeAudio" // name iPhone sees
|
|
#define JBL_NAME "JBL Charge 5" // must match exactly
|
|
#define CARDO_NAME "Tangerine EDGE" // must match exactly
|
|
|
|
To find exact BT name of a device:
|
|
iPhone → Settings → Bluetooth → tap the device name shown there
|
|
|
|
---
|
|
|
|
## 6. Powering the ESP32 on the Bike
|
|
|
|
Options (all wireless, no wires to phone):
|
|
A. USB powerbank in jacket pocket or tank bag — plug ESP32 via USB-C cable
|
|
B. Small LiPo 3.7V 1000mAh + TP4056 charging module (~$5 total) — fully self-contained
|
|
C. Tap 5V from bike's USB port if you have one
|
|
|
|
The ESP32 draws ~200-300mA during active BT streaming. A 1000mAh LiPo lasts ~3-4 hours.
|
|
|
|
---
|
|
|
|
## 7. Troubleshooting
|
|
|
|
JBL or Cardo not connecting:
|
|
- Make sure they are NOT paired to your iPhone anymore
|
|
- Put them in pairing mode before powering the ESP32
|
|
- Check exact name match in the #define lines
|
|
- Open Serial Monitor and watch the output
|
|
|
|
Compilation errors:
|
|
- Double-check you're on ESP32 core 2.0.17 not 3.x
|
|
- Double-check Partition Scheme = Huge APP
|
|
- Make sure both pschatzmann libraries are installed
|
|
|
|
Audio cutting out:
|
|
- Increase BUFFER_SIZE from 4*1024 to 8*1024 in the sketch
|
|
- Keep ESP32 away from other 2.4GHz sources (WiFi routers)
|
|
|
|
Only one speaker plays:
|
|
- The second source connection may have failed on boot
|
|
- Check Serial Monitor — it will say which device is waiting
|
|
- Power cycle everything and let them reconnect
|
|
|
|
---
|
|
|
|
## 8. How the Audio Path Works
|
|
|
|
iPhone sends standard Bluetooth A2DP audio (SBC codec, 44.1kHz stereo 16-bit).
|
|
ESP32 receives it as a sink (like a Bluetooth speaker).
|
|
Each audio frame is written into two separate ring buffers simultaneously.
|
|
JBL source reads from buffer 1, Cardo source reads from buffer 2.
|
|
Both get identical audio at the same time = in sync.
|
|
|
|
Latency added by the relay: ~50-150ms on top of normal BT latency.
|
|
Since you said latency is fine, this is not an issue.
|
|
Both speakers receive audio with the same added delay so they stay in sync with each other.
|