Voice Controlled Lights

It's not moop today but me again returning as a guest contributor. So, it's not planes or lathes today but wireless plugs and stuff.

If you read my last blog post (http://www.moop.org.uk/index.php/2013/05/27/homemade-wireless-plug/) you'll know that I tried building a cheap Bluetooth controlled plug socket that'd fit in a standard back box. When it came to actually installing though I got cold feet. There are safety and legal issue to fitting something like that into the wall so instead I opted for a commercially available version. I choose the LightwaveRF range of plug sockets and dimmer switches. These are just like what I was designing in that they just replace the standard fittings and are switchable remotely. With the LightwaveRF Wireless Controller this also includes controlling them across the network. They are pricey compared to my design but on the other hand, look a lot nicer and far less likely to catch fire.

The LightwaveRF network protocol is a fairly simple UDP scheme that's very easy to hook into (http://blog.networkedsolutions.co.uk/?p=149). The only strangeness is having to send a message with ID 533 first time to get the LightwaveRF box to prompt to register a new device. Coding this only took a few minutes and once that was working the only thing left was to think of something to do with it!

The most obvious thing to me was to live out Star Trek (http://www.youtube.com/watch?v=hShY6xZWVGE) by controlling things in my house by talking to them. "Computer, lights on" for example. I didn't want to leave a computer running all the time but I did have a Raspberry Pi lying around which I've been wanting to find a use for.

So, I started by looking for voice recognition technology to use. Doing a quick Google, bought up a lot of suggestions to use Google's voice API (they would say that! ;)). As much as I like Google, I don't really want everything I ever say getting sent to their servers, so that was out. Next best choice seemed to be CMU Sphinx. pocketsphinx is designed for embedded systems so seemed a good fit for the Pi.

On first impressions I was very unimpressed with CMU Sphinx. The accuracy of recognition seemed absolutely terrible. However it does have facilities to work with a subset of words for doing digit recognition for example. With a text file of commands I wanted it to recognise the lmtool (http://www.speech.cs.cmu.edu/tools/lmtool-new.html) creates all the files needed. Using these files the quality of recognition improved considerably. However there were still problems distinguishing "on" and "off". Also the word "Computer" was frequently misunderstood. So accepting this as a limitation of voice control, "Computer, lights on" became "Jeeves, lights up". Finally I adapted the voice model (http://cmusphinx.sourceforge.net/wiki/tutorialadapt) which improved the voice recognition even further.

Up until this point I'd been doing everything on my laptop but moving this to the Pi was fairly straight forward. I now needed some sort of microphone though. I tried Singstar mics at first. These worked straight off but didn't really do a very good job unless speaking directly into them. So next I tried another of my discarded game accessories, a PS3 Eye camera. This worked much better when picking up sound from across the room.

For sound output I used a pair of cheap PC speakers which I could connect to the 3.5mm audio jack on the Pi. I had spent some time trying to sort out a problem where the first second or so of audio when using HDMI output was silent. I tried updating the firmware and googled around for the answer. In the end I worked around this by appending a second of silence to the start of my audio output with sox. However when using the speakers the problem just went away anyway much to my relief.

As a finishing touch I made a quick LED display to indicate when the Pi was ready to accept the next command. While doing this, I decided to also wire up an IR LED so I could control the television too. Not having IR LEDs in my parts draw I just cracked open an old remote and took the LED out of there. I connect this to GPIO 7 as an arbitrary clock can be generated on that pin. I used this to provide the 38KHz modulation needed for my TV. I then toggled that pin between clock and a zero output in software to encode the commands to control the TV. This did not work at first. I could see on my laptop's webcam that the IR LED was flashing away but the TV did not respond. Cracking out the oscilloscope I found that the pulses when the output was a clock were all around 200us too long. I assume this is due to a delay in toggling the state. I decided to take the easy way out and just adjusted these timings. After these adjustments I was successfully able to control my TV using just an IR LED and a resister.

So enough talk, here it is in action...


Nb. The source is downloadable here Lightwave Source. I warn you now though it's some pretty ugly code. A lot of this coding was done crouched on the floor working directly on the Pi. Getting back off the floor was my top priority, not following any coding standards. Still thought I should include it just in case anyone wanted some reference. The main guts, speech.c is just a modified version of the pocketsphinx continuous speech sample. irTrans turns the TV on and off and lightwave.c deals with the network side of things. speaker.c just keeps festival open so I don't have to pay the start up time when doing voice synthesis. Hope it's helpful to someone.