TL;DR : This is an iPod emulator that creates a bridge between an older car head unit (typically one found on a LCI BMW Mini Cooper, aka "Boost CD") and a mobile phone, and allows streaming audio content over A2DP to the car while retaining the radio commands such as Next, Previous and Track metadata display.
Second-generation BMW Mini Coopers (R56, 55, 57, 58...) usually did not come with Bluetooth music streaming capabilities, except for some that had the "Visual Boost" or "Mini Connected" packages selected. These are easily identifiable because they replace the large central speedometer with a touch-screen surrounded by a speedo ring.
In the case of "LCI" (aka facelift), post-2010 Mini Coopers and derivatives, a good portion of them came with the "Radio Boost CD" head unit, which in some cases may feature Hands-free Bluetooth, USB input and an Aux 3.5mm jack input (typically those with option $6ND).
Here is what the USB+Aux connection typically looks like :
A large number of thoses are capable of reading USB drives and the likes on the USB input, and in some cases they also can "control" good old 30-pins iPods, via a now-rare and often-faked "Y-cable".
This normally allows access to a special audio source on the screen ("iPod") and provides some niceties like Playback control, metadata display and even Playlist/Artist/Album/Genre browsing.
Unfortunately, connecting any other device on this USB will usually not work, as it is not operating in Host mode and our modern phones are now too advanced anyways.
As a palliative, some companies like Bovee or Gitank created some similar types of emulators, that connect to the USB + Aux and appear on the phones as BT Speakers.
I have had a very mixed bag of results with those, and it appeared to be even worse when using an Android phone, as the Playback/Synchronisation/Metadata seemed to be mostly reserved to iPhone users.
Taking this into account, I chose to combine together a USB <-> Serial interface connected to an ESP32 WROOM32 development board, hook this up to an external DAC with a 3.5mm audio jack socket, and finally to spin some code in order to make my Mini think that there is a very special type of iPod connected to it... the kind that doesn't exist !
The objectives were :
The iPodESP32 relies primarily on three specific aspects :
All of this fancy code is living on an ESP32 WROOM32 MCU, and for the sake of easy sourcing, in my case a NodeMCU 32S. Please do not that alternative ESP MCUs might work as long as they have enough Flash space (about 2MB), RAM (320kB or more) and processing power... on top of supporting Bluetooth Classic (so no ESP32-S3 for example).
The I2S stream generated from the ESP32 goes to a DAC chip (in my case an UDA1334A, but others are usable) to generate an audio signal on the aux Jack, and the Car <-> ESP32 interfacing is done through a very specific Serial interface chip (more on that below).
Unfortunately BMW's head unit doesn't seem to natively recognise the most widely available USB-Serial chips like the FTDI 232 or the CH340 and other variants, possibly because of trade deals and of their release dates.
Most if not all the Y-cables used to connect iPods to the Mini use a PL2303HX chip to let the iPod communicate over Serial with the car.
Working USB-Serial chips need to report the VID and PID of the PL2303HX converter to be recognised and unfortunately it is difficult to source in small quantities. Additionally this has been a widely copied chip so there is a host of fakes available on the Internet. These should just as fine as the real ones, but they are obviously not the real deal.
Hardcore DIY makers can get a PL2303G interface board like the one manufactured by Waveshare and edit the OTPROM (only once) with the PL2303HX VID and PIDs, but PL2303HX alternatives from Amazon/Aliexpress and consorts might work just as well without trying to find a way to edit the VID and PID.
My personal choice in that case was to use a NodeMCU 32S based on the WROOM32, which is readily available in many shapes and forms and can be bought in many outlets at a very cheap price. These usually feature largely enough RAM and Flash to host the app and run without stuttering.
Other boards, such as the Sparkfun Thing Plus, will work, as will some of the DevKit C V4 from AZ-Delivery.
Please note : ESP32-S3 do not support BT classic, and therefore WILL NOT WORK.
Please note, because of deprecation issues with ESP's A2DP-I2S implementation, this project uses now pschatzmann's Arduino Audio Tools lib for the A2DP-I2S implementation. It works just the same with some syntax adjustments.
Before I may get around to providing an all-in-one board, the best solution is to use an external DAC with a 3.5mm barrel jack output. The possible models are described, along with some configuration hints, on pschatzmann's ESP32-A2DP library wiki pages.
In my case I went for a UDA1334A, which is really a copy of a board apparently originally sold by Adafruit, and is quite available all over the place.
For the McGyver style, a handful of jumper wires can suffice to connect all this hardware together.
I may provide a base PCB at a later point to provide a "standard" footpring and cleaner set-up, but it is not an absolute necessity.
At the time of writing, this is what is supported :
Some features are also partially supported but known to generate some bugs or unintended effects :
Some features that seem to be there but are actually not doing what they are originally intended to :
This repository is built around a Platformio project and VSCode, which allows automatic pulling of the right libraries, at the right version, from the right places, and good auto-configuration based on a couple build flags.
For the recommended hardware configuration, the simplest is to clone this repository, open it in Platformio (in VS Code for instance), connect the ESP32 board (without the DAC or the USB-Serial interface) and flash it like any other ESP32 bit of software.
For more exotic configurations, the build flags may need to be updated and the main.cpp file may also require some fiddling. I may provide some pre-made configurations in the future.
Please be aware that it is not currently possible to flash via the PL2303HX because it is not connected to the UART0 pins of the ESP32. Use USB CDC or the embedded USB-UART chips on the ESP32 devboard to flash via the main UART.
First start by installing Visual Studio Code and from within its Extensions interface, PlatformIo IDE. Once they are both installed, download the latest release or clone the repository on your computer. Unzip the release file and from within the folder, right-click and choose "Open with Code" as shown below.
The PlatformIO extension should automatically recognize and configure the project (which might take a few minutes). Once it is ready, select the build configuration you need (most likely nodeMCUESP32S_externalDAC ) and hit the "Build and Upload" arrow in the bottom bar, after connecting your NodeMCU32S board to the computer and letting it install the drivers.
VS Code should automatically find the target board and upload the software to it. After this, disconnect it, remount/reconnect as below, and look over Bluetooth for iPodEsp 2.
To be completed when a clean build exists...
For a NodeMCU32S or a Devkit C V4, the shape of the board may change but the pin numbers remain the same. The view and schematics are looking like so :
Pins numbers may change according to the DAC being used or the board. For the case of a Adafruit-style UDA1334A, the table is as follows :
UDA1334A | Pin number on DevKit board |
---|---|
WSEL | 25 |
DIN | 22 |
BCLK | 26 |
VIN | 3V3 or 5V |
GND | GND |
And on the PL2303 interface board : | PL2303 | Pin number on DevKit board |
---|---|---|
TX | RX0 | |
RX | TX0 | |
VIN | 5V or VIN | |
GND | GND |
To be designed.