LED Control with FastLED Library + Arduino
Contents
Introduction
So you have an addressable LED strip and you're looking to light it up. The task may at first seem daunting, but fear not! There are many ways to get started with your LED strip, and one of the easier and more flexible ways is using the FastLED library available for Arduino. This library supports all of the most common types of LED strips including Neopixel, Dotstar, and many more. It offers advanced color control and color mathematics, making it a good choice for many projects. Let's get started!
Downloading the Library
The library can be downloaded here. There are many releases available, but I would recommend downloading the latest release to ensure that the library supports your chip type. To download, click on the link that says "Source code (zip)" under the latest release. Extract the folder into the libraries folder for your Arduino. On my computer, this folder is accessed by:
OS (C:) > Program Files (x86) > Arduino > libraries
You now have the library downloaded and you're ready to get coding.
Using an Example Sketch
Let's start with some example code provided by FastLED. Note, not all of the example files support all chip types. Some of the older examples do not support more recent chips. We will begin with the example "FirstLight". Navigate to the FastLED folder that you have just unzipped, double click on the folder called "examples", then double click "FirstLight". At the top of the sketch, there should be a lot of code with a lot of commented lines, telling you how to adjust the code to your LEDs.
There are a few changes that you will need to make to this header to tailor it to your project. First, you need to adjust the number of LEDs on your strip accordingly to be #define NUM_LEDS (number on your strip). Next, you may need to change the data pin definition depending on what pin you wish to write the data over to your strip. For me, using an Arduino UNO, this was pin 11. You also must determine if your strip has a clock input or not. This should be apparent just by looking at your strip and seeing if it has an input and output on the LEDs for the clock signal. If your strip contains a clock input, uncomment the line "#define CLOCK_PIN 8" and adjust the value to the pin you are using for the clock signal. For me, this was pin 13. The last adjustment that you will need to make is uncommenting the appropriate line to add your LEDs. You will need to know the type of chip your LEDs contain, and uncomment the line in the setup loop that adds the right type of LEDs and commenting out or deleting the lines for all the other LED chips. For my project, this is what the new header for this example would look like:
#include "FastLED.h"
///////////////////////////////////////////////////////////////////////////////////////////
//
// Move a white dot along the strip of leds. This program simply shows how to configure the leds,
// and then how to turn a single pixel white and then off, moving down the line of pixels.
//
// How many leds are in the strip?
#define NUM_LEDS 60
// Data pin that led data will be written out over
#define DATA_PIN 11
// Clock pin only needed for SPI based chipsets when not using hardware SPI
#define CLOCK_PIN 13
// This is an array of leds. One item for each led in your strip.
CRGB leds[NUM_LEDS];
// This function sets up the ledsand tells the controller about them
void setup() {
// sanity check delay - allows reprogramming if accidently blowing power w/leds
delay(2000);
FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);
}
Upload the code to your Arduino and wire up your LEDs. You should see a single white dot moving along the length of the strip. Congrats! You now have the basics of controlling your LEDs. You are now ready to move onto more complicated code.
Determining Color Order
You may have noticed that in the FirstLight example file, the line that adds the LEDs with the chip APA102 is slightly different than the line included in the section above. Where the example code has "RGB", the code I used has "BGR". This is because on my LEDs, the color order is blue-green-red instead of the standard red-green-blue. This would mean that if I attempted to turn an LED red with the standard declaration, it would actually be blue on my strip. To determine the color order of your LED strip, go through the example "RGBCalibrate" provided by FastLED and then adjust your line adding the LEDs accordingly. If you do not do this step, the colors may not behave how you intended.
Lighting your LEDs
If you have ever used LEDs before, the way that you light the LEDs on an LED strip may seem counterintuitive. With the FastLED library, you are not determining which LEDs to light, but instead, you are setting colors to the LEDs and then lighting all of the LEDs on the strip at once by using the function FastLED.show().
To set an LED to a color, there are many methods which are outlined in detail here. The basic idea is to set the LED you want to a specific color by setting its index in the "leds" array equal to a color value. For example, to light the 3rd LED on your strip to red, you could use the following syntax:
leds[2] = CRGB::Red;
FastLED.show();
Note that the leds array is zero-indexed, so the third LED has the index "2". Also note that the first line alone would not light your LED, but the LEDs are not lit until FastLED.show() is called. This means that if you want to light many LEDs simultaneously, you can assign all of them a color and wait to call FastLED.show at the end.
To turn an LED off, you can use either of the following lines
leds[i] = CRGB::Black;
leds[i] = CRGB(0, 0, 0);
and then when FastLED.show() is called, this light will be turned off.
Tips and Going Further
LED strips can be finnicky and temperamental at times. You would think that not assigning a color to an LED would leave it turned off, but this is not true. Often, if you do not explicitly assign a color to an LED, they can choose to be whatever color they would like. Because of this, I got in the habit of turning every LED off in the setup loop with the following code.
for (int i = 0; i < NUM_LEDS; i++){
leds[i] = CRGB::Black;
}
This ensures that unless I turn an LED on, it will not be on. Similarly, if your strip contains 60 LEDs but you only want to use 20 of them, you may think you can define NUM_LEDS to be 20 --many of the example files do this. However, in my experience, this means that the other 40 undefined LEDs will behave unpredictably. Instead, I would always define the number of LEDs to be the actual number you have plugged into your Arduino. If you want to leave 40 of them turned off, then you must actually set them to be turned off.
The LEDs on my strip at least were extremely bright. It is not recommended to turn on the LEDs to full brightness, because it can be genuinely painful to look at. Many of the example colors from the FastLED website also appeared white on my strip, because the brightness was too high. I would recommended capping each color value at 150, or 0x96, because any brighter than that is just drawing more power than necessary and most likely hurting your eyes.
Finally, it is a good idea to leave the initial delay(2000) in your setup loop. This will give you a chance to see if your LEDs are wired correctly before they begin drawing too much power. Often, if the LEDs are not wired correctly, you will know as soon as they are connected to a power source by them having unpredictable behavior before code is even run.
There are many more complex and interesting things you can do with the FastLED library that have not been outlined in this tutorial. If you're interested in taking your code to the next level, look here for more instructions and help.