Combining my love for lighting and IKEA furniture with a need to find a new way to tinker with a Raspberry Pi, built a remote-controllable shelf light.
What I used:
- EXPEDIT shelving
- DIODER LED light strips (4-pack)
- FIXA, a 114-piece cable managment
- Raspberry Pi Series B
- PowerTail Switch II, a 120V opto-isolated relay accepting anything from 3V to 12V for a simple control input to activate the switch.
- I also have a breadboard, jumpers, and the GPIO cobber/cable kit which came with the Adafruit Raspberry Pi Starter Pack, but aren’t necessary if you’ve got another way to connect GPIO pins to an external component.
Assembly
IKEA, as always, provided delightful instructions for EXPEDIT. But seriously, this shelving is actually a very easy IKEA build, and it looks great; I highly recommend it. After the build, I started by mounting one DIODER strip in each of the four shelves in the top row:
Using the FIXA pieces and a little obsessive cable management, I pulled each lead straight to the back of the shelf and ran along the bottom edge of the shelving.
All of that terminated in a bit of a mess of excess cable which I just folded in a bundle and ziptied to the back of the unit.
Then I connected that up to the PowerSwitch and the RPi to get started on the Node fun.
Node.js control of RPi GPIO pins
Controlling the PowerSwitch Tail is really easy. All it needs is 3-12VDC applied to the control terminal:
We can do that with the Raspberry Pi’s GPIO, by attaching a GPIO pin to +
and
then connecting -
to a grounding pin. Controlling this in Python is really
easy:
#!/usr/bin/env python
import RPi.GPIO as io
io.setmode(io.BCM)
power_pin = 18
io.setup(power_pin, io.OUT)
io.output(power_pin, True)
But my experience is in Node.js and I wanted a fun way to make it controllable via a browser or other URL call. In short, I wanted:
/
– A very simple static site with on and off link buttons. We’ll use Express to host those assets./on
– Turn the light on (GPIO pin “on”)/off
– Turn the light off (GPIO pin “off”)
Full control of RPi GPIO using Node.js is currently a little lacking. There are two primary npm modules, but neither seems actively maintained and both appear to be on track for being replaced. Luckily, our needs are quite simple. I used pi-gpio because at the time, I couldn’t get gpio to work (although it has been updated since I last looked).
Remember that the GPIO pins can either be addressed as they are printed on the
board or in actual pin order. The pi-gpio
library uses the physical pinout,
not the printed numbers.
Image from Hobby Electronics illustrating the printed GPIO numbers compared to the physical pinout for the Raspberry Pi B.
We load up the two necessary libraries and also note the pin as 16 (which is labeled on the board as GPIO 23).
var gpio = require('pi-gpio');
var pin = 16;
var express = require('express');
var app = express();
A simple function to open the pin for writing, write x
(a boolean to turn on
or off the pin), and close the pin for output after half a second.
var lightSwitch = function(x){
gpio.open(pin, "output", function(err) {
gpio.write(pin, x, function() {
setTimeout(function(){gpio.close(pin)}, 500);
});
});
}
Now our utility URLs /on
and /off
app.get('/on', function(req, res){
lightSwitch(1);
var body = 'Lights On';
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Content-Length', body.length);
res.end(body);
});
app.get('/off', function(req, res){
lightSwitch(0);
var body = 'Lights Off';
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Content-Length', body.length);
res.end(body);
});
Lastly, we set up the Express server to listen for HTTP requests on 8080, and,
for any path that hasn’t already been declared, serve assets out of the
project’s /public
directory which contains a standard index.html
and
assorted CSS and JS assets.
app.listen(8080);
app.use(express.static(__dirname + '/public'));
console.log('Listening on port 8080');
Interaction outside the browser
I use
Tasker
on my phone. Essentially, it waits for contexts and takes actions. For example,
when I plug my phone in at night, Tasker silences text and email notifications.
Now that my lights are web-controlled, I have added a step in that profile to
also fire a request to /off
to turn of the lights.
In the future, I’d also like to set up similar actions on my computer (either with a taskbar/dock icon or automated actions) to turn the lights on when I start using my computer. Also, I have a second PowerSwitch Tail, so it would be trivial to add a second “circuit” to my system. Guess I’ll have to go buy more light fixtures!
Question
I’d love to find a better way of interacting with the GPIO pins, especially if I ever do anything more complicated. Are there any more mature GPIO libraries for Node.js? Join in the comments.