This instructable shows how to use a Raspberry Pi to voice control an RGB LED strip, through a website, using the Web Speech API Interfaces for SpeechRecognition and SpeechSynthesis.
This example shows how to
Note
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.
Install the latest version of Node.js. At the time of writing I am using 8.9.1
curl -sL https://deb.nodesource.com/setup_8.x</a> | sudo -E bash - sudo apt-get install nodejs
sudo apt-get install git
pi-blaster enables PWM on the GPIO pins you request of a Raspberry Pi. The technique used is extremely efficient: does not use the CPU and gives very stable pulses.
This Pulse Width Modulation allows the the Raspberry Pi to control how bright each of the Red, Green and Blue channels are for the LED strip.
First, clone the repository
cd /opt/ sudo git clone https://github.com/sarfata/pi-blaster.git sudo chown -R pi:pi pi-blaster
Then, build and install
cd /opt/pi-blaster ./autogen.sh && ./configure && make && sudo make install
Finally, configure which pins you want to use
Under the root account, or using sudo, create and edit the file
/etc/default/pi-blaster
Add the following lines
DAEMON_OPTS=--gpio 23,24,25
These gpio pins need to match the pins that you are connecting to your LED strip.
NOTE: There is a difference between GPIO and pin number. This example uses the following
LED - Blue, GPIO-23, Pin - 16 LED - Red, GPIO-24, Pin - 18 LED - Green, GPIO-25, Pin - 22
Extra tweaks
Start pi-blaster
sudo service pi-blaster start
Restart pi-blaster
sudo service pi-blaster restart
Stop pi-blaster
sudo service pi-blaster stop
Start pi-blaster automatically at boot time
sudo systemctl enable pi-blaster
Pins being used by pi-blaster will be configured as outputs. Do not plug something on an input or you might destroy it!
This daemon uses the hardware PWM generator of the raspberry pi to get precise timings. This might interfere with your sound card output.
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
2. Clone the example git repository
git clone https://github.com/haydockjp/colour-pi.git
or
git clone [email protected]:haydockjp/colour-pi.git
3. Install the dependancies
cd colour-pi npm install
This might take 2-3 minutes
4. This project needs to communicate over HTTPS and WSS. At this time cylon-api-socketio does not support SSL connections. There is an open pull request to add this support, but until that is merged, there is a patch file in this repository. Run the following command after npm install
git checkout node_modules/cylon-api-socketio/lib/api.js
1. Create a private key file
cd /opt/com.jonhaydock/colour-pi/certs openssl genrsa -out colour-pi-key.pem 2048
2. Create a CSR (Certificate Signing Request)
openssl req -new -key colour-pi-key.pem -out colour-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]:Colour Pi Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:colour-pi Email Address []:[email protected]
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 colour-pi-csr.pem -signkey colour-pi-key.pem -out colour-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
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. N-channel MOSFET transistors are used to separate the 3.3v on the RPi pins and the 12v of the LED power supply.
The MOSFET has three pins Gate, Drain and Source. If you are not sure about which is which google for the data sheet of the transistor you are using, e.g. IRL3303
We are going to connect the Raspberry Pi Pin to the Gate, the LED wire to the Drain and a common ground to the Source. When the Pin goes high, the voltage between the Drain and the Source will activate the Gate and will connect the gate to the Source.
We are also going to put 10kΩ Resistors across the Gate and the Source, so that when we the RPi pin is high, we can protect the pin by reducing the current going through it.
Carry out the next steps at your own risk. I take no responsibility for anything that may go wrong.
There is a fritzing image and a photo of the actual circuit above.
I would recommend doing this while the power is off for the RPi and the LED strip
Set up the transistor circuits, one per colour channel
Connect the RPi pins to the board
I have used matching wire colours to the LEDs: Blue, Red and Green. I have used black for the ground
Connect the Barrel Jack
Connecting the LED strip
My LED strip came with a connector that was a good enough size that it could be temporarily plugged into breadboard. I Pushed the connector in the breadboard and wired it to the test of the circuit.
Drain
pin (middle pin) to the red wire on the LED strip connectorDrain
pin (middle pin) to the green wire on the LED strip connectorAfter checking the circuit, you should be good to power on the Raspberry Pi and plug in the 12v supply to the barrel jack.
cd /opt/com.jonhaydock/colour-pi sudo npm start
This will start up the web server and start listening for HTTPS and WSS requests.
NOTE: Remember to have pi-blaster running first
The default website port is 443, but you can override this by setting an environment variable before starting the code. For example
export COLOUR_PI_PORT=2443
The default web socket port is 1443, but you can override this by setting an environment variable before starting the code. For example
export COLOUR_PI_WSS_PORT=3443
Note: As the web socket is be handled by cylon.js and not the main website, these need to be on different ports
The pins that are used for the Blue (pin 16), Green (pin 18) and Red (pin 22) can also be overridden. For example
export COLOUR_PI_PIN_BLUE=36 export COLOUR_PI_PIN_RED=38 export COLOUR_PI_PIN_GREEN=40
Note: These need to match the physical pins you used. If you change these, you will also need update the GPIOs defined in the /etc/default/pi-blaster file. For example
DAEMON_OPTS=--gpio 16,20,21
The main server code can be found in the app.js file. This file starts the HTTPS web server and also, through the Cylon.js framework, uses socket.io to listen for web socket requests on a separate 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 web server will serve up any content under the public folder. It defaults to display the index.html page.
Cylon.js creates an end point that you can connect Socket.io.
https://10.0.1.2:1443/api/robots/colour-pi
You can send a set_colour message to through the socket to set the Red, Green and Blue values
device.emit('set_colour', r,g,b)
Which calls the set_colour command, which calls the setColour function in app.js. This function sets the brightness levels, for each of the R, G and B values, between 0 and 255. Where 0 is off and 255 is fully on.
e.g.
Red r=255, g=0, b=0 Green r=0, g=255, b=0 Blue r=0, g=0, b=255 White r=255, g=255, b=255 Black / Off r=0, g=0, b=0
The website uses voice recognition to select colours from a predefined list. To add a colour to the list, edit the file on the server: public/data/colours.json
e.g.
"red":"#FF0000",
When a colour is found, or selected from the drop down, the Output box will be set to that colour and a message will be send through socket.io to the Raspnerry Pi, which will set the LEDs to the same colour.
NOTE: depending on how good your LEDs are you may or may not see a similar colour. Some are easier to duplicate than others
When you first load the website, as you are using a self-signed SSL certificate you will need to acknowledge this in the browser. You should see a security alert about the certificate.
This box has a microphone icon. If you click the icon when it is green, it will start listening for colours. While it is listening, it will turn red. It will listen for a short amount of time and then stop. Clicking the microphone icon when it is red will also stop it from listening.
As this site needs to access your microphone, you will need to give it permission when prompted
NOTE: You need a microphone to for this part. I use the one on my web camera.
This box is tracking the guesses of the words that you are saying, as you are saying them.
This box tracks the final guess are what you said.
This is a list of all the colours the page knows about. It is created from the colours.json file. If you select one of these colours, the page will speak the colour and set the output colour.
NOTE: You need speakers or headphones to hear the speech
This web page currently only supports matching the colour. If the word or words you spoke into the microphone matches the name of a known colour, or you select a colour from the Known Colour list, it will be added here as a log.
The last found colour will be displayed here. The Colour Hex value (e.g. #7cb9e8) and the RGB value (e.g. 124, 185, 232) will be displayed as text and the background of the box in the middle will be set to the actual colour.
This colour is also sent to the Raspberry Pi and you should see the colour of the LED strip change.
NOTE: if you do not see the LED colour change, try restarting pi-blaster and/or the node.js app
sudo service pi-blaster restart
sudo npm start
This box displays a list of "Known Voices" from the supported speechSynthesis. Selecting one of these voices will change the voice and the language you will hear, and it will speak the name of the voice.
It will also change the language of the SpeechRecognition to be the same as that chosen in the list.
Here is an example of what you should see.
Please let me know if you have any issue and I can update as needed.