===== Oak: controlling the color of an RGB LED ===== [[http://digistump.com/wiki/_media/oak-rgb-led.png|{{http://digistump.com/wiki/_media/oak-rgb-led.png?400}}]] An RGB LED the capability to take on any color since it contains a red, green and blue LED in one bulb. The concepts surrounding controlling an RGB LED are identical to the [[oak:tutorials:leds|basic]] and [[oak:tutorials:advanced-leds|advanced]] LED tutorials. The primary difference will be in the circuit. ===== Components used ===== ^Part ^Quantity ^Identification^ |Oak with soldered headers| 1 | | |Breadboard| 1 | | |Jumper wires | 4 | | |RGB LED| 1 | whitish LED with 4 leads, one longer than the others | |Resistor, 220 ohm| 3 | Red-Red-Brown| **Note:** 220 ohms is a ballpark recommendation; acceptable values are between 100 - 1k ohms. ===== Concepts ===== === Current sourcing vs. sinking === As discussed in the previous LED tutorials, LEDs allow the flow of current in one direction. For RGB LEDs, this is still true, however some are designed as common anode, and some as common cathode. The difference is whether the current flows //into// the longer lead (common anode) or //out// of the longer lead (common cathode). The connections to the pins for each color are the same: each connected to a PWM-capable pin on the Oak. The difference is in whether the longer lead is connected to ''Vcc'' (common anode) or ground (common cathode). A common anode LED operates in what is known as current sinking. When you send a ''LOW'' signal to a pin, current passes through that color's LED, and //into// the Oak. It "absorbs" the current into the signal pin. When you send a ''HIGH'' signal, the voltage entering the longer lead and the voltage sent to that color's pin are the same and no current flows (that color's LED is off). In the other scenario, the long lead is connected to ground (common cathode). A ''HIGH'' signal at the pin drives current through the pin, into that color's LED, and to ground. Current flows //out// of the longer lead and is called current sourcing. The LEDs provided with the starter kit are common cathode type, so the common lead will be grounded. ===== Circuit ===== Here is the circuit to connect: [[http://digistump.com/wiki/_media/oak-rgb-led.png|{{http://digistump.com/wiki/_media/oak-rgb-led.png?500}}]] Complete these steps: * Insert the RBG LED so that the leads are all in separate rows * Connect a jumper wire from one of the Oak's ground pins to the //long// lead of the LED * Insert one end of each resistor into a row containing the lead of the LED, making sure the other lead is either in a different row by itself or spans a gap as shown in the breadboard above * Connect one jumper wire from pins 6, 7, and 8 to each of the free ends of the resistor Here is an example of a real world setup: [[http://digistump.com/wiki/_media/oak-wiring-rgb-led.jpg|{{http://digistump.com/wiki/_media/oak-wiring-rgb-led.jpg?400}}]] ===== Code ===== === Code: pulsing each color === With the following code, we will use nested ''for()'' loops to cycle each of our LED pins (6, 7 and 8) to pulse each color the LED. void setup() { // set all LED pins to OUTPUT pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); } void loop() { for(int i = 6; i <= 8; i++) { for(int j = 0; j <= 1023; j++) { analogWrite(i, j); delay(1); } for(int j = 1023; j >= 0; j--) { analogWrite(i, j); delay(1); } } } We start off by entering a loop where ''i = 6''. This is used for the output pin. Next, a second for loop is entered which writes to pin ''i'' (6, the first time around) values for ''j'' starting at 0 (off) and going to 1023 (full power). When that loop completes, the opposite loop runs, taking the brightness all the way back to 0 (off). The whole process begins again with pin ''i = 7'', then pin 8, and then repeat. You should see each color pulse, one at a time, each over the course of ~2 seconds. [[http://digistump.com/wiki/_media/oak-rgb-led-cycle.gif|{{http://digistump.com/wiki/_media/oak-rgb-led-cycle.gif?400}}]] === Code: fading through the rainbow === The code in [[oak:tutorials:advanced-leds|advanced LED tutorial]] ended with a sketch that would ramp up three different LEDs at overlapping times. Check out the link to see the animation at the end for an idea of what it looked like. It turns out that we can use the exact same code to cycle through the various colors achievable with an RGB LED. Instead of toggling individual bulbs, we'll do it with the internal LED colors in our RGB bulb. Here is the code: // these values will store the brightness for each of our colors int r_bright = 0; int g_bright = 0; int b_bright = 0; void setup() { // set all color pins to OUTPUT pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); } void loop() { // this first loop will run from i = 0 until i = 2000 for(int i = 0; i <= 2000; i++) { // these lines map the value of i to the desired brightness range, 0-1023 // because we've "offset" the min/max of i, we need to constrain // the output to make sure it's between 0-1023 r_bright = constrain(map(i, 0, 1000, 0, 1023), 0, 1023); g_bright = constrain(map(i, 500, 1500, 0, 1023), 0, 1023); b_bright = constrain(map(i, 1000, 2000, 0, 1023), 0, 1023); // each time through the loop, we write each brightness // value to it's corresponding color channel analogWrite(6, r_bright); analogWrite(7, g_bright); analogWrite(8, b_bright); // we delay for 1 millisecond, otherwise this runs at // lightning speed! delay(1); } // now we repeat the same cycle of i from 0-2000, but with a twist! for(int i = 0; i < 2000; i++) { // this is the same code except that our output range in map() // is reversed! When i is 0, r_bright will be 1023; // when i is 1000, it will be 0. This let's us dim the colors one by one r_bright = constrain(map(i, 0, 1000, 1023, 0), 0, 1023); g_bright = constrain(map(i, 500, 1500, 1023, 0), 0, 1023); b_bright = constrain(map(i, 1000, 2000, 1023, 0), 0, 1023); analogWrite(6, r_bright); analogWrite(7, g_bright); analogWrite(8, b_bright); delay(1); } } We ramp up the red channel of the LED, and when it's halfway through (when ''i = 500''), the green channel begins ramping up. At ''i = 1000'', the red channel is fully on, green is halfway to full on, and blue is just starting. They start and stop the process approximately half a second offset from each other, and once they're all at full brightness, the process reverses to bring them back down to off. Here's what you will see with the code above! It's a bit hard to make out, but the progression is red, yellow, white, cyan, blue. [[http://digistump.com/wiki/_media/oak/tutorials/oak-rgb-led-rainbow.gif|{{http://digistump.com/wiki/_media/oak/tutorials/oak-rgb-led-rainbow.gif?400}}]] ===== Conclusion ===== In this tutorial, you learned how to write the individual color channels of an RGB LED, as well as to blend colors by writing values to multiple color pins simultaneously. This means you have near infinite control of the output color! What might you do with this? How about color-coded alerts based on various sensors? Or a light that interfaces with the music you're currently listening to in order to change color with tempo or pitch? The RBG LED is a great way to indicate sensors as well, mapping a value at the high end to one color (say, red) and another color the low end (perhaps blue). Now you can tell by the color what the sensor is reading. Good luck in finding something useful for //your// RGB LEDs, and please check out some of the other [[oak:tutorials|tutorials]].