TL;DR – A Bluetooth-enabled Button/Joystick to control music/podcasts on your phone whilst driving.
One thing I find very dangerous in the car is changing tracks etc on my phone when it’s in its screen mount. It’s impossible to do so without taking your eye off the road even for a second. And it’s illegal in many countries. I used to love the steering column controls for the old car radio but they don’t work over A2DP or AVRCP Bluetooth to my phone which streams to my Lidl car stereo.
I’ve made three attempts at solving this and I finally succeeded today.
The first attempt involved one of those cheap Chinese Bluetooth Serial modules like HC-05 or HC-06. I got pretty far with this and was able to send commands to my phone. But that’s where I got stuck. I would need to write a native Android App to take those commands and broadcast them as media commands in the phone. I made some progress there but I was way out of my depth.
Whilst in the midst of that, Adafruit announced the Bluefruit. We know how that turned out for me, but if you want to make something like my BBB, I’d recommend that route since you get almost everything out of the box.
Finally I settled on the Microchip Roving Networks RN42 HID Bluetooth module. It only cost €16.50 ex-VAT from Farnell Element 14 in Ireland. As usual with Farnell, you need to bump the order over €20 to get free (fast!) deliver. My big concern was to make sure I’d get the right variant since there are quite a few. But since May 2013 it looks like the HID one is what they ship by default. Of course the big drawback is that this is an SMD module which isn’t really designed for hand soldering into a hobby project. You can get them on breakout boards but it adds a lot to the cost. In the end the soldering was fine since it only really involved 4 wires and a stiff drink (Power, Ground, Serial Receive, Serial Transmit).
So what does it do? It’s really very simple. You pair it to your phone and it appears as a combo Keyboard/Mouse device. You then send commands using an Arduino Nano to the RN42 and it sends them to the phone. The trick here is that the commands are “Consumer Report” ones which means Play/Pause, Next/Prev Track and Volume Up/Down (amongst many others). It’s all powered by a LiPo battery I salvaged from some broken kids toy.
It works beautifully and will take pride of place attached to my steering wheel as I wend my way around the country. Update: Just tested on an emergency drive from Bandon to Mount Mellary to collect a sick Boy Scout.
I have tested on an SGS4 but there is no reason it won’t work on an iDevice unless Tim and Co have not implemented Consumer Report HID on iOS. Update: Tested and working beautifully on an iPhone 5 with iOS 7.
The only real issues I have so far are that it won’t auto-connect to the phone (I think this is the SGS4′s fault) and I haven’t implemented any power saving. I’m trying to sort auto-connect by using an NFC sticker to force the Samsung to connect. Not much joy yet. Power-saving should be easy to do since the joystick itself could be used to wake everything up. In the meantime I’ll just unplug when not in use and charge the battery every once in a while from the cigarette lighter socket using one of these very neat $3 USB LiPo chargers from the usual crew in DX in China.
One thing I haven’t figured out is why it won’t work with a 3.3V Arduino Pro Mini. The RN42 is a 3.3V device but only works with my 5V Arduinos like the Nano and the Uno. Is it possible the UART pins need 5V?
The Bill of Materials is as follows:
- Cheap Chinese Joystick Module
- Arduino Nano
- RN42 HID
- 3.7V Lipo Battery
- Double sided foam tape
- A few headers
- NFC Sticker
Wiring is beyond easy: TX on Arduino to RX on RN42. RX on Arduino to TX on RN42. 3V3 on Arduino to VCC on RN42. GND on Arduino to GND on RN42.
My code is trivially simple and uses my improved version of an existing Arduino library called BPLib to talk to the RN42. I had to modify the library to work on anything other than an Arduino Mega but that was a simple search/replace. I also added a bunch of the Consumer Report functions to the library if you want to make use of them. They are:
- void volumeUp();
- void volumeDown();
- void muteAudio();
- void playPause();
- void nextTrack();
- void prevTrack();
- void stopAudio();
- void fastForwardAudio();
- void rewindAudio();
- void keyRelease();
My Arduino sketch and library are available on GitHub here. Edit the ino file to suit yourself e.g. shorten a lot of the overly conservative delays or add proper power management. The BPLib directory should be dropped into the libraries sub-directory of your Arduino IDE installation.
One thing to be careful of is that most Arduinos only have one serial port. So if you have the RN42 attached to the serial pins and powered up, then you won’t be able to program the Arduino using the IDE until you disconnect power or RX/TX to the RN42.
As always, any questions, let me know in the comments.
UPDATE: I’ve been using it for two days now and I love it! One problem I’ve run into which should have been obvious is that once I pull the power, the BBB forgets what it has been paired to. So when I reconnect power, the phone thinks it is paired but the BBB doesn’t and therefore connection fails. So I have to un-pair and re-pair. The solution is obviously to implement strong power management so the LiPo lasts more than the current 48hrs. I’ll post new code when I have that figured out.
The other tiny problem is that play/pause on Android by default uses your main Music app rather than the last audio app you ran,. In my case I want it to control the Doggcatcher Podcast player. It’s no biggie, I just have to manually open Doggcatcher at the start of a journey and then the controls work perfectly.