Mood lighting with Raspberry Pi
Mood lighting or ambience lighting refers to using different colors of light to create an ambience reflecting a particular mood. With incandescent or CFL bulbs, mood lighting was very restrictive - color of the light would be restricted to the color of the enclosure of the bulb. However advent of RGB (Red Green Blue) LEDs has opened up a new dimension in mood lighting. A good example is Philips Hue (http://www2.meethue.com/en-xx/). Not only one is not restricted by the color of the enclosure, one gets a choice of colors not previously possible which can be dynamically changed too!!
If you don't want to invest in a proprietary solution, here's one way to achieve the same using RGB LED strip and RPi.
Hardware
A typical RGB strip needs 12V. However, RPi provides only 3.3V at the GPIO pins. Hence we need a bridge between these two circuits. A ULN2803 chip acts as this bridge - it takes TTL input and allows one to drive a high voltage circuit.
Software
We will use raspberry-gpio-python to control the GPIO from python (v2.7). We will write a simple webserver which will take color hexcode as a query string and apply Pulse Width Modulation (PWM) to generate the same at RPi output.
Install raspberry-gpio-python package
Download tar from http://sourceforge.net/p/raspberry-gpio-pythonIn a different directory, create two files pwm.py and server.py as listed below.
gunzip RPi.GPIO-0.5.11.tar.gz
tar xvf RPi.GPIO-0.5.11.tar
cd RPi.GPIO-0.5.11
sudo python setup.py install
pwm.py
#!/usr/bin/python
#Controlling a RGB LED with software PWM.
#Mostly copied from GPIO PWM example:
#http://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/
import time
import RPi.GPIO as GPIO
import math
GPIO.setmode (GPIO.BOARD)
red = 12
#pin numbers to match LED legs
green = 16
blue = 18
GPIO.setup (red, GPIO.OUT)
#setup all the pins
GPIO.setup (green, GPIO.OUT)
GPIO.setup (blue, GPIO.OUT)
Freq = 100
#Hz
#setup all the colours
RED = GPIO.PWM (red, Freq)
#Pin, frequency
RED.start (0)
#Initial duty cycle of 0, so off
GREEN = GPIO.PWM (green, Freq)
GREEN.start (0)
BLUE = GPIO.PWM (blue, Freq)
BLUE.start (0)
def colour (R, G, B):
#colour brightness range is 0-100
RED.ChangeDutyCycle (R)
GREEN.ChangeDutyCycle (G)
BLUE.ChangeDutyCycle (B)
def hex_to_argb(value):
lv = len(value)
return tuple((int(value[i:i + lv // 4], 16) * 100)/255 for i in range(0, lv, lv // 4))
'''
try:
while 1:
colour(0, 0, 100)
except KeyboardInterrupt:
pass
'''
def stop():
#Stop all the PWM objects
RED.stop ()
GREEN.stop ()
BLUE.stop ()
#Tidy up and remaining connections.
GPIO.cleanup ()
#Controlling a RGB LED with software PWM.
#Mostly copied from GPIO PWM example:
#http://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/
import time
import RPi.GPIO as GPIO
import math
GPIO.setmode (GPIO.BOARD)
red = 12
#pin numbers to match LED legs
green = 16
blue = 18
GPIO.setup (red, GPIO.OUT)
#setup all the pins
GPIO.setup (green, GPIO.OUT)
GPIO.setup (blue, GPIO.OUT)
Freq = 100
#Hz
#setup all the colours
RED = GPIO.PWM (red, Freq)
#Pin, frequency
RED.start (0)
#Initial duty cycle of 0, so off
GREEN = GPIO.PWM (green, Freq)
GREEN.start (0)
BLUE = GPIO.PWM (blue, Freq)
BLUE.start (0)
def colour (R, G, B):
#colour brightness range is 0-100
RED.ChangeDutyCycle (R)
GREEN.ChangeDutyCycle (G)
BLUE.ChangeDutyCycle (B)
def hex_to_argb(value):
lv = len(value)
return tuple((int(value[i:i + lv // 4], 16) * 100)/255 for i in range(0, lv, lv // 4))
'''
try:
while 1:
colour(0, 0, 100)
except KeyboardInterrupt:
pass
'''
def stop():
#Stop all the PWM objects
RED.stop ()
GREEN.stop ()
BLUE.stop ()
#Tidy up and remaining connections.
GPIO.cleanup ()
server.py
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from urlparse import urlparse, parse_qsl
import cgi
from pwm import hex_to_argb, colour, stop
class GetHandler (BaseHTTPRequestHandler):
def do_GET (self):
parsed_path = urlparse (self.path)
message_parts =['CLIENT VALUES:',
'client_address=%s (%s)' % (self.client_address,
self.address_string ()),
'command=%s' % self.command,
'path=%s' % self.path,
'real path=%s' % parsed_path.path,
'query=%s' % parsed_path.query,
'request_version=%s' % self.request_version,
'',
'SERVER VALUES:',
'server_version=%s' % self.server_version,
'sys_version=%s' % self.sys_version,
'protocol_version=%s' % self.protocol_version,
'', 'HEADERS RECEIVED:',]
q = parse_qsl(parsed_path.query)
for k,v in q:
if (k == "color"):
self.execute(v)
for name, value in sorted (self.headers.items ()):
message_parts.append ('%s=%s' %
(name,
value.rstrip ()))
message_parts.append ('')
message = '\r\n'.join (message_parts)
self.send_response (200)
self.end_headers ()
self.wfile.write (message.encode ())
return
def execute(self, color):
print("color = " + color)
c = hex_to_argb(color)
print(c)
colour(*c[1:])
def do_POST(self):
# Parse the form data posted
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD':'POST',
'CONTENT_TYPE':self.headers['Content-Type'],
})
for field in form.keys():
print field
if (field == "color"):
v = form[field].value
self.execute(v)
# Begin the response
self.send_response(200)
self.end_headers()
if __name__ == '__main__':
PORT = 8080
server = HTTPServer (("", PORT), GetHandler)
print ('Starting server, use <Ctrl-C> to stop')
server.serve_forever ()
Since we will be handling low level IO functions, we need to run this server as root.
sudo python server.py
Now we can use curl to change the color as we want by passing color hexcode in argb format (1 byte each for alpha, red, green and blue). e.g. to get red color, use
curl http://<rpi-ip-addr>:8080 -d color=ffff0000
Or use a browser:
http://<rpi-ip-addr>:8080/?color=ffff0000
Comments
Post a Comment