Hello and welcome to my entry for MAKE’s Raspberry Pi Design Contest! I’ve spent the past week working hard on building a ceiling lamp with a ring of LED’s below it.
I call it the Cloud Lamp, and here’s how it all went down:
After getting my home somewhat automated with a z-wave network and a few other custom devices, I thought I’d like to have a simple way to see the status of my home, the weather, surf report, etc, easily visible from my bed. My initial thought was that I’d buy a conventional ceiling lamp and put four rgb LEDs around the perimeter of the lamp as status indicators. Well, two weeks ago I came upon Make’s contest and even though I was already behind I thought it’d be really fun to try building something. So I took my original idea and made the following changes: I went from 4 to 60 rgb LEDs after being inspired by this beautiful clock. Well, that and I love circular LED displays! :) I probably wouldn’t use the analogue-like clock functionality but I thought it was a beautiful design and I thought I could add something to it. And of course I changed out the Arduino for a Rasberry Pi, which made the project amazingly versatile!
The Build Process
The building process broke down into three major parts, the electronics, the physical lamp and the software.
To start, I bought a cheap, commercial ceiling lamp from Home Depot for about
30 (Girlfriend reminded me that we got one on sale) 10 bucks along with a bunch of flat pieces of steel, wires and assorted nuts and bolts. I shaped the pieces of steel into a simple bracket that could attach to the lamp base and welded the assembly together. This would also be the platform for the power supply, power switch tail (for switching the light bulbs off and on), the Pi and electronics board.
To make the lamp shade, I used the thick steel wire and built a template on plywood. I drew a circle using a pencil and twine connected to a wood screw in the center of the circle. (A trick that I used many times during this build) More wood-screws held the wire in
place while I soldered it together. This worked really well with a few caveats. Because the wire was under tension after welding it to keep it’s circular shape, welding cross-braces was problematic because the hot steel was ply-able enough to bend. Also, it’s just plain hard to make a nice, round circle even without the welding problems.
Lastly, the LED holder was done using a thin but durable board. I drew the initial circles using three strings, one had the outer diameter, another was the inner diameter and the final one was where the LED’s would be situated. I used the angle markings on a cheap protractor/square to get the rotational position of each LED; 60 LED’s, so I put one LED at every 6th degree. (360 degrees / 60 LEDs). Then, I cut out four holes from the center of the disk to allow light from the bulbs through, but left a wide column to keep the disc sturdy for the LEDs.
For the electronics portion I breadboard-ed out a ws2801 LED string using the schematic on Cody Ledbetter’s blog. Hooking them up is really simple. There’s four wires coming from the LED string, the Yellow wire (DI, on the LED string I used, the four wires are labled on the small PCB embedded in the plastic below the LED) should connect to the Raspberry Pi’s MOSI pin. And the Green wire should connect to the SCLK pin. The red and black should be +5 Volts to the red and Gnd for the black. Note that you’ll probably need a beefy power supply if you plan to control many lights and definitely more than the small usb power supplies used for Raspberry Pi’s.
The two light bulbs in the fixture are wired to the Power Switch Tail 2, which made it safe and easy to control them from the Pi. I simply connected a GPIO pin to screw terminal 1 (+in) and ground to 2 (-in).
I also soldered up a prototyping board next to the Raspberry Pi for future expansions. There’s an H-bridge motor driver IC connected to two GPIOs and the PWM pin so that I can add a motor and another GPIO pin broken out so that I can connect other LED’s.
The software was really exciting for this project. I’ve built lots of things with Arduino and it can be a lot of fun but it can also be limiting. To get this up and running quickly enough for the contest I’ve written a simple bit of code that will act as a web server, accepting commands over http that can control all the functions of the lamp. It works likes this:
To turn the bulbs off and on, send this command:
- http://[ ip of Pi ]:8080/?light=[ off or on ]
To change the ‘mode’ that the string lights are in
- http://[ ip of Pi ]:8080/?mode=[ Integer of mode you want to select ]
The ‘Modes’ allow you to switch the functionality of string LEDs. Mode 0 is LEDs off, Mode 1 is the color swirl pattern that came with Lady Ada’s ws2801 example; and mode 2 is an analogue clock. However, I plan to create new and more useful modes. Like one that will tell me the weather and surfing forcast, along with whether the house is secure or not. I also thought about a music visualizer, a rain simulator and many more! The fact that I can ssh into a full development environment to code new functionality without taking anything apart is amazing and really shows the power of embedding a Pi into something.
# title: lamp daemon
# author: falldeaf
# date: April 11th 10:16pm Eastern
# details: This code acts as a web server to accept commands over http
# as request variables to control all the functions of the cloud lamp
# This code is modified from the:
# Test code for Adafruit LED Pixels, uses hardware SPI
import RPi.GPIO as GPIO, time, os, datetime
from twisted.web import server, resource
from twisted.internet import reactor
MODE = 2 #initial mode
DEBUG = 1 #debug flag
GPIO.setmode(GPIO.BCM) #gpio mode
power_pin = 17 #powerswitch tail pin
#This class defines the web server object
isLeaf = True
def render_GET(self, request):
#If light command is sent, turn bulbs off or on
if 'light' in request.args:
if request.args['light'] == "off":
return " light off "
if request.args['light'] == "on":
return " light on "
#Set the 'mode' for the RGB LED circle
if 'mode' in request.args:
if request.args['mode'] == "0":
colorwipe(ledpixels, Color(0, 0, 0), 0)
MODE = 0
return " mode set to 0 "
if request.args['mode'] == "1":
MODE = 1
return " mode set to 1 "
if request.args['mode'] == "2":
MODE = 2
return " mode set to 2 "
return "invalid command"
def slowspiwrite(clockpin, datapin, byteout):
for i in range(8):
if (byteout & 0x80):
byteout < <= 1 GPIO.output(clockpin, True) GPIO.output(clockpin, False) SPICLK = 18 SPIDO = 17 ledpixels =  * 60 def writestrip(pixels): spidev = file("/dev/spidev0.0", "w") for i in range(len(pixels)): spidev.write(chr((pixels[i]>>16) & 0xFF))
spidev.write(chr((pixels[i]>>8) & 0xFF))
spidev.write(chr(pixels[i] & 0xFF))
def Color(r, g, b):
return ((r & 0xFF) < < 16) | ((g & 0xFF) << 8) | (b & 0xFF) def setpixelcolor(pixels, n, r, g, b): if (n >= len(pixels)):
pixels[n] = Color(r,g,b)
def setpixelcolor(pixels, n, c):
if (n >= len(pixels)):
pixels[n] = c
def colorwipe(pixels, c, delay):
for i in range(len(pixels)):
setpixelcolor(pixels, i, c)
if (WheelPos < 85):
return Color(WheelPos * 3, 255 - WheelPos * 3, 0)
elif (WheelPos < 170):
WheelPos -= 85;
return Color(255 - WheelPos * 3, 0, WheelPos * 3)
WheelPos -= 170;
return Color(0, WheelPos * 3, 255 - WheelPos * 3)
def rainbowCycle(pixels, wait):
for j in range(256): # one cycle of all 256 colors in the wheel
for i in range(len(pixels)):
# tricky math! we use each pixel as a fraction of the full 96-color wheel
# (thats the i / strip.numPixels() part)
# Then add in j which makes the colors go around per pixel
# the % 96 is to make the wheel cycle around
setpixelcolor(pixels, i, Wheel( ((i * 256 / len(pixels)) + j) % 256) )
#This function displays a real-time analogue clock
hour = 60 / int(time.strftime('%l'))
minute = int(time.strftime('%M'))
second = int(time.strftime('%S'))
one = 1
quarter = 15
half = 30
threequarter = 46
for i in range(len(pixels)):
c = Color(0,50,100) #This is the background color
if i == one or i == quarter or i == half or i == threequarter:
c = Color(0,0,20) #This is the four cardinal directions color
if i == hour:
c = Color(20,0,0) #Color of the hour hand
if i == minute:
c = Color(20,0,20) #Color of the minute hand
if i == second:
c = Color(20,20,20) #Color of the second hand
setpixelcolor(pixels, i, c)
#start the web server on port 8080
site = server.Site(Simple())
#main loop - check the web connection and draw to the leds once for each loop
if MODE == 1:
if MODE == 2:
#if MODE == 3:
#if MODE == 4:
This is the first personal project I’ve ever done that wasn’t only for the fun of it. It was stressful in some ways but also really rewarding and challenging. For instance, given more time, I probably would have used a service like Ponoko to CNC cut the LED holder. But with the time crunch it was cool figuring out how-to create and cut the shape and solve the LED spacing problem. ( I got some help on this ;) Thanks Corey! ) I hope that if anyone wants to recreate this or some variation thereof that I was explicit enough in my directions and code commenting. If not, please feel free to email me at email@example.com or leave a comment in the comment section below!
I plan on adding some more features in both hardware and software, so if you get a chance, check back here!
Oh, and here’s the injury tally for anyone keeping score:
- Minor lacerations (Steel is sharp after you cut it)
- Sub-dermal irritatants (The lamp was chock full of insulation)
- Welding Tan (New to welding… didn’t know this was a thing. Wear sunscreen!)
- Severe Burns (Metal is very, very hot after you weld it, there’s probably room for a Captain Obvious Meme here…)
Ok, that’s all, Thanks for reading! :)