This project was originally designed as a car stereo because voice control in a car is not just a gimmick, it is a very safe method of control.
Previously I had used a mounted tablet for music, but in reality touch screens and cars do not mix - the problem being that you must look at a touch screen to use it.
This project does not just rely on voice control though, four large buttons (also easy to use without looking) are really the primary method of control.
Of course this could also be a great ''lazy'' stereo for your lounge or bedroom - you wouldn't have to lift a finger (or even open your eyes) to change albums - just ask Alexa to do it for you!
- SD card mp3 player (with long filename support)
- FM radio (with ten user-savable channels)
- Bluetooth connection
- Simple four-button control
- LCD display
- Alexa voice control (as an optional add-on)
- Practically no boot-up delay for music (though voice control takes longer to initialize)
Great! Where can you buy one of these? Out of luck - this is D.I.Y. only!
Step 1: System Overview
The circuit is based around an Arduino Pro Mini which can select between/and control: an mp3 player module, an FM radio module, and a Bluetooth dongle. The capabilities of the Arduino were really stretched here - mainly because the SD card library uses a lot of ram. I had to put some limit on filename length, reuse buffers for multiple purposes, and write a minimal FM module library to make it all fit.
For optional voice control, a small unit containing an ESP8266 (configured as a MQTT client) can be plugged into the Arduino's serial port.
All on Amazon services:
Alexa Skill Service --> AWS Lamda Function --> MQTT Broker running on AWS BC2
Step 2: Electronics Board
1 x ARDUINO PRO MINI 5V
1 x RDA5807M FM Module ( http://www.ebay.com/itm/232380804289 )
1 x VS1053 MP3 Module with SD slot ( http://www.ebay.com/itm/222350760505 )
1 x LM1117 3v3 Regulator
1 x Bluetooth USB dongle
1 x 100K
3 x 470R
9 x 10K
1 x 1K
4 x 120R
8 x 10uF 6.3v
2 x 3.3nF
2 x 100nF
1 x PN100 NPN general purpose transistor
1 x IRF4905 MOSFET
2 x 2N7000 small signal MOSFET
SMA Antenna Socket
Micro USB Power Socket
Stereo Jack Socket
Various headers & Cable
Single Sided PCB Board 70x100mm
5V FTDI programmer
- The board was etched using common iron-on toner method.
- The power and audio sockets, the LM1117 and a 100nF capacitor are mounted on the copper side of the board.
- The micro USB socket is used to deliver power only - so I have not etched pads for all of the 5 pins (they are too close together). I have only placed pads for the two outer power pins. Bend the inner 3 pins up so they do not contact any copper.
- For the mp3 audio input - which connects between the SPK jack on the module and the PCB: Do not connect anything to the 'ground' pin of the SPK jack - it is actually not a ground connection. In one of the pictures you can see that I have used the ground pin (which is the one nearest the edge of PCB) of the MIC jack instead.
- Due to a small design oversight, the resistor in front of the Bluetooth MOSFET had to be moved slightly so that it did not contact a mp3 module mounting bolt (see picture).
Step 3: Firmware and Operating Instructions
The firmware is uploaded in the usual way from Arduino IDE, and requires:
SDFat library ( https://github.com/greiman/SdFat )
Adafruit VS1053 library - MODIFIED (Unmodified original here: https://github.com/adafruit/Adafruit_VS1053_Librar... )
This library has been modified to use SDFat library instead of SD library - this enables long-filename use. The modified library is attached.
At the top of the CAR_STEREO.ino sketch is a list of local FM stations and frequencies. Fill this out for your local stations so that the radio will display the name of the station you are tuned to. This can be an exhaustive list or not, and is independent of your ''favorite channels'' which are programmed during general use.
4 button + power panel:
The four push-buttons are connected to A0-A3 as digital inputs and short to ground when pressed. The PWR button is a locking button with LED that controls the 5v supply to the unit.
The function of the buttons are (short press is a normal press, long press is hold for more than 1 second then release):
MODE button:short: toggle between mp3 and FM mode; long: toggle Bluetooth mode on/off.
In MP3 mode:
<< button: short: select previous album; long: jump back 8 albums
>> button: short: select next album; long: jump forward 8 albums
> button:short: select next (sequential or random) track; long: toggle between random play and sequential play
(when random play is active, a small r will show inside the SD card icon)
In FM mode:
<< button: short: select previous saved channel; long: delete current station from saved channel list
>> button:short: select next saved channel; long: save current station to saved channel list
> button:short: scan to next station
You can program 10 favorite channels.
NOTE: The other two inputs (A6 & A7) are analog only inputs. When A6 is driven high, the output volume will be reduced - this is for a future use. A7 is currently unused.
SD CARD - ALBUM FILE STRUCTURE
The mp3's on the SD card should be placed within album directories which reside in the root directory. Each album directory contains mp3s, with the following naming conventions:
eg The directory Billy Joel-52nd Street (artist-album), contains tracks
01 Big Shot.mp3
02 Honesty.mp3 (2 digit track number, space or fullstop, track name)
I was able to implement long-filenames, but due to the memory restriction of the Arduino, I had to implement some restrictions:
- album and track filenames restricted to maximum of 30 characters
- maximum of 20 tracks per album directory
- but unlimed number of album directories
Because I have over 100 albums on my SD card, manually applying the above restrictions would be quite a chore, so I wrote a python script to do the renaming. This will rename most existing albums to the required form.
Note that there are two options for names that are too long - either truncate to 30 characters, or mark the long names (with a ] character) so that they can be identified and manually renamed.
The python script (written for Python 3.6) will also output some text files that will be used later in the Alexa Lambda function.
Step 4: Enclosure and Installation
Project Case Enclosure 125x80x32mm ( http://www.ebay.com/itm/301836019553 )
20x4 LCD Display + I2C Serial Interface Board Module ( http://www.ebay.com/itm/351808680291 )
RF Coax RG58 Extension Cable ( http://www.ebay.com/itm/111494095326 )
Car FM Aerial Antenna Splitter Cable ( http://www.ebay.com/itm/111494095326 )
Ground loop filter ( http://www.ebay.com/itm/291976287955 )
4 x Momentary Push Buttons ( http://www.ebay.com/itm/171505118701 )
1 x Latching Power Button ( http://www.ebay.com/itm/321756663194 )
Before attaching the I2C board to the LCD, I modified it to lower it's profile. As you can see in the photo, I moved the trim-pot off the PCB and added a new 4-pin header. I also removed the black plastic separators on the main header before soldering to the LCD, so that the two PCBs were almost flush. This is only required if you are going to use my 3D printed display housing.
Note that the stereo will also work with a smaller 16x2 display (which was my original design), and there is an option in the sketch to choose this. Some album and track names will be truncated on the display though.
See the photos. Some 3D printed spacers were used to facilitate mounting. Note that one of the center mounting pillars of the case needed to be removed, as it was in the way of the audio output jack. The display and button connectors were extended to the edge of the case with a small PCB (three of the pins on the button header are through-connectors to suit my previously wired power button and power controller - so you can ignore these).
I used a power controller from a previous project for power supply, but the unit has been designed so that you can use an ordinary 5V car charger to power it (via a power switch).
I joined the two antenna cables together with a coax-connector to make a DIY SMA to car antenna adapter cable.
The audio output connects to the AUX input of my existing car amplifier. I employed a ground loop filter to ensure a clean, high-quality sound output.
The display housing was mounted on the dash with some double-sided padded tape..
The stereo unit resides in my glove compartment - making it easy to remove and update the SD card.
Step 5: ALEXA I: Overview and MQTT Broker
You will need an Amazon Web Services account to set these up. These instructions assume that you have some familiarity with the Amazon and Alexa sevices. Note that the EC2 account is free for the first year, but then you will be charged for usage (which would be very minimal for this project). It is probably possible to use a different (free) service for the MQTT broker - but I have not explored this possibility.
SETUP MQTT BROKER ON AMAZON EC2
1. Create a new EC2 instance
Login to Amazon Web Services https://console.aws.amazon.com/console/home
- Select EC2 service
- Press launch instance
- Select Ubuntu Server 16.04 LTS
- Select t2.micro
- Press review and launch button
- Click edit security groups
- Create a new security group with rules (see picture):
22: Needed for SSH
1883: The MQTT standard port
8883: The MQTT standard port for MQTT over TLS.
8000: The port to use for MQTT over websockets
- Press review and launch
- Press launch
- Create a new key pair and download the MQTT_KEY.pem file
- Press launch instances
- View instances and take note of your Public DNS (IPv4) (eg ec2-XXX-XX-XXX-XXX.compute-1.amazonaws.com )
2. SSH into your EC2 instance
Now need to download PuTTY and SSH into your EC2 instance using your .pem file and Public DNS.
Use the login: ubuntu@ec2-XXX-XX-XXX-XXX.compute-1.amazonaws.com, on port 22 and a PPK file generated from your .pem file. Full instructions can be found here: https://linuxacademy.com/howtoguides/posts/show/to...
3. Setup Mosquitto MQTT Broker on your EC2 instance
Once logged through PuTTY, enter these commands to setup the Broker with a chosen password and username:
sudo apt-get update
sudo apt-get install mosquitto
sudo apt-get install mosquitto-clients
sudo mosquitto_passwd -c /etc/mosquitto/passwd username ( enter a password when prompted )
sudo nano /etc/mosquitto/mosquitto.conf
and add these lines to end of the file:
press Ctrl-O to save and Ctrl-X to exit.
Start the broker with:
mosquitto -c /etc/mosquitto/mosquitto.conf
You can test that everything is running by opening a new PuTTY login and type:
mosquitto_sub -h localhost -t "STEREO" -u "username" -P "password" to subscribe to your broker
Open another PuTTY login and type:
mosquitto_pub -d -t "STEREO" -m "test" -u "username" -P "password" to publish a test message.
The test message should appear on your subscribed login window.
You can now close all of the PuTTY windows as your MQTT broker is up and running!
Step 6: ALEXA II: Lambda Function and Alexa Skill
SETUP LAMBDA FUNCTION
Login to AWS console: https://console.aws.amazon.com
- Select lambda
- Create function
- Author from scratch
- Set trigger to alexa skills kit
- Enter name: CAR_STEREO
Prepare zip file
Download the attached CAR_STEREO.zip file and extract the lambda_function.py script. - you will need to edit this in a text editor:
- At the top of your script enter your MQTT details: Public DNS, username and password
- Add your album, artist and station data - you can paste the Album and Artist data from the text files that were generated using RenameMusic_1.0.py. Once edited, place lambda_function.py back into the zip file, overwriting the original.
Back in Lambda:
- Select upload a .zip file
- Select Python 3.6
- Upload your modified CAR_STEREO.zip file
- Make sure handler is: lambda_function.lambda_handler
Create custom role
- Leave lamda_basic_executions and create new role policy
- Select allow
- Press next - create function
Take note of arn in top left of screen: (eg arn:aws:lambda:us-east-1:XXXXXXXXX:function:CAR_STEREO )
CREATE ALEXA SKILL
Login to amazon developer console: https://developer.amazon.com/home.html
- Click Alexa tab, then Alexa Skills kit - get started
- Press add new skill: Name: CAR_STEREO, Invocation Name: car stereo
- Click save
- Click interaction model tab
Paste the text from the attached Intent_Schema.txt file into the Intent Schema box.
Create custome slot type called STATIONNAMES and enter radio station names as values eg:
radio hauraki etc
(These should be the same names as entered into your Arduino Script)
Paste the text from the attached Sample_Utterances.txt file into the Sample Utterances box.
- Press next
- Select aws endpoint and enter your arn from your lambda function (eg arn:aws:lambda:us-east-1:XXXXXXXXX:function:CAR_STEREO )
- Click next
Select the test tab
Enter a test sentence with one of your artists, eg play billy joel
You should get a response that contains something like: "Playing Billy Joel, An Innocent Man". If you are still subscribed to your MQTT broker in PuTTY, then you should also get an output like: ALB:Billy Joel-An Innocent Man.
Step 7: ALEXA III: ESP8266 Client and Use
This small add-on board connects to your MQTT Broker via wi-fi and feeds the messages received to the stereo board through a serial connection.
LM1117 (Surface Mount)
1 x 10uF (Surface Mount or 6.3v Radial)
1 x100nF (Surface Mount)
2 x 2N7002 (Surface Mount)
6 x 10K (Surface Mount)
Double Sided PCB 23x37mm
5V FTDI programmer
ESP8266 CLIENT PROGRAMMING
The board is programmed using the Arduino IDE. Short the two pin jumper to enter programming mode. Plug the FTDI programmer into the right-hand set of pins and program as a generic ESP8266.
To test, remove the jumper, reset and monitor the output using the serial monitor (9600 baud). You should see a notification when it has successfully connected to wi-fi, and a output of MQY every five seconds when it has successfully connected to the MQTT broker.
If you do the Alexa test again, you should now see the output (eg ALB:Billy Joel-An Innocent Man ) on the serial monitor.
ESP8266 CLIENT USE
Make sure the programming jumper is removed and plug the boards left-hand set of pins into the serial port of the Arduino on the stereo board.
Note: Do not plug the board into the stereo and the FTDI programmer at the same time.
When the stereo has connected to the MQTT broker, you should see a wi-fi icon appear on the display. You can now issue voice commands to Alexa and the stereo will respond.
In the car you will of course need a wifi connection to use the voice commands. I use a small pocket wifi unit (Prepay Pocket WIFI R209ZR). The stereo will connect and be ready within about 30 seconds, the Echo Dot takes a bit longer to boot and connect.
Say: Alexa, open car stereo
Response: What would you like to listen to?
You can then say things like:
Play some Billy Joel (will play a random Billy Joel album if you have more than one)
Play River of Dreams (will play an album)
Tune to More FM (tune to a station)
Bluetooth on (toggle bluetooth)
If you install Reverb for Amazon Alexa app on your phone (basically Amazon Alexa on your phone), then you can use voice control without an Echo Dot in your car. Note that you will still need the Pocket WIFI for the stereo connection.