In my room, my bed is lofted above my desk. While I like the setup, it becomes a little difficult to see and study because the only source of light in the room is obscured slightly. Unfortunately, because I'm in Seattle and we have rain and overcast weather from September to July, sunlight isn't an option.
I could always buy a lamp, but why do that when I can have a little fun tinkering with technology? I also had a Raspberry Pi sitting on my desk, so I decided I would put it to use. The completed project, which I call PiFX, can be recreated with the steps below.
Obviously, if I was going to use an entire Linux computer to power a light, it might as well be the most controllable light source available: a strand of digitally addressable RGB LEDs. Another goal of the project was to make sure I could control the lights remotely-- there's no buttons on the Raspberry Pi I can use, plus an external interface is much more customizable.
Ultimately, the project came down to this: string a set of digitally addressable multi-color LEDs above my desk and hook it up to an internet connected Raspberry Pi. Using Hamachi, I could then connect to a custom web interface on the Raspberry Pi to control the LEDs themselves. All of this would be done on Adafruit's Occidentalis Linux distribution with the server built in Node.js.
Installing Occidentalis is almost exactly the same as installing Raspbian. You can follow my other tutorial to do so, but simply use the Occidentalis image file rather than the Raspbian distribution. Otherwise, the steps are the same.
I used Socket.io and Node.js to display the web interface. Socket.io allows for multiple clients connected simultaneously to the interface to see, in real time, what any other client is changing. Essentially, if I have the UI open on my laptop and desktop and change a slider on one, it will also change on the other. You can see the interface below.
To install Node.js, I simply used the pre-built binary (v0.8.16) on this page to avoid waiting 2 hours for the package to compile.
Simply download and unpack the ZIP file, and then run sudo make install
from the directory to copy the binaries into the appropriate locations.
The PiFX web interface is completely custom done and built on Twitter Bootstrap and the Cyborg theme from Bootswatch (when I use the console in the dark, it's better to use a dark interface). The source code is available on GitHub, but the basic premise of the entire app is that it takes a Buffer integers with a length of [Number of Pixels] * 3
, and then writes it to the strand of pixels using node-spi.
I may consider writing a separate tutorial on how to write custom animations for PiFX, but you can look at the built in animations for an example. It's pretty simple-- each animation has a function that takes in a PixelBuffer, modifies it according to the current frame number, and then returns it again.
An important part of the PiFX console is the code that drives the LEDs themselves. I use a modified version of node-spi, courtesy of Alex from Tinkerlog. The default node-spi package on NPM doesn't work, and I don't have the lower level hardware experience to bother fixing it, but the modified version included in the PiFX repository works fine.
I also have a separate RaspberryPixels NPM module that is designed to manage a buffer of LED pixels. It has some convenience functions to set the RGB or HSL color of individual pixels, fill the entire strand with a color, etc. There's no standalone documentation at the moment, but the code is very simple and easy to read. All of the parameters are documented within the code itself.
Anyhow, to setup your Raspberry Pi like mine, simply create a new directory somewhere on your Raspberry Pi with mkdir
. Inside of this, do a git clone git://github.com/andrewmunsell/PiFX.git
or download the contents of the repository.
After you have the repository cloned, use npm rebuild node_modules/spi
to rebuild the SPI module and download the remaining dependencies with npm install
.
Afterwards, you should be able to run sudo node server.js
to start the server. Visit your Raspberry Pi's IP address at port 8888 to view the web console. Obviously, it's not connected to anything, so nothing will happen if you try and add animations. Note-- you must use sudo
because you're accessing the GPIO hardware. Also, the server should work with any WS2801 based pixel strands or tape of any length (just change the Javascript or environmental variable corresponding to the number of pixels), not just those from Adafruit.
I am not a hardware expert, and simply used the female-to-male jumper wires on Adafruit to connect to the Raspberry Pi. The female end connects to the actual pins on the Raspberry Pi, while I taped the exposed wires from the JST SM Plug + Receptacle set to the male pin on the same cable. This isn't the most secure, but it does work. Considering my setup won't be moving, it's fine for me.
On the LED strand, there's two sets of power wires-- one spliced from the red and blue wires before the connector, and one in the connector itself. Using the exposed wire on the JST SM Plug/Receptacle connecting to the power on the LED strand and the jumper cables, I connected to the GND and 5v pins on the Raspberry Pi to provide power. The spliced wire along the LED Pixel strand is connected to the female DC jack, which then connects to the wall.
The clock and data wires connect to the Raspberry Pi in the same fashion as the power-- electrical taped to the jumper pins, which are hooked up to the GPIO on the Pi. You can refer to the diagram here to verify you have the right pins.
Wiring this together literally took four tries. First, I got the power hooked up but no control over the LEDs. This was due to me hooking up the Raspberry Pi to the output end of the strip. You can figure out which one is the input end by looking on your pixel-- the Adafruit site says there's an embossed arrow on the side of the LED's housing, but the arrow for me was printed directly onto the LED's PCB on the bottom of the pixel. The second and third times were just problems with my electrical tape job and not actually having the clock and data wires connected to the male side of the jumper cable properly.
Finally, if you did everything right, you should be able to restart the Node.js server and control your LEDs.
I simply mounted the Raspberry Pi on the bed frame using some velcro strips I found at a drug store nearby. It's plugged into ethernet and power from behind my desk. It's also plugged into a power strip/surge protector that has a timer feature, so I can turn the outlet on or off based on the time of day or manually if I'm away for the weekend (to reduce any potential fire hazards).
I do admit, the whole setup looks extremely suspicious and possibly malicious with the wires protruding from the PCB...
The photo below shows the setup, with the Raspberry Pi in the clear case on the bed frame. The ethernet goes against the wall behind the back board, as does the power.
Now, I have a fully controllable set of LEDs above my desk. Of course, I claim it's because I need light to study and see my homework, but we all know that's not strictly true. The strobe effect combined with the color wheel is great for an instant party.
I'm looking at using a program on my PC to remotely control the LEDs in time with music, but I'll have to connect the Raspberry Pi some other way than over ethernet and Hamachi because the latency is too high thanks to the IT department at the University of Washington (the Hamachi VPN is connected over an external relay and isn't strictly over LAN due to the locked down network).