Introduction: Roulette Party Music Player

This is the Roulette Party Music Player, because everything's better with a little bit of risk right?

When setting up music for a gathering of friends (party, game night, seance, etc.), you really have two options. You can lock everything down with a per-determined playlist and listen to everyone complain at some point about the "terrible" music or you can leave the selection open and deal with people's MADD (Music Attention Deficit Disorder) and passive aggressive battles over the genre.

The RPM Player is sort of a compromise between the two: you determine what songs are available and the guests can choose to randomly change the song at will, but this is where the twist, and roulette reference, comes in. Besides placing all your chosen music on the player you've also chosen a number of songs that most people would agree are "bad". These can be truly terrible songs, the worst ear worms, or just utterly out of place for the setting (Kenny G Christmas at an August BBQ). When someone chooses to skip a song they run the risk of pulling one of these "gems" at which point the player promptly disables the button and forces you to listen to the song, thus giving everyone else plenty of time to heap ridicule and shame on the unfortunate gambler.

Note: Thanks to Youtube's overzealous song matching copyright protection there won't be a video of this in action.

Step 1: Materials & Tools

Materials

  • Arduino UNO
  • Seeedstudio MP3 Shield v1 - There are a lot of different options for MP3 shields ranging in features and costs. This one probably isn't the best option being that the documentation and software support is buggy and limited but it is cheap and shipped quickly
  • SPST Switch - You can use the on-board Volume Up button without changing the code. The switch is for style.
  • Switch Cover (Optional) - Prevents accidental triggering and just looks cool.
  • Enclosure - In the end design and construction are of very little consequence. I used an old box from a cell phone. Something custom and 3D printed was in the works but just didn't materialize.
  • 2 GB Micro SD Card - Another limitation of the v1 Seed shield is it's 2GB size limit. Obviously the exact size can be catered to your shield and storage needs.
  • 3.5mm Audio Aux Cable - These are the standard male-male audio cables.
  • Power Supply/Batteries (Pack or Pile) - Whatever you usually use for Arduino projects. If this is your first Arduino project then you're looking for 7-12V. 9V is probably the safest and most commonly used.
  • Speakers - These will either need to be low power or externally powered. They will also need to except a standard 3.5mm audio plug input or you will need to provide adapters between.
  • Music - Most digital music distributors (Amazon, Google) now offer DRM free downloads as standard so don't be a gibbon, buy your music.

Tools

  • Micro SD Card Reader
  • Soldering Equipment

Step 2: Hardware Setup

This is a pretty hardware light build since the MP3 shield contains almost everything we need. In fact you can even get away with doing nothing but attaching the Music Shield and powering the board if you so choose. If you want a little more style though you can easily attach a different style switch, in my case a push button with a big red switch cover.

In the code, the volume up button on the shield, pin 3, is selected as the one to kick everything off and select a random song. If you're not adding your own switch then all you need to do is make sure that the V+ button is accessible.

If you are spicing things up then start by bending the "VU" pin up and out of the way on the shield. This is the fourth pin from the right on the side with the buttons and corresponds to the "3" pin on the Arduino. If you have to connect your own leads to the switch do that before proceeding.

With the pin out of the way the hot wire from your switch can be plugged into the space it vacated. Finally find a way to wire the switch to ground, I used an empty spot on the shield that is supposed to support a 30-pin iPod connector, and slap the shield on top of the Arduino.

Step 3: Get Some Music

Before you start in on the code you need to do a little legwork with the music. I used a 1:4 bad-to-good ratio for my songs but you can tweak that as you see fit. During my digging in the code it appears that the music shield I bought has a playlist limit of 100 songs. It's entirely possible that once it hits this limit it simply clears the list but the time required isn't worth it since 100 songs is around four hours of music. This leaves me with 75 good songs and 25 bad, time for a...

Aaaaaaand we're back, I'll assume you've purchased and downloaded your music at this point and are ready to move on.

You need the Arduino code to be able to construct the full path of your songs on a random basis. This means the file names need to have an incrementing numerical component and be otherwise identical. The simplest way to to do this is to rename all the files (or more conveniently, copies of the files) as just a number starting at 01 and incrementing through the last file. The result is: "01.mp3, 02.mp3, ..., 099.mp3, 0100.mp3" (The proceding 0 is necessary because of the code). Just be aware that you need to know where your bad songs are and they need to be in one block. For me songs 1-75 are good and 76-100 are bad. I used a program called Bulk Rename Utility which is powerful but not especially user friendly.

With your files renamed, transfer them to the root level of your micro SD card. The card should be formatted using the FAT16 format prior to transferring any files.

Step 4: Software

As stated earlier, the documentation and libraries for the v1 Seeedstudio music shield are a bit shoddy and under supported. I eventually tracked down a fixed set of the libraries needed to actually get this running and they are attached below. You will need to add the three folders to your Arduino libraries folder as you would with any other library.

Now is the point in this step where I proceed to ramble about the inner workings of the sketch. If that doesn't interest you then feel free to move on, you're not missing anything critical, but if you stay you just might learn something.

First off we call a lot of libraries. These are all used by the music shield to do various things like read from the SD card, transmit the audio, and decode the .mp3 formatted songs. With the libraries out of the way the music player itself is initiated and our global variables are declared.

#include <Fat16.h>

#include <Fat16Util.h>

#include <NewSPI.h>

#include <arduino.h>

#include "pins_config.h"

#include "vs10xx.h"

#include "newSDLib.h"

#include "MusicPlayer.h"

//Music player initiation

MusicPlayer myplayer;

//Variables

char title[8]; //holds the assembled music track title

long trackNum; //holds the randomized track name

boolean switched = LOW; // tells if switch has been thrown

Moving into setup() we begin to, well, setup the music player. This includes allowing digital control, starting the player in normal mode, and assigning the random song selection function to our button. after that we draw a seed for the random number generator from an unattached analog pin and choose the first song.

myplayer.keyDisable();

myplayer.digitalControlEnable();

myplayer.begin();//will initialize the hardware and set default mode to be normal.

myplayer.attachDigitOperation(3, randomSong, HIGH);

randomSeed(analogRead(4));

Any time a song is chosen the code must build the file name of the song in three steps. First it adds a "0" as a string. Since the file names are strings it is easiest if we start building from a string. This is why every music file needs to have a 0 as the first character. Next it chooses a random number from the available set (1-75 for normal mode, 1-100 for gambler mode) and concatenates that to the string containing the 0. Finally the file extension, .mp3, is slapped on the end and the whole thing is written to a character array.

String base = "0";

trackNum = random(1, 76);

base.concat(trackNum);

base.concat(".mp3");

base.toCharArray(title,9);

Now we enter our main loop and begin by setting the player to normal mode and beginning playback of the first song. At this point the code holds at line 41 until either the song ends, which makes sure the button is unlocked and picks a new song, or the button is pressed. When the button is pressed it activates the function that we tied to the button in setup().

myplayer.setPlayMode(MODE_NORMAL);//set mode to repeat to play a song

myplayer.playSong(title);//play a song named with test.wav

switched = LOW;

The randomSong() function begins with simple form of debounce that probably isn't really necessary and then moves to check if the button is unlocked. If it is then it stops the player, selects a new song from the entire set, adds that song as the next in the playlist (don't even get me started on this shield's playlist system), advances the playlist to the new song, and locks the button down.

if (switched == LOW){

playingState = PS_STOP;

. . .

myplayer.addToPlaylist(title);

playingState = PS_NEXT_SONG;

switched = HIGH;}

Step 5: Assemble

I prepped my enclosure by simply painting over the front panel with the phone logo, as the rest was plain white already. Then a quick hole in the middle of the front panel and we're ready to add the switch, and optional cover. With the button ready all that remains is to place the power pack and Arduino in the case and run the aux cable out. My aux cable was flat so there was no need for a hole but you may have to drill one if you are using a round cable.

Step 6: Party!

Power it up and be ready to shame and ridicule your friends and their poor impulse control!

Thoughts/Issues

First off, this initially was supposed to be a IoT project using the Intel Edison but something went wrong during development and the breakout board caught fire. More specifically the voltage regulator for the full size USB ports released it's magic smoke which meant I no longer could interface the Edison with the USB sound card that was necessary to actually, you know, play music. Fortunately the rest of the board and chip seems to have survived allowing my next project to continue.

I chose the Seeedstudio v1.0 music shield for a couple of reasons. First off was cost, coming in at least half the cost of most other full feature music shields, which was perfect for a silly project like this. The second was time. When the Edison quit/spontaneously combusted it left me short on time and the possible multi-week wait for a better board in my price range wouldn't work. I paid for it though in the form of broken libraries and clunky file structure support.

If this ever gets the Mk.2 treatment it definitely will be with a shield that has working libraries that are readily available and not rebuilt by a heroic community member and buried in a long forgotten forum post. I was also hoping to go with a 3D printed case but as other things went wrong it didn't seem like a cost or time effective solution.

There is still one bug that has me completely baffled. Occasionally when running with the board only connected to external power it will act like the random switch is constantly being depressed. Meaning the button has no effect and it randomly shuffles through all 100 songs not just the first 75. Plug it back into the computers USB (externally powered or not) and reset and it's suddenly working fine again. I'm going to try swapping to a fresh UNO but I suspect that the shield (and more specifically, its patched together libraries) is somehow to blame. I'll be sure to post if I find the solution.

Conclusion

If I'm honest, overall I'm a little disappointed in the presentation of the final product but I'm proud of the code and it's simplicity (although I know there are a couple of optimizations I chose to leave on the table due to time). In the end the premise and end result still amuse me so, mission accomplished I guess.

Thank you for spending your valuable time reading this. As always ask any questions, make any comments, and post any pictures if you make your own!

Comments

author
RustyM1 (author)2015-03-31

You probably need to de-bounce your button to stop it from getting "stuck".

author
bwrussell (author)RustyM12015-03-31

Stuck? I think I know what you're getting at but not sure specifically what you're referencing.

author
LilWiz333 (author)bwrussell2015-04-16

You stated "....will act like the random switch is constantly being depressed." That is what I meant by stuck.

My understanding is that if a switch is not properly de-bounced, it may be in a state that we do not intend. Imagine the button not depressed is represented by a 0 and depressed by a 1. Ideally, if we watched a constant polling of the switch state (most likely represented by some variable in programming) , we would see a stream of zeros until the button was depressed, and then a stream of ones until we stop depressing it and then back to a stream of zeroes again. If the switch is not properly de-bounced it is possible that when we release the button, we would continue seeing a stream of ones and therefore the switch is "stuck" in a depressed state (Actually it is the programming variable that is "stuck" as opposed to the physical button).

author
bwrussell (author)LilWiz3332015-04-16

In my experience debouncing is mostly used to prevent small variations in voltage and/or current from causing unwanted triggers of the switch. A switch without any form of debounce is also very sensitive, making accidental triggering almost assured. Regardless of the use of debounce I don't think it's related to the issue.

I don't think I made it clear enough in the write up but the bug happens as soon as the Arduino is unplugged from the PC, regardless of whether the button has been pushed or not, or if the Arduino was even on when the USB was removed. I need to put in a little debugging code to print the button state to a file on the SD to see if it's even responding when it's only on external power. I suspect it isn't.

Based on some of the debugging I've attempted I suspect there is something in the shields library that is causing this. Essentially I think the shield is reverting to it's normal play mode, disabling the digital control, and just playing everything on the SD card. Given some of the other issues/inefficiencies with this shields firmware makes it a prime suspect.

author
cruelgreedy (author)2015-03-31

Stuck? I think I know what you're getting at but not sure specifically what you're referencing.

author
bwrussell (author)cruelgreedy2015-04-01

???

author
seamster (author)2015-03-31

Oh man, this is a brilliant idea. Love it!

Is this something you'll revisit try to iron out the kinks?

author
bwrussell (author)seamster2015-03-31

Thanks! I'm glad you like it.

Honestly I'd love to revisit most of my projects because there's always something that doesn't work quite right or a feature that got left on the bench but obviously that's not feasible. With the rise of miniaturized computers and since it didn't quite end up like my vision I think this might be one of the more likely to see a revisit.

I am going to put a little time into working out the dead button bug because it's truly baffling (which means the solution is probably obvious but out of my sight somehow) and because it essentially kills it when it crops up.

About This Instructable

7,505views

126favorites

License:

Bio: Why buy when you can DIY? Educated a Mechanical Engineer and trained as a classical cellist I consider myself a bit of a jack-of-all-trades, dabbling ... More »
More by bwrussell:Replacement PC Case Power SwitchLaser Engraved QR & NFC WiFi Access Card3-Ingrediant Taco Meat
Add instructable to: