ESP8266 + Neopixel + FastLED
Controlling Neopixels with ESP8266 using the FastLED library��Steven Smethurst https://blog.abluestar.com/�Instagram, Twitter, Github: @Funvill
Version: 1
Last updated: Feb 11, 2019
What are we doing today
Wifi SSID: MakerLabs�Password: Ecordova
Preparation
Hardware
Anatomy of an NeoPixel (WS2812) RGB LED
Pinout of a WeMos (ESP8266) board
Setup the Arduino IDE (Step 1)
To install the ESP8266 board in your Arduino IDE, follow these next instructions:
Setup the Arduino IDE (Step 2)
Setup the Arduino IDE (Step 3)
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
Setup the Arduino IDE (Step 4) - Upload !
An extremely short introduction to programming
This is not a programing course.
In this workshop you are going to learn just enough to become dangerous, and get some basic patterns working. The “C” language has over 100+ keywords. In this workshop we will be learning about 5 of them. “if, else, for, variables, and functions”
Online resources for learning to programing.
Blink Sketch
// The setup function runs once when you press reset or power the board�void setup() {� pinMode(LED_BUILTIN, OUTPUT); // Initialize build in led pin as an output.�}
// The loop function runs over and over again forever�void loop() {� digitalWrite(LED_BUILTIN, HIGH); // Turn the LED ON (HIGH)� delay(1000); // Wait for a 1000 ms� digitalWrite(LED_BUILTIN, LOW); // Turn the LED OFF (LOW)� delay(1000); // Wait for a 1000 ms�}
File > Examples > 01.Basics > Blink
Functions
Segmenting code into functions allows a programmer to create modular pieces of code that perform a defined task and then return to where the function was called from.
Functions have several advantages:
Function: digitalWrite()
Write a HIGH or a LOW value to a digital pin. If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the corresponding value: 3.3V for HIGH, 0V (ground) for LOW.
Syntax:
digitalWrite(pin, value)
Parameters:
pin: The pin number�value: HIGH or LOW
Function: delay()
Pauses the program for the amount of time (in milliseconds) specified as parameter. (There are 1000 milliseconds in a second.)
1,000 = 1 sec � 30,000 = 30 sec� 60,000 = 1 min
Note: There are many issues with using the delay() function. Instead it is suggested to use millis() with a timer. We will show you timers later on in this workshop.
Syntax:
delay(ms)
Parameters:
ms: the number of milliseconds to pause (unsigned long)
Make your own functions
void setup() {� pinMode(LED_BUILTIN, OUTPUT); // Initialize the built in LED pin as an output.�}
// the loop function runs over and over again forever�void loop() {� Blink(); // A function you created.�}��void Blink() {� digitalWrite(LED_BUILTIN, HIGH); // Turn the LED on� delay(500); // Wait for half second� digitalWrite(LED_BUILTIN, LOW); // Turn the LED off� delay(1000); // Wait for one second�}
Try this
Blink Faster and Slower
void setup() {� pinMode(LED_BUILTIN, OUTPUT); // Initialize the built in LED pin as an output.�}
// the loop function runs over and over again forever�void loop() {� digitalWrite(LED_BUILTIN, HIGH); // Turn the LED ON� delay(500); // Wait for half second� digitalWrite(LED_BUILTIN, LOW); // Turn the LED OFF� delay(2000); // Wait for two second�}
Variables
Variables is a container that hold information. They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by the reader and ourselves.
Data types are the representation in memory and have ranges of acceptable values. The larger the range the more memory it consumes.
void loop() {� // Variable declaration� int OneSecond = 1000 ;� � // Wait for half second� delay(OneSecond / 2);� digitalWrite(LED_BUILTIN, LOW);�� // Wait for two seconds� delay(OneSecond * 2);� digitalWrite(LED_BUILTIN, HIGH);�}
Next up is the LED strips
What is in the LED(s)
Each pixel is actually 3 LEDs (Red, Green, Blue), a serial to parallel control IC chip called (WS2811) all packaged into a single chip.
If you are looking for a deep dive into the technical details of these LEDs. Take a look at this slideshow. https://www.slideshare.net/usefulthink/noderpiws281x
Check your power supply
Check and double check to ensure that you have the correct power supply for you LED(s)
Most Neopixel, WS2812, and other LED strips are 5 volt. If you power them with more voltage you will destroy them.
Use a voltmeter to test your power supplies before connect them to your LED(s).
More voltage is BAD!�More current is good.
GND must be connected
The GND on the microcontroller and the LED strip must be connected.
If your microcontroller and LED strip are powered from two different sources (USB and DC power), there must be a ground connection between the two.
It will show up as random flashing of LED(s)
Add a capacitor
Add a capacitor (1000 µF, 6.3V or higher) across the + and – terminals of your power source. ��If your microcontroller and NeoPixels are connected to the same power source. The LED(s) may draw a lot of current on start up. This could “brown out” your microcontroller causing it to reset.
It will show up as blinking lights on your LED strip.
Short DATA wire as possible
Minimize the distance between the Microcontroller and the first LED
Try to minimize the distance between the microcontroller and first LED pixel, so the signal is clear. A meter or two is usually no problem. Much longer and things can become unreliable.
The long wire can act as an antenna for noise. If noise gets into your DATA line then the LED(s) will flash randomly.
Add a resistor to close to the LED(s) on the DATA line
Place a 300 to 500 Ohm resistor between the microcontroller DATA output pin and the input to the first LED Pixel. The resistor should be at the end of the wire closest to the LED(s), not the microcontroller.
Some products already incorporate this resistor…if you’re not sure, add one…there’s no harm in doubling up!
3.3v microcontrollers with 5V LED(s)
Neopixel LED(s) powered by 5v require a 5V data signal. If using a 3.3V microcontroller you must SHOULD use a logic level shifter such as a 74AHCT125 or 74HCT245 or drop the supply voltage to the LED(s) to be closer to the microcontroller 3.3v.
The ESP8266 is a 3.3v microcontroller but still can control the Neopixel LED(s). This is because the LED strips that we are using are good quality and accept this voltage range.
Estimating Power Requirements
Each individual NeoPixel draws up to 60 milliamps at maximum brightness white (red + green + blue). In actual use though, it’s rare for all pixels to be turned on that way. When mixing colors and displaying animations, the current draw will be much less. It’s impossible to estimate a single number for all circumstances, but we’ve been using 1/3 this (20 mA per pixel) as a gross rule of thumb with no ill effects. To estimate power supply needs, multiply the number of pixels by 20, then divide the result by 1,000
30 LED(s) * (20 mA) / 1000 = 0.6 Amp Probably okay�30 LED(s) * (60 mA) / 1000 = 1.8 Amp “Guaranteed” to work�
Voltage drops across long LED strips
The longer a wire is, the more resistance it has. The more resistance, the more voltage drops along its length. If voltage drops too far, the color of NeoPixels can be affected. Consider a full 5 meter reel of NeoPixels. With 5V applied at one end of the strip, for those pixels closest to this end, power traverses only a few inches of copper. But at the far end of the strip, power traverses 10 meters of copper — 5 meters out on the +5V line, 5 meters back on the ground line. Those furthest pixels will be tinted brown due to the voltage drop (blue and green LED(s) require higher voltage than red).
Power taps for long series of LED(s)
The way to resolve the power drop over long distances is to separate the LED(s) power connections into smaller sections. Depending on your power supply a power tap every 5 meter or 150 LED(s) work best.
Important: Ensure that the Data, GND is connected between segments, but the +ve is not connected. If they are connected one power supply might try to charge the other power supply and damage it. Explosions and Fire!
Where to get more support
Install 3rd party libraries
FastLED library
What is the FastLED library?
FastLED contains a LOT of functions including:
Test the LED(s), ESP8266, and FastLED library
The LED should change pattern every 10 seconds or so.
Start a new sketch (SimpleLEDStrip.ino)
#include "FastLED.h"
#define NUM_LEDS 30
#define DATA_PIN D6
CRGB leds[NUM_LEDS]; // Define the array of leds
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
// Set the color of the LED(s). More info https://github.com/FastLED/FastLED/wiki/Pixel-reference
void loop() {
leds[0] = CRGB::Red; // Choose color by name, Red
leds[1] = CHSV( 96, 255, 255); // Choose color by HSV (Hue, Saturation, Bright/Value), Green.
leds[2] = CRGB( 0, 0, 255); // Choose color by RGB (Red, Green, Blue), Blue
leds[3] = 0x000000; // Choose color by 'hex color code'. Black (off)
leds[4] = CHSV( 0, 255, ((millis()/500%2)*255)); // Blink on and off, (Advanced).
leds[5].g = 255; // Set to green.
FastLED.show();
}
Function: CRGB(red, green, blue)
Parameters:
red, green, blue: Arguments are the pixel color, expressed as red, green and blue brightness levels, where 0 is dimmest (off) and 255 is maximum brightness.
CRGB purple = CRGB(128, 0, 128);�CRGB skyBlue = CRGB(135, 206, 235);�CRGB limeGreen = CRGB( 50, 205, 50); �CRGB darkOrange = CRGB(255, 140, 0);
RGB color wheel
The RGB color model is an additive color model in which red, green, and blue light are added together in various ways to reproduce a broad array of colors. The name of the model comes from the initials of the three additive primary colors, red, green, and blue
FastLED HUE Chart
Working with raw RGB values in your code can be awkward in some cases. For example, transition between two colors in RGB while keeping a constant brightness. In most cases working with HUE is better to use than RGB.�https://github.com/FastLED/FastLED/wiki/Pixel-reference
Function: FastLED.show()
This updates the whole strip at once, and despite the extra step is actually a good thing. If every call to setPixelColor() had an immediate effect, animation would appear jumpy rather than buttery smooth.
FastLED.show();
Try this
Update the sketch to make a pattern of �Yellow, Green, Blue, Magenta, Purple, Red
For Statement
The for statement is used to repeat a block of statements enclosed in curly braces. An increment counter is usually used to increment and terminate the loop. The for statement is useful for any repetitive operation, and is often used in combination with arrays to operate on collections of data/pins.
There are three parts to the for loop header:
for( int pixel = 0 ; pixel < NUM_LEDS ; pixel++ ){
leds[pixel] = CRGB(0, 255, 0); // Green
}
pixel++ // All the same
pixel += 1 // All the same
pixel = pixel + 1 // All the same
Make all the LED(s) Green (AllLED(s)Green.ino)
#include "FastLED.h"
#define NUM_LEDS 30
#define DATA_PIN D6
CRGB leds[NUM_LEDS]; // Define the array of leds
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}
void loop() {
for( int pixel = 0 ; pixel < NUM_LEDS ; pixel++ ) {
leds[pixel] = CRGB(0, 255, 0); // Green
}
FastLED.show();
}
Make a pattern (MakeAPattern.ino)
Repeat the the sequence of red, green, blue across the entire strip of LED(s)
void loop() {
for( int pixel = 0 ; pixel < NUM_LEDS ; pixel +=3 ) {
leds[pixel+0] = CRGB::Red; // Red
leds[pixel+1] = CRGB(0, 255, 0); // Green
leds[pixel+2] = CRGB(0, 0, 255); // Blue
}
FastLED.show();
}
A very common mistake is “pixel <= NUM_LEDS” �instead of “pixel < NUM_LEDS”. In C we count arrays �from zero (0) instead of one (1)
If Statement
The “if” statement is the most basic of all programming control structures. It allows you to make something happen or not, depending on whether a given condition is true or not. It looks like this:
if (someCondition) {� // do stuff if the condition is true�}
There is a common variation called if-else that looks like this:
if (someCondition) {� // do stuff if the condition is true�} else if (someCondition){� // do stuff if this condition is true�} else {� // do stuff if both of the other condition are false�}
Function: millis()
Returns the number of milliseconds since the board began running the current program. This number will overflow (go back to zero), after approximately 50 days. The millis can be used as a timer.
unsigned long currentTime ;
currentTime = millis(); // currentTime == 0
delay(1000);
currentTime = millis(); // currentTime == 1000
delay(250);
currentTime = millis(); // currentTime == 1250
Creating a timer
Using the millis function and a if statement we can create a timer that triggers an event after a certain amount of time has passed.
We need a global variable to record the last time we triggered the event. Every time we trigger the event we update this global variable with the next time this event should be run.
This example will run every 3 seconds.
unsigned long nextEvent;
void setup() {
nextEvent = 0 ;
}
void loop() {
if( nextEvent < millis() ) {
nextEvent = millis() + (1000 * 3) ;
// Do something interesting
}
Rainbow color (Rainbow.ino)
#include "FastLED.h"
#define COLOR_ORDER GRB
#define NUM_LEDS 30
#define DATA_PIN D6
#define LED_TYPE WS2811
CRGB leds[NUM_LEDS]; // Define the array of leds
uint8_t currentHue ; // variable to hold the Hue�unsigned long nextEvent;
void setup() {
FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
currentHue = 0 ;
nextEvent = 0 ;
}
void loop() {
if( nextEvent < millis() ) {
nextEvent = millis() + 100 ;
currentHue++ ; // Increase the Hue every 100 ms
}
for( int pixel = 0 ; pixel < NUM_LEDS ; pixel++ ) {
leds[pixel] = CHSV(currentHue, 255, 255);
}
FastLED.show();
}
Try this
FastLED advanced features
The FastLED library has many useful functions to do more advanced patterns. fill_rainbow, fill_gradient, fading, scaling, blending, noise, palettes, EVERY_N_MILLIS, . We don’t have time to go through each of these functions in this workshop. I suggest that you check out the FastLED documentation and examples. ��http://fastled.io/docs/3.1/modules.html �http://fastled.io/docs/3.1/colorutils_8h.html
Examples and demos
The Arduino IDE and the FastLED library both come with many examples that you can learn from.
Andrew Tuline (Local from Vancouver) has created a repository of 58 other examples for you to learn from. https://github.com/atuline/FastLED-Demos You will need to update the following parameters to use his examples ��#define LED_DT D6 �#define LED_TYPE WS2811�#define COLOR_ORDER GRB
Another great source for FastLED examples is Marc Miller https://github.com/marmilicious/FastLED_examples
Where to go from here