Introduction: Disco-pi

About: A Raspberry Pi enthusiast with a passion for making things smarter and more connected

This instructable shows how to use a Raspberry Pi to control a coloured LED strip, based on music played from a web browser.

It shows how to create a basic website using Node.js over HTTPS and use socket.io over WSS (Secure Websocket).

The website has a single page which has a very basic layout. The webpage populates a drop down list with music files, which are located in the public/audio folder on the server. Selecting an option in the list plays the music file in the webpage using the HTML 5 audio element. While playing the music file, the webpage uses the AudioContext interface to analyse the music, which is then sent to the server over a secure websocket connection.

The server running on a Raspberry Pi uses the Node RPI WS281x Native library (wrapping Jeremy Garff's WS281X library) to change the colours of the LEDs on a WS2811 LED strip, based on the data sent through the websocket.

The example code can be found here: disco-pi

Step 1: Equipment

  1. Raspberry Pi - I used a Raspberry Pi 2B that I had laying around, but you can get a Raspberry Pi 3 Starter Kit for around CAD 100
  2. WS2811 LED Strip - I was playing with ALITOVE 16.4ft 150 Pixels WS2811. This comes with a controller and a power supply for about CAD 45-50
  3. Barrel Jack Connector - I bought one from my local electronics shop, something like this. Just make sure if fits your power supply
  4. Jumper Connectors / Wire - I had some Female to Male connector cables and some 22 Gauge Solid hook up wire lying around

Step 2: Setting Up the Raspberry Pi

Operating System

I normally use the latest Raspbian build. Download the image and write it to the SD Card. If you are using a Windows computer, you can use Win32 Disk Imager to write the image to the SD Card.

Node.js

Install the latest version of Node.js. At the time of writing I am using 8.9.1

curl -sL <a href="https://deb.nodesource.com/setup_8.x" rel="nofollow"> https://deb.nodesource.com/setup_8.x </a> | sudo -E bash -
sudo apt-get install nodejs

Install git

sudo apt-get install git

Step 3: Setting Up the Example Code

Clone the example code

1. Set up a base folder to install into

cd /opt
sudo mkdir com.jonhaydock
sudo chown pi:pi com.jonhaydock<br>cd com.jonhaydock<br>

2. Clone the example git repository

git clone https://github.com/haydockjp/disco-pi.git"

or

git clone  git@github.com:haydockjp/disco-pi.git

3. Install the dependancies

cd  disco-pi
npm install

This might take 2-3 minutes

Step 4: Create a Self Signed SSL Certificate

1. Create a private key file

cd /opt/com.jonhaydock/disco-pi/certs
openssl genrsa -out disco-pi-key.pem 2048

2. Create a CSR (Certificate Signing Request)

openssl req -new -key disco-pi-key.pem -out disco-pi-csr.pem

At this point you will be prompted for some information for the certificate request. As this is a self signed certificate, it is up to you how accurately you fill in the details. Here is an example

Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:British Columbia
Locality Name (eg, city) []:Vancouver
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Disco Pi
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:disco-pi
Email Address []:disco-pi@jonhaydock.com

A challenge password []:
An optional company name []:

In this example, just press return to leave the challenge password blank

3. Generate the certificate

openssl x509 -req  -days 1095 -in disco-pi-csr.pem -signkey disco-pi-key.pem -out disco-pi-cert.pem

4. For extra security we will also create a Diffie Hellman Parameters file

openssl dhparam -out dh_2048.pem 2048

This could take 15-20 minutes

Step 5: Connecting the Hardware

Powering the LED strip

The LED strip is powered by 12 volts. The Raspberry Pi is only capably of outputting 3.3v or 5v and is not capable of outputting anywhere near the amps needed to drive so many LEDs.

It is important to not connect the 12 volt power supply to the Raspberry Pi.

My strip also had additional power wires connected to the strip at either end. I suggest that you tape these up so they do not make contact with any of your other equipment.

Carry out the next steps at your own risk. I take no responsibility for anything that may go wrong.

LED Strip

My LED strip has three wires:

RED - +12 Volts

BLACK - Ground

GREEN - Data

NOTE: there is a Din and a Dout - Data In and Data Out. Ensure you are working with the end of the LED strip that says Din.

Ensuring that the the Barrel Jack is not connected to the power supply

1. Connect the Red wire from the LED strip to the + side of the Barrel Jack.

I used a white 22 gauge hook up wire.

Place the wire into the + slot in the barrel jack and screw it in place.

Push the other end of the wire into the socket on the LED. Ensure you are connecting with the red wire.

2. Connect the Black wire from the LED strip to the - side of the Barrel Jack.

I used a black 22 gauge hook up wire.

Place the wire into the - slot in the barrel jack. At this point also place the male end of one of the connector cables (brown wire in the photo) into the same hole and screw them both in place.

Push the other end of the black wire into the socket on the LED.

Ensure you are connecting with the black wire.

3. Connect the green wire from the LED strip

Take one of the femal to male connector cables. In my photos this is the green wire.

Place the male end into the LED socket with the green wire.

This is the data cable.

Raspberry Pi

1. Take the green connector cable and connect it to the Raspberry Pi GPIO.

You need to connect it to the PCM_CLK (Pin 12 / GPIO 18)

2. Take the black connector cable and connect it to the Raspberry Pi GPIO.

You need to connect it to one of the grounds. I suggest you use pin 14, but you could also use pin 6, 9, 20, 25, 30, 34 or 39.

NOTE: for this to work the LED power source and the Raspberry Pi must have a common ground. Also note that you must not connect the 12 Volt + (Red wire) to the Raspberry Pi.

LED Power

You should not be able to connect your 12 volt power supply to the barrel jack

All the LEDs on your LED strip should now light up WHITE

Step 6: Server Side Code

Running the server side code

cd /opt/com.jonhaydock/disco-pi
sudo npm start

This will start up the web server and start listening for HTTPS and WSS requests.

The default port is 443, but you can override this by setting an environment variable before starting the code. For example

export DISCO_PI_PORT=1443

My LED strip has 150 LEDs. These are controlled in in groups of threes. This means that I cannot control every LED individually, and I need to send through enough information to control 50.

If your LED has more or less you can override the number of LEDs that you are controlling by passing in a parameter to the start up. For example, if you can only control 10 LEDs

sudo npm start 10

The main server code can be found in the app.js file. This file starts the HTTPS web server and also adds on socket.io to listen for websocket requests on the same port.

To access the website, you should open a web browser on your main computer (I have only tested this in Chrome) and use the IP address of the Raspberry Pi, e.g.

https://10.0.1.2/

You can find out your IP address from the Raspberry Pi command line.

ifconfig

The webserver will serve up any content under the public folder. It defaults to display the index.html page.

It has one API end point - /api/audio. This end point looks for any files under the public/audio folder and returns the list. For example

["GYAKO.mp3","Havana (feat. Young Thug).mp3","Queen_Bohemian_Rhapsody.mp3","Set It All Free.mp3","This Is What You Came For (feat. Rihanna).mp3"]

To add music as an option, copy files to this folder. I personally use Filezilla over ssh. The folder that you want to add files to is /opt/com.jonhaydock/disco-pi/public/audio

Step 7: Website Code

When you hit the website you should see something like this.

If you see a security warning this is because we are using a self-signed SSL certificate. You can ignore it or add it as an exception.

On selecting a file name, the source for the HTML 5 audio element. will be set to that file. Once ready, the music will begin to play. Once the song has finished the music will stop.

If you select the None option, the music will stop playing.

While playing the music file, the webpage uses the AudioContext interface to analyse the music, which is then sent to the server over a secure websocket connection.

The message is the type that the socket.io on the server has been set up to listen for "ws2811". It contains an array of 50 elements, which are between 0 and 255.

"ws2811",{"0":251,"1":252,"2":241,"3":217,"4":193,"5":164,"6":148,"7":139,"8":110,"9":96,"10":81,"11":67,"12":72,"13":66,"14":60,"15":60,"16":63,"17":54,"18":37,"19":30,"20":31,"21":26,"22":13,"23":3,"24":10,"25":7,"26":6,"27":0,"28":0,"29":0,"30":1,"31":8,"32":12,"33":3,"34":2,"35":2,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0}

The server uses the Node RPI WS281x Native library (wrapping Jeremy Garff's WS281X library) to change the colours of the LEDs on a WS2811 LED strip, based on the data sent through the websocket.

Step 8: Finally

You should see the LEDs on the strip change colour with the music, based on the Fast Fourier Transform analysis done in the web page.

I hope that you enjoy this. Let me know what you do with it!

NOTE: If you have any issues

Since this library and the onboard Raspberry Pi audioboth use the PWM, they cannot be used together.

You may need to blacklist the Broadcom audio kernel module by creating a file /etc/modprobe.d/snd-blacklist.conf with

blacklist snd_bcm2835 

If the audio device is still loading after blacklisting, you may also need to comment it out in the /etc/modules file. On headless systems you may also need to force audio through hdmi

Edit config.txt and add:

hdmi_force_hotplug=1
hdmi_force_edid_audio=1

A reboot is required for this change to take effect

Raspberry Pi Contest 2017

Participated in the
Raspberry Pi Contest 2017

LED Contest 2017

Participated in the
LED Contest 2017