1 of 51

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

2 of 51

What are we doing today

  • Introduction and setup of the Arduino IDE
  • An extremely short introduction to programming.
  • How to install 3rd party libraries in the Arduino IDE. FastLED
  • How LED strips work, and tips and tricks.
  • How to make simple pattern for the LED strips.
  • Examples and demos

Wifi SSID: MakerLabs�Password: Ecordova

Preparation

  • Download and install the Arduino IDE �https://www.arduino.cc/
  • Download the slides from https://bit.ly/2FpLrAE
  • MAC drivers for Wemos (ESP8266) https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver

Hardware

  • ESP8266 (Microcontroller)
  • LED strip (WS2812B aka Neopixels) NeoPixels is the brand name of the WS2812B LED(s)

3 of 51

Anatomy of an NeoPixel (WS2812) RGB LED

4 of 51

Pinout of a WeMos (ESP8266) board

5 of 51

Setup the Arduino IDE (Step 1)

To install the ESP8266 board in your Arduino IDE, follow these next instructions:

  1. Open the preferences window from the Arduino IDE. Go to File > Preferences�
  2. Enter http://arduino.esp8266.com/stable/package_esp8266com_index.json into the “Additional Board Manager URLs” field as shown in the figure below. Then, click the “OK” button.

6 of 51

Setup the Arduino IDE (Step 2)

  1. Open boards manager. Go to �Tools > Board > Boards Manager…
  1. Scroll down, select the ESP8266 board menu and install “esp8266 by ESP8266 Community

7 of 51

Setup the Arduino IDE (Step 3)

  1. Choose your ESP8266 board from �Tools > Board > WeMos D1 R1 & Mini
  • Select the serial port from the tools menu �Tools > Port > COM10 �(Your comport might be different)
  • Load example blink script �File > Examples > 01.Basics > Blink

void setup() {

pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {

digitalWrite(LED_BUILTIN, HIGH);

delay(1000);

digitalWrite(LED_BUILTIN, LOW);

delay(1000);

}

8 of 51

Setup the Arduino IDE (Step 4) - Upload !

  1. Upload the sketch to the ESP8266 board. �Sketch > Upload

9 of 51

10 of 51

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.

11 of 51

12 of 51

Blink Sketch

// The setup function runs once when you press reset or power the boardvoid setup() {� pinMode(LED_BUILTIN, OUTPUT); // Initialize build in led pin as an output.�}

// The loop function runs over and over again forevervoid 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

13 of 51

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:

  • Stay organized
  • Functions make the whole sketch smaller and more compact because sections of code are reused many times.
  • They make it easier to reuse code in other programs by making it more modular, and as a nice side effect, using functions also often makes the code more readable.

14 of 51

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 numbervalue: HIGH or LOW

15 of 51

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)

16 of 51

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 forevervoid 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�}

17 of 51

Try this

  • Change the blink sketch to make the LED blink faster or slower. �*Hint:* You can change the value in the delay function.
  • Change the blink sketch to make a pattern. Do SOS in morse code. Three short blinks, three long blinks, three short blinks. �*Hint:* Copy and paste the code a few times.

18 of 51

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 forevervoid 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�}

19 of 51

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.

  • int (-32768 to 32767 is 16 bit signed)
  • uint (0 to 65535 is 16 bit unsigned)
  • uint8_t (0 to 255 is 8 bit unsigned)
  • long (is 32 bits signed)
  • and many more. . .

void loop() {� // Variable declarationint OneSecond = 1000 ;� � // Wait for half second� delay(OneSecond / 2); digitalWrite(LED_BUILTIN, LOW);�� // Wait for two seconds� delay(OneSecond * 2);� digitalWrite(LED_BUILTIN, HIGH);�}

20 of 51

Next up is the LED strips

21 of 51

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

22 of 51

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.

23 of 51

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)

24 of 51

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.

25 of 51

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!

26 of 51

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.

27 of 51

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�

28 of 51

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).

29 of 51

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!

30 of 51

Where to get more support

  • Electronics Stack Exchange - A great place to ask questions from experts. It can be a little overwhelming. �https://electronics.stackexchange.com/
  • Hackaday - Showcase of awesome projects and news about what is new and shiny. https://hackaday.com/
  • Hit me up on social media Instagram, Twitter, Github: @Funvill https://blog.abluestar.com/

31 of 51

Install 3rd party libraries

  1. Find the following 3rd party library using the library manager �Sketch > Include Library > Manage Libraries�
  2. Install “FastLED” by Daniel Garcia�
  3. Install “Blynk” by Volodymyr Shymanskyy

32 of 51

FastLED library

What is the FastLED library?

  • FastLED is a fast, easy-to-use Arduino library for programming addressable LED strips.
  • FastLED is used by thousands of developers. Do a YouTube search for ‘FastLED’ to see examples projects.
  • It supports multiple microcontroller platforms and multiple addressable LED types.
  • It’s FAST! Its built from the ground up to be the fastest LED library around. It’s really really fast.

FastLED contains a LOT of functions including:

  • Reasonably good random number generation
  • Fast 8 and 16 bit basic math functions
  • Fast trigonometry
  • Setting RGB and HSV values
  • Helpful functions fill_rainbow, fill_gradient, fading, scaling, blending, noise, palettes
  • Power management
  • And lots more…

33 of 51

Test the LED(s), ESP8266, and FastLED library

  1. Connect the LED(s) to the ESP8266 �
  2. In Arduino IDE, Load the FastLED demo reel. File > Examples > FastLED > DemoReel100 �
  3. Change the DATA_PIN to D6 (Line 18)�#define DATA_PIN D6�
  4. Upload!

The LED should change pattern every 10 seconds or so.

34 of 51

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();

}

35 of 51

36 of 51

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);

37 of 51

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

http://www.colorspire.com

38 of 51

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

39 of 51

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();

40 of 51

Try this

Update the sketch to make a pattern of �Yellow, Green, Blue, Magenta, Purple, Red

41 of 51

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

42 of 51

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();

}

43 of 51

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)

44 of 51

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�}

45 of 51

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

46 of 51

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

}

47 of 51

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();

}

48 of 51

Try this

  • Create a sketch where a single green LED moves though the length of the strip from one end of the strip to the other. �*Hint*: Every 1 second increment a counter. The counter is the offset. �
  • Change pattern every 30 seconds, to one of three different patterns �*Hint*: Increment a counter for the pattern and use a if,else if, else to show the current pattern
  • Make a pattern that blinks the LED(s) like a beating heart/pulse �*Hint*: Google “Cardiac cycle” for the timing. �
  • Make all the LEDs have random color, wait 2 seconds and repeat. �*Hint*: Use the random() function

49 of 51

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.htmlhttp://fastled.io/docs/3.1/colorutils_8h.html

50 of 51

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

51 of 51

Where to go from here

  • Control the LED(s) from internet via your cell phone using Blynk (BlynkBlink.ino)
  • Control the LED(s) with If This Then That (IFTTT) and schedule tasks https://ifttt.com/
    • Turn on at 5pm, or wake me up in the morning as an alarm clock
  • Add sensors like microphone to make it reactive to sound.
  • Add buttons to trigger certain effects.