Controlling a RGB LED with a Raspberry Pi

May 25, 2013 · 506 words · 3 minute read

You can use the General Purpose IO pins on a Raspberry Pi to easily control an LED. If you choose a three colour red-green-blue (RGB) LED you can mix these colours to create a wide range of colours, in the same way a pixel on your screen does.

I used a common cathode RGB LED , wiring the cathode to the ground pin on the Pi. Then the three legs are each wired to a GPIO pin on the board. In this case red to 12, green to 16 and blue to 18.

From the datasheet and the GPIO outputs I’d calculated the following resistances were needed between the LED and the GPIO’s 3.3V supply. If you’re using different LEDs check their current draw and typical forward voltage and use Ohm’s law to calculate the resistor you need (or use the handy LED Resistor Calculator ).

Assuming a 20mA current draw per leg:

ColourTypical Fwd VoltageInternalAdditionalCommonly Available
Red1.9V95Ω70Ω68Ω
Green3.3V165Ω-
Blue3.2V160Ω10Ω

But using these resulted in the green and blue were much brighter than the red, so when all the colours were on at the same time to create a ‘white’ light, it was distinctly blue. The yellow (red and green mixed) also came out very green.

After some experimenting with different resistor values and measuring with a multi-meter I managed to achieve an even white colour with the values below.

ColourResistor UsedMeasured Voltage Drop
Red0 Ω1.88V
Green220 Ω2.66V
Blue100 Ω2.69V

I used the Python GPIO library that comes with Raspbian, which recently added an experimental Pulse Width Modulation (PWM) feature , so make sure you follow the update instructions to make sure you have version 0.5.2a or later.

I included a small function that cycles through each colour at different speeds so the colour changes, creating an effect similar to Mitch Altman’s Trippy RGB Waves Kit that I saw a couple of weeks ago at the Bristol Hackspace .

 #!/usr/bin/python3    
 #Controlling a RGB LED with built in PWM.    
 #Mostly copied from GPIO PWM example:    
 #http://code.google.com/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, on_time):    
   #colour brightness range is 0-100    
   RED.ChangeDutyCycle(R)    
   GREEN.ChangeDutyCycle(G)    
   BLUE.ChangeDutyCycle(B)    
   time.sleep(on_time)    
     
   #turn everything off    
   RED.ChangeDutyCycle(0)    
   GREEN.ChangeDutyCycle(0)    
   BLUE.ChangeDutyCycle(0)    
     
 def PosSinWave(amplitude, angle, frequency):    
   #angle in degrees    
   #creates a positive sin wave between 0 and amplitude*2    
   return amplitude + (amplitude * math.sin(math.radians(angle)*frequency) )    
     
 try:    
       
   while 1:    
     for i in range(0, 720, 5):    
       colour( PosSinWave(50, i, 0.5),    
           PosSinWave(50, i, 1),    
           PosSinWave(50, i, 2),    
           0.1 )    
         
 except KeyboardInterrupt:    
   pass    
     
 #Stop all the PWM objects    
 RED.stop()    
 GREEN.stop()    
 BLUE.stop()    
     
 #Tidy up and remaining connections.    
 GPIO.cleanup()