What do you get if you cross an Arduino Mega, an MP3 decoder, an SD card, and a nokia LCD?
If you throw in several hundred hours of programming, and a few thousand lines of code, you get an MP3 player :D.
For an Embedded systems module at Uni, I decided to be over the top and try to push what an 8 bit microcontroller can do to the absolute maximum. I finished the project at the end of last year, but as I need do a write up on it for the Uni, I thought I would refresh my memory and post it here.
Final Project on custom PCB (hand soldered :D)
When it is turned on, first it checks all the hardware is working, then updates the song library. There is a text file in which the user simply enters the filename of any songs they want to add (less extension) on a new line at the top, with a + in front of each if it is a song file, or an @ in front if it is Album Art.
The software then checks that each song exists, and then using TAG data from the song, it adds the song to the library under the correct Artist and Album (Each artist has a text file containing a list of Albums - each line contains the name of an album, and the filename of its index). In the Album index file is a list of the name of each song, and its filename. If an album or artist exists, then the song is placed in the correct file, else a new artist or album file is created. The files are used later to display data onscreen.
If any new Album art is added (a standard 24bit BMP file, or any size greater than or equal to 128px square), then the image is checked to be a valid bitmap and then converted into a file containing 12bit pixel colour data for use by the screen. If the image is larger than 128px square, it is rather nicely scaled down to the correct size with my own image scaling method. Images can then be assigned to album(s) to which is belongs.
If an album doesn't have any Art assigned, it uses a default image, which is just a picture of a music note.
After that is all done, it moves to the song selector. This allows the user to pick a song or album to play, or alternatively, allows the creation/naming/renaming/deletion/editing of custom playlists.
There is also a page which shows a list of settings - screen brightness, contrast, dimmed brightness. These settings can be changed.
When a song/album/playlist is selected to be played, it moves on to the Media Player portion of the code. This displays the album art for any given song, begins to buffer the song into some FeRAM (Not enough for a whole song, but enough that while the MP3 decoder is processing the last batch of data, the buffer can be refilled fom the SD card), and then sends the data to an MP3 decoder IC (STMicroelectronics STA013S) for playback.
The media Player also scrolls through the Tag information - showing album name, artist name, track name, year, track number, and also the Genre (decoded with a lookup table).
There are options for play, pause, stop, skip, mute, volume control, repeat, and random shuffle (doesn't repeat any song until all have been played). There is also an option to turn the MP3 player off.
Volume is shown on a bar graph. To save space onscreen, every few seconds, the bar graph is replaced by a symbol showing battery level, and whether it is charging.
The screen is automatically dimmed after 1 minute of no user activity (it continues to play the song though). Any activity on the trackball will brighten the screen again. Also when the battery starts to run low, the screen is permanently dimmed to save power.
If you unplug the headphones, playback is automatically paused until they are reconnected, at which point it resumes.
Everything is controlled through just the trackerball which is setup to trigger 5 pin change interrupts.
I think that just about covers all the features.
List of Artists:
Scrolling to the left there is a list of playlists:
To delete or rename, you click on rename or remove, and then the next playlist you click will have that action performed on it. To create a playlist, just click create, or to edit one, click on that playlist. This will then allow you to move through the list of songs selecting songs or whole albums you want in the playlist. Anything in the playlist is highlighed blue. Clicking on a blue item removes it from the playlist, clicking again readds it.
Scrolling Left from a playlist shows you songs in the playlist:
and allows you to start playback by clicking on a song in this list - it will then play all songs in the list starting with the one you clicked.
If the cursor was hovering over create,delete, or rename, then instead of showing songs in the list, it moves to the settings page, where clicking on a setting and scrolling left/right changes it. Click again to save.
Scrolling right moves back a page until you reach the Artist page.
From there scrolling right displays a list of albums by the highlighed artist:
Clicking on an album plays all songs in that album.
Scrolling right from an album shows songs in the album:
clicking on one plays just that song.
You can scroll left to move back a page until you reach the Artist page again.
Firstly, it loads the album art of the song, and then buffers the song into the onboard FRAM (this takes <2 seconds):
Then starts playback, showing song information at the bottom. The media player buttons are shown at the top, as is how much of the song has been played, and how long is left. There is a portion of the media player that toggles between showing battery level, and volume level:
If the headphones are unplugged, the song is paused, and the speaker symbol is replaced by an x. A message at the bottom informs you to reconnect the headphones:
Left an right scrolls move which button is highlighed. Clicking informs the button to do its funtion. In the case of the speaker being highlighted, clicking mutes, while scroll up and scroll down change the volume level.
In this case the volume button is highlighed, and I scrolled up to increase the volume. The volume graph increased as can be seen by comparing it to one of the previous screenshots:
Non active funtions are shown in red, for example the shuffle and repeat buttons on the left. When one of these is clicked, it is activated and turns blue, e.g. here shuffle is clicked to activate:
Thats about it :D.
PS. The code is 95kB, and takes over a minute to download! :D
Any chance we can see the code? :)
Sure, I have attached the code.
There are two libraries (my gLCD library, and a second which is a merger of a modified SD library, the SPI library, the Wire library, and a couple of other bits to control the memory modules and STA013 chip).
Then there is the ino sketch.
I'm sure there are lots of ways in which the code could be improved, but this was one of the first things I made with an arduino. :)
Total noob here. Just started with arduino [and electronics in general . I am programmer by profession]. This looks very interesting[and complicated] to me. Would love to have more details on how to build one? Have lots of questions, some one please answer them if possible. 1. Can we use any other chip for decoding MP3 ? 2. Can we decode Flac ? 3. Can we use an high quality audio DAC with this same setup?
Woot! Huge kudos to you Tom! That is one heck of a build.
There are LOTS of chips out there that will decode MP3 (or OGG or WAV or <insert format here>). I use the VS1053b made by VLSI and as an added bonus, you get MIDI functionality with a bank of instruments! This is the same decoder used in the Sparkfun MP3 shield (https://www.sparkfun.com/products/10628). If you're looking for a relatively simple way to get started on mp3 I would look at getting that shield. There is also example code provided. Ladyada (http://www.ladyada.net/make/minty/hardware.html) also has a run through of the MP3 player she made a while back.
Would it be possible to re-write the code to use buttons instead of a trackball?
Please forgive my ignorance, I've never done this before.
It shouldn't need any change. Simply connect push buttons to each of the Up, Down, Left, Right, and Button pins, with the other end going to ground.
You should post a video showing it in action.