You can purchase long flexible strips of small surface mounted LEDs that come on a spool. You can cut the strip to length at the cut marks. You can solder strips together by using the solder pads.
There are a number of different type of SMD (surface mounted device) LEDs available:
The most common type of SMD LED is the ‘5050’ square LED light. A single ‘5050’ LED consists of 3 individual miniature LEDs. These miniature LEDs can be either pure white, all of the same color or red-green-blue (tri-color). As a result, ‘5050’ LEDs are brighter than ‘3528’ LEDs, but ‘3528’ LEDs used in high density strips will be able to provide a similar brightness whilst being more cost effective.
You can order LED strips:
When choosing an RGB LED strip you may want to pay attention to the brightness in lumens:
Accent Lighting and Mood Lighting | ~ 156 – 350 |
Under cabinet Lighting | ~ 175 – 525 |
Task Lighting with low distance from light source | ~ 280 – 437 |
Task Lighting with higher distance from light source | ~ 344 – 687 |
Indirect lighting in a bedroom/ hotel / vehicle / lobby | ~ 375 – 562 |
Industrial lighting / signage / tube replacements | ~ 500 – 950 |
Analog LED strips come in single–color strips and multi-color strips. Analog multi-color strips are also known as ‘analog RGB LED strips’.
Analog single-color LED strips simply have a “+” and “GND” terminal. You can use PWM to change the brightness. You can order these strips in pure white (cool / warm) or a single color. Each individual LED is a single color.
The multi-color strips use “tri-LEDs” consisting of 3 miniature Red-Green-Blue (RGB) LEDs inside a single ‘5050’ LED.
Single color analog LED strip (top) and multi-color analog LED strip (bottom).
Analog multi-color strips have all the LEDs connected in parallel and so they acts like one huge tri-color LED. You can set the entire strip to any color you want, but you can’t set a different color each individual LED. They are very easy to use and fairly inexpensive. Analog multi-color LED strips have a +12V terminal and separate Red, Green and Blue terminals for the miniature RGB LEDs inside the (tri-color) ‘5050’ LEDs. Using pulse width modulation (PWM) we can change the intensity of the Red, Green or Blue miniature LED from 0V to 12V and generate the desired overall color and brightness.
You can use a sharp knife to remove some of the protective tubing and solder wires to the solder tabs.
Use heatshrink tubing to make the LED strip IP65 waterproof if required.
An Arduino digital I/O pin can output a maximum of 40mA. The total amount of current across all pins should not exceed 500mA. A single ‘5050’ LED will consume up to 60 mA. It is good practice not to power a LED strip directly from a digital I/O pin. A 1 meter LED strip with 60 ‘5050’ LEDs per meter = 60 * 60 mA = 3600 mA = 3.6 A max.
The easiest way to power a LED strip is by using an external power supply. We can use transistors to switch the LED strip on or off. A transistor uses a small current flowing from the Base to the Emitter to create a conductive path between the Collector and Emitter. It is a bit like how the first small patch of loose snow moving down a mountain slope causes an avalanche. A TIP120 transistor (darlington pair) can handle 60V 5A across the Collector-Emitter junction and only needs 2mA applied to the Base-Emitter junction to create a short between Collector and Emitter, just like a switch.
// Color swirl! // Connect an RGB LED to the PWM pins as indicated #define REDPIN 9 #define GREENPIN 10 #define BLUEPIN 11 #define FADESPEED 5 // make this higher to slow down void setup() { pinMode(REDPIN, OUTPUT); pinMode(GREENPIN, OUTPUT); pinMode(BLUEPIN, OUTPUT); } void loop() { int r, g, b; // fade from blue to violet for (r = 0; r < 256; r++) { analogWrite(REDPIN, r); delay(FADESPEED); } // fade from violet to red for (b = 255; b > 0; b--) { analogWrite(BLUEPIN, b); delay(FADESPEED); } // fade from red to yellow for (g = 0; g < 256; g++) { analogWrite(GREENPIN, g); delay(FADESPEED); } // fade from yellow to green for (r = 255; r > 0; r--) { analogWrite(REDPIN, r); delay(FADESPEED); } // fade from green to teal for (b = 0; b < 256; b++) { analogWrite(BLUEPIN, b); delay(FADESPEED); } // fade from teal to blue for (g = 255; g > 0; g--) { analogWrite(GREENPIN, g); delay(FADESPEED); } }
Analog RGB strips sold on the internet often come with a 28 or 44 function control unit.
This control unit uses pulse width modulation to change the brightness of each of he Red, Green and Blue channels of the analog LED strip similar to our code.
Digital RGB LED strips are also called pixel (addressable) RGB LED strips or Neopixel LED strips. Each LED in the strip is connected to a small chip. This chip allow you to control the brightness and color of each individual(!) LED. The chips used are either WS2801, WS2811 or WS2812.
(!) Unlike the analog RGB LED strips most Digital RGB LED strips operate on 5 Volts!
Before we start, we should probably identify the differences between the WS2801, WS2811 and WS2812 chips. Most projects and descriptions out there discus these sometimes mixed, and for one who dives into LED strips for the first time, these models numbers might be confusing.
The model numbers WS2801, WS2811 and WS2812 actually refer to different “things”:
In the illustration below you’ll see the difference:
On the left a 5050 RGB LED, on the right a WS2812 which combines a 5050 RGB LED with a WS2811 chip.
Note how the layout of the “silver” tracks are almost identical in both images, yet the black (IC) block and the tiny wires are different (right). Where the WS2801 strips needed 4 wires, the WS2811/WS2812 strips only needs 3 wires. The WS2801 uses a separate clock line, which can be seen as an advantage, whereas the WS2811/WS2812 does not. The WS2811/WS2812 depends on sending data matching a very tight timing. The advantage of the WS2812 though, is that production of these combo’s in strips is easier and therefor cheaper, and each RGB LED takes much less space on strips.
We will be using the WS2812 digital LED strips.
The resistor is used to protect against voltage spikes and large currents. As the resistor value is very low and these resistors are only 0.25W, they basically act like a fuse and will protect your precious digital RGB LED strip data line (WS2812 chips) from power surges.
A 1000uF electrolytic capacitor prevents the initial onrush of current from damaging the pixels. The capacitor is not needed for a few (say 1-3) pixels, but definitely recommended for anything more than that, otherwise you risk to damage the pixels!
It’s important to pay attention to the arrow on the digital RGB LED strip; if you use your strip in the wrong “direction”, it will not work. Simply connecting +5V and GND will at best flash up your strip for a fraction of a second. The LEDs need to be “told” to be ON, so without data signal your LEDs will remain OFF.
As the WS2812 does not use both a clock and data line but only a data line, timing has to be very precise. There are two libraries that are often used to drive digital RGB LED strips:
#include <Adafruit_NeoPixel.h> #define PIN 7 // Parameter 1 = number of pixels in strip // Parameter 2 = pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); void setup() { strip.begin(); strip.show(); // Initialize all pixels to 'off' } void loop() { // Some example procedures showing how to display to the pixels: colorWipe(strip.Color(255, 0, 0), 50); // Red colorWipe(strip.Color(0, 255, 0), 50); // Green colorWipe(strip.Color(0, 0, 255), 50); // Blue // Send a theater pixel chase in... theaterChase(strip.Color(127, 127, 127), 50); // White theaterChase(strip.Color(127, 0, 0), 50); // Red theaterChase(strip.Color( 0, 0, 127), 50); // Blue rainbow(20); rainbowCycle(20); theaterChaseRainbow(50); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay(wait); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255)); } strip.show(); delay(wait); } } //Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<10; j++) { //do 10 cycles of chasing for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } //Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } }
#include "FastLED.h" // Number of RGB LEDs in the strand #define NUM_LEDS 60 // Define the array of leds CRGB leds[NUM_LEDS]; // Arduino pin used for Data #define PIN 7 void setup() { FastLED.addLeds<NEOPIXEL, PIN, RGB>(leds, NUM_LEDS); } void loop() { // one at a time for(int j = 0; j < 3; j++) { for(int i = 0 ; i < NUM_LEDS; i++ ) { memset(leds, 0, NUM_LEDS * 3); switch(j) { case 0: leds[i].r = 255; break; case 1: leds[i].g = 255; break; case 2: leds[i].b = 255; break; } FastLED.show(); delay(10); } } // growing/receding bars for(int j = 0; j < 3; j++) { memset(leds, 0, NUM_LEDS * 3); for(int i = 0 ; i < NUM_LEDS; i++ ) { switch(j) { case 0: leds[i].r = 255; break; case 1: leds[i].g = 255; break; case 2: leds[i].b = 255; break; } FastLED.show(); delay(10); } for(int i = NUM_LEDS-1 ; i >= 0; i-- ) { switch(j) { case 0: leds[i].r = 0; break; case 1: leds[i].g = 0; break; case 2: leds[i].b = 0; break; } FastSPI_LED.show(); delay(1); } } // Fade in/fade out for(int j = 0; j < 3; j++ ) { memset(leds, 0, NUM_LEDS * 3); for(int k = 0; k < 256; k++) { for(int i = 0; i < NUM_LEDS; i++ ) { switch(j) { case 0: leds[i].r = k; break; case 1: leds[i].g = k; break; case 2: leds[i].b = k; break; } } FastLED.show(); delay(3); } for(int k = 255; k >= 0; k--) { for(int i = 0; i < NUM_LEDS; i++ ) { switch(j) { case 0: leds[i].r = k; break; case 1: leds[i].g = k; break; case 2: leds[i].b = k; break; } } FastLED.show(); delay(3); } } }
Additional information: