Introduction: Touchscreen Musicbox With Lightshow

About: student NMCT at Howest (Kortrijk Belgium)

***

UPDATE: here's my second attempt at the musicbox:

https://www.instructables.com/id/Touchscreen-Musicbox-With-Lightshow-20/

***

Hi and welcome to my first Instructable!

As a student in New Media and Communication Technology, we get lots of project assignments throughout the year. This is the first one where we have to publish our project as an Instructable.

I like music a lot, so I decided to implement this in my project. I thought of something that would make for a fun little gadget to put on your desk or in your living room.
A music player looked like a great idea, but to me it was a bit too simple... So I decided to add a lightshow.

Our assignment required us to use Raspberry Pi, so I decided to use that for the music player. For the Lightshow, I looked for something familiar. I had the most experience with the Arduino, so that was what I went for.

This is how I got the idea of my project, now let's get right into the first step!

Step 1: Materials

First of all, let's have a look at what materials we need for the Music Player:

  1. Raspberry Pi (almost any version will do)
  2. SD card (8GB is probably the best)
  3. Touchscreen for the Raspberry Pi
    (I used the Adafruit PiTFT, but I had a LOT of trouble with it, so I would recommend a different one)
  4. A speaker for the Raspberry Pi
  5. USB swivels (to make the USB ports of your Pi more flexible)

Then for the Lightshow you'll need:

  1. Arduino UNO (or any higher version should work as well)
  2. Breadboards (1 or two depending on how many LEDs you're using)
  3. Potentiometer (to manipulate the lightshow speed)
  4. LEDs (as many as you want!)
  5. lots of cables (depends on your amount of LEDs)

Finally, you'll need some Plexiglas for the box. You could get some decorative stickers if you want.

In the file below, you'll find a list with all these items and where to buy them (from the Belgium area).

Step 2: Lightshow With Arduino

Let's start with the most fun (and the easiest) part: the Lightshow!

There's multiple ways you can do this, but by far the easiest is to code the Lightshow, upload it to your Arduino and voila!
You could also try doing it straight from the Raspberry Pi with the pyserial library in Python. If you're experienced at Python, Raspbian and Arduino, you should be able to do this, but you'll be making it very hard for yourself when there's a very simple way to do it that is just as much fun.

Install the Arduino software

This should be fairly easy, just go to the Arduino website and download it there.

Plug in your Arduino

Plugging in the Arduino will make it install all its drivers automatically, so no worries there.

Open the IDE

In this enviroment, we'll start to code our lightshow, just open a new blank file and let's begin!

Coding

GitHub link

The code is quite simple, you read the value from the potentiometer to determine the length of the delay between putting lights on or off.
You can tweak the code a bit if you want a different kind of lightshow (for example, make the lights go on from left to right)

After you're done checking out the code, just verify it and upload it to the Arduino.

//Variables
int potpin = 1; //Potentiometer pin (analog)
int val = 0; //to store the Potentiometer value
int randNumber1 = 0; //to store the random number
int randNumber2 = 0; //to store the random number

void setup()
{
  //set LED pins to output
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop()
{
  randNumber1 = random(2, 12); //random number between 2 and 11
  randNumber2 = random(2, 12);
  val = analogRead(potpin); //read the Potentiometer value and store it
  
  if (val <= 1010) //if the potentiometer is not turned all the way down, start lightshow
  {
    analogWrite(randNumber1, 255); //turn one of the LEDs on
    analogWrite(randNumber2, 255); //turn one of the LEDs on
    delay(val); //wait
    analogWrite(randNumber1, 0); //turn that same LED off
    analogWrite(randNumber2, 0); //turn that same LED off
    delay(val); //wait
  }
  else //if the potentiometer is all the way down, turn off all LEDs
  {
    for (int i=2; i < 12; i++){
      analogWrite(i, 0);
   } 
  }
} 

Assemble the circuit

Now all we need to do is put the lights in the lightshow. Check out the pictures for some more info.

All done!

Now you should be able to control a lightshow with the potentiometer!

Step 3: Raspberry Pi Setup

With the Lightshow done, now comes the hard part;: the music player with touchscreen.

Again before we start, I have to say that I find the Adafruit PiTFT very annoying to use. It's not very responsive, very small and it makes your Raspbian OS very difficult to use. I recommend using a different one than this.

Touchscreen setup

The installation of the touchscreen I used can be found here: adafruit.
I suggest using the image and burning it into an empty SD card.

If you have trouble with the touchscreen (I for example couldn't get the touch aspect to work). Consider buying a new copy (this solved my problem as the first one I bought was apparently broken)

Since the screen is so small, it might be smart to hide your taskbar when it's not used, so you have more space.

Coding

GitHub link

Now to start coding our music player.

Be sure to check if you installed all the libraries that are imported at the start of the code. Or else you'll run into trouble. (Googling the library names will get you to their installation guides)

The code isn't that hard and I expain a lot in the comments as well, so have a look:

"""
Imports
"""
import easygui		#easygui library for the interface
import glob		#to read file location
import pygame		#to play the music

"""
Variables
"""
#initialize mixer and load the songs
pygame.mixer.init()
playing = 0
songlist = glob.glob('/home/pi/Music/*.mp3')

#variables for the choicebox
lst_message = "Choose a song."
lst_title = "Music Player"
lst_choices = glob.glob('/home/pi/Music/*.mp3')
#remove path and extension
for index in range(len(lst_choices)):
	lst_choices[index] = lst_choices[index].replace('/home/pi/Music/','')
	lst_choices[index] = lst_choices[index].replace('.mp3','')

#variables for the buttonbox
btn_message = ""
btn_title = "Playing Song"
btn_choices = ["Different song","Pause/Play","Quit"]

"""
MusicPlayer loop
"""
#automatically start loop first time
while True:
	#open choicebox with songs
	lst_choice = easygui.choicebox(lst_message, lst_title, lst_choices)
	
	#check if your choice is a song
	for index in range(len(lst_choices)):
		if lst_choice == lst_choices[index]:
			#load song and make it ready to play
			pygame.mixer.music.load(songlist[index])
			#play the song
			pygame.mixer.music.play()
			#set integer that tells us the song is now playing
			playing = 1
			#message that tells us the song is playing
			btn_message = "Now playing " + lst_choices[index] + "."
			while True:
				#buttonbox that opens when song plays
				btn_choice = easygui.buttonbox(btn_message, btn_title, btn_choices)
				#if pause is pressed, check if song is playing or not and then go back to buttonbox
				if btn_choice == "Pause/Play":
					if playing == 1:
						pygame.mixer.music.pause()
						playing = 0
						continue
					elif playing == 0:
						pygame.mixer.music.unpause()
						playing = 1
						continue
				else:
					break

	#if different song is pressed, go back to choicebox (restart loop)
	if btn_choice == "Different song":
		btn_choice = "";
		continue
	#if quit is pressed, close app and stop music
	elif btn_choice == "Quit":
		pygame.mixer.music.stop()
		btn_choice = "";
		break
	#if nothing has been chosen, also close app and stop music
	else:
		pygame.mixer.music.stop()
		btn_choice = "";
break

File management

The code should be store in a *.py file. What we now could do is make a desktop shortcut to make it more nice to interact with. For this you'll need to make 2 files (these are made assuming that you named the file MusicPlayer.py and placed it in the Music folder of the Raspberry Pi):

[Desktop Entry]
Name=MusicPlayer
Comment=Starts the Music Player python app
Icon=/usr/share/pixmaps/pimixer.xpm
Exec=lxterminal -t "Starting Music Player" --working-directory=/home/pi/Music/musicplayer -e ./StartMusicPlayer.sh 
Type=Application
Encoding=UTF-8
Terminal=false
Categories=None;

This was the Shortcut file that you see on the picture.

#! /bin/bash
cd /home/pi/Music/musicplayer &>/dev/null
sudo python MusicPlayer.py &>/dev/null

This little script starts the python MusicPlayer in silent mode (not showing terminal commands.

Add Songs

Now to add some songs!

The easiest way is to just use the USB drive to transfer songs, but you can also download them from the Pi if it has internet connection. (BE SURE TO PUT THEM IN THE RIGHT FOLDER)

Done!

Now go and test your music player.

Step 4: Database

Part of our assignment was to make a Database as well. Here however, I encountered a big problem. When I tried to install MySQL on my Raspberry Pi, it said I had to run 'sudo apt-get update' if I wanted to install it. The problem is that if I run that command, the newly installed kernel (for the Adafruit Touchscreen) will be overwritten, this way it's not possible to install MySQL on the Pi. I've tried installing older versions of MySQL, but to no avail. So if you really want a database, don't use the touchscreen.

Yet, to show I do have the skill of creating, reading and writing databases, I created some code that does include SQL statements in Python: these can be found here. (GitHub link)

Check out the ERD of my database to see what I had planned!

Step 5: What's in the Box?

Now to create the box.

The sketch I made is the easiest way I could think of to get all of these parts together. yet when I tried to get them all together, well... let's just say it didn't go as planned (at first).

This can be the tricky part. The way I see it, there are 3 ways to make the box:

  • Glue
  • Tape
  • Drilling

I first tried with glue, but I probably used a wrong kind of glue because my Plexi just didn't stick. I then tried with tape, but it just looked more messy and not very appealing.

Eventually we used a drill to get the Plexiglass in a box-shape. I'm pretty sure you can get some decent glue or tape for this, but I didn't have any around at that time so drilling was my only option.

The inside of the box is quite loose so it's easy to move around with all the Arduino cables. This way you can also place LEDs wherever you want to get some more light out of them.

Be sure to watch out that no cables get disconnected while you're assembling the box, that's why I recommend leaving the top loose so you can easily get inside and tweak/repair a few things.

Step 6: Party!

Now that you assembled the box, everything should be good to go!

I hope you guys enjoyed my first Instructable, I know it's far from perfect and I still have a lot to learn, but I hope you enjoyed it.
Feedback and (constructive) criticism would be greatly appreciated ;)

Party on!