Touchscreen Musicbox With Lightshow 2.0
by SamTeerlinck in Circuits > Raspberry Pi
1484 Views, 12 Favorites, 0 Comments
Touchscreen Musicbox With Lightshow 2.0
Hi!
Here we are again with another musicbox! This is my second attempt at my original Touchscreen musicbox from a few months ago.
Although it was a fun project that looked cool, it was not perfect and some parts were unfinished. Now I'm doing this project again and I tried my best to improve it in every way possible.
Be sure to give my first instructable a quick look so if you want some more info on why I chose this project and how I came to the idea of a musicbox.
Without further ado, let's start with the project!
Materials
First of all, let's have a look at what materials we need for the Music Player:
- Raspberry Pi (almost any version will do)
- SD card (8GB is probably the best)
- 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) - A speaker for the Raspberry Pi
- USB swivels (to make the USB ports of your Pi more flexible)
Then for the Lightshow you'll need:
- Arduino UNO (or any higher version should work as well)
- Breadboards (1 or two depending on how many LEDs you're using)
- Potentiometer (to manipulate the lightshow speed)
- LEDs (as many as you want!)
- 220/330 Ohm resistors (one for each LED and 1 for the Potentiometer)
- 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).
Downloads
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
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 <= 900) //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!
Downloads
Raspberry Pi and MusicPlayer
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
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:
#Here we import all the required libraries import os import pygame from Tkinter import * import tkFileDialog import random import MySQLdb #Connect to the database with played songs db = MySQLdb.connect("localhost", "root", "root", "musicplayer") curs=db.cursor() #Create Tkinter screen root = Tk() root.minsize(320,240) listofsongs = [] realnames = [] v = StringVar() songlabel = Label(root,textvariable=v,width=35) shufflevar = IntVar() shufflevar.set(0) index = 0 numberrandom = 0 #Choose the directory with the songs def directorychooser(): directory = tkFileDialog.askdirectory() os.chdir(directory) for files in os.listdir(directory): if files.endswith(".mp3"): listofsongs.append(files) #Start playing the first song pygame.mixer.init() pygame.mixer.music.load(listofsongs[0]) pygame.mixer.music.play() #Send to database curs.execute("INSERT INTO playedsongs (song, playeddate, playedtime) values(%s, CURRENT_DATE(), NOW())", (listofsongs[index].replace(".mp3",""))) db.commit() v.set(listofsongs[index].replace(".mp3","")) #Start directorychooser directorychooser() #Update the label with the song name def updatelabel(): global index global songname v.set(listofsongs[index].replace(".mp3","")) #Return songname #Pause when it's playing, play when it's paused def playpause(event): global index if pausebutton["text"] == 'Pause': pygame.mixer.music.pause() pausebutton["text"] = 'Play' elif pausebutton["text"] == 'Play': pygame.mixer.music.unpause() pausebutton["text"] = 'Pause' #Next song in the list (+1) def nextsong(event): global index #Check if shuffled if shufflevar.get() == 1: numberrandom = random.randint(0,len(listofsongs)-1) while index == numberrandom: numberrandom = random.randint(0,len(listofsongs)-1) index = numberrandom pygame.mixer.music.load(listofsongs[index]) pygame.mixer.music.play() curs.execute("INSERT INTO playedsongs (song, playeddate, playedtime) values(%s, CURRENT_DATE(), NOW())", (listofsongs[index].replace(".mp3",""))) db.commit() updatelabel() else: if index < len(listofsongs)-1: index += 1 pygame.mixer.music.load(listofsongs[index]) pygame.mixer.music.play() curs.execute("INSERT INTO playedsongs (song, playeddate, playedtime) values(%s, CURRENT_DATE(), NOW())", (listofsongs[index].replace(".mp3",""))) db.commit() updatelabel() #Previous song in the list (-1) def prevsong(event): global index #Check if shuffled if shufflevar.get() == 1: numberrandom = random.randint(0,len(listofsongs)-1) while index == numberrandom: numberrandom = random.randint(0,len(listofsongs)-1) index = numberrandom pygame.mixer.music.load(listofsongs[index]) pygame.mixer.music.play() curs.execute("INSERT INTO playedsongs (song, playeddate, playedtime) values(%s, CURRENT_DATE(), NOW())", (listofsongs[index].replace(".mp3",""))) db.commit() updatelabel() else: if index > 0: index -= 1 pygame.mixer.music.load(listofsongs[index]) pygame.mixer.music.play() curs.execute("INSERT INTO playedsongs (song, playeddate, playedtime) values(%s, CURRENT_DATE(), NOW())", (listofsongs[index].replace(".mp3",""))) db.commit() updatelabel() #Stop playing song and clear label def stopsong(event): pygame.mixer.music.stop() v.set("") #Tkinter objects label = Label(root,text='Selected songs:') label.place(x=5,y=5) listbox = Listbox(root) listbox.place(x=5,y=30) listofsongs.reverse() indexforloop = 1 for items in listofsongs: listbox.insert(0,str(indexforloop) + ". " + items.replace(".mp3","")) indexforloop += 1 listofsongs.reverse() pausebutton = Button(root,text = 'Pause') pausebutton.place(x=180,y=40) nextbutton = Button(root,text = 'Next Song') nextbutton.place(x=180,y=70) previousbutton = Button(root,text = 'Previous Song') previousbutton.place(x=180,y=100) stopbutton = Button(root,text='Stop Music') stopbutton.place(x=180,y=130) shufflechkbox = Checkbutton(root,text = 'Shuffle', variable=shufflevar, onvalue = 1, offvalue = 0) shufflechkbox.place(x=180,y=160) pausebutton.bind("<Button-1>",playpause) nextbutton.bind("<Button-1>",nextsong) previousbutton.bind("<Button-1>",prevsong) stopbutton.bind("<Button-1>",stopsong) songlabel.place(x=40,y=185) root.mainloop()
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. Since there is a directorychooser present this time, you can play music from whichever folder you prefer (even USB sticks).
Done!
Now go and test your music player.
Top 5 and Database
Apart from the Musicplayer being very much improved, this database and Top 5 is also a big improvement compared to my first attempt.
This is the guide that I followed to get a webserver installed on my Raspberry Pi: webserver guide.
And here you will find the Top 5 python code (again also available on Github).
#Import required libraries import MySQLdb from Tkinter import * #Create Tkinter screen root = Tk() root.minsize(320,240) #Connect to Database db = MySQLdb.connect("localhost", "root", "root", "musicplayer") curs=db.cursor() #Show Top 5 most played songs curs.execute ("SELECT song, COUNT(*) Amount FROM playedsongs GROUP BY song ORDER BY amount DESC LIMIT 5") index = 1 top5list = "" #Display Top 5 for reading in curs.fetchall(): top5list += "Nr. " + str(index) + " = #" + str(reading[1]) + " " + str(reading[0]) + "\n" index += 1 #Tkinter label with Top 5 label = Label(root,text= 'Top 5 played songs \n \n' + top5list, anchor = W, justify = LEFT) label.place(x=5,y=5) root.mainloop()
I also added a desktop link and a bash file (similar to the Musicplayer), just copy the .desktop and .sh files from the MusicPlayer and change the destination to Top5.
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.