Project 5.05 Individually Fading Neopixels

In this project we will create a dynamic light display using two Neopixels. The objective is to smoothly transition one Neopixel from off to full brightness while simultaneously dimming the other from full brightness to off, and then reversing this process.

////////////////////////////////////////////////////////
#include <Adafruit_NeoPixel.h>

byte dataPin = 10;
byte numberOfPixels = 2;
byte brightness = 255;

Adafruit_NeoPixel pixels(numberOfPixels, dataPin, NEO_GRB + NEO_KHZ800);
void setup() {
  pixels.begin();
  pixels.setBrightness(brightness);
  pixels.show();
}

void loop() {

  for (uint8_t i = 0; i < 255; i++) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));
    pixels.show();
    delay(5);
  }

  for (uint8_t i = 255; i > 0; i--) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));
    pixels.show();
    delay(5);
  }
}
////////////////////////////////////////////////////////

*If you’re copying and pasting the code, or typing from scratch, delete everything out of a new Arduino sketch and paste / type in the above text.

The setup of the Neopixels is the same as the other Neopixel projects, so we’ll skip straight to the loop() section. In the loop() there are two for-loops that control the behavior of the Neopixels:

void loop() {

  for (uint8_t i = 0; i < 255; i++) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));
    pixels.show();
    delay(5);                                     
  }

  for (uint8_t i = 255; i > 0; i--) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));
    pixels.show();
    delay(5);                                      
  }
}  

The first for-loop counts from 0 to 255 and writes that value to Neopixel number 0. Since we are setting the green and blue values of that Neopixel to 0 and just writing to the red portion, this has the effect of increasing the brightness of that Neopixel with the count:

  for (uint8_t i = 0; i < 255; i++) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));

The next line of code in the for-loop writes to Neopixel number 1. This time instead of writing the for-loop count directly to the Neopixel, we first subtract it from 255. If you remember from lesson 5.00, the Color function takes 8-bit values (0-255) to represent red, green, and blue. So if we subtract the current for-loop() count from 255 before we write it to the NeoPixel it gives us the inverse of the loop count. This effectively gives us an inverse brightness for Neopixel number 1 from Neopixel number 0.

    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));

Next, the neopixels are updated with the show() function and the program is delayed by 5 milliseconds. The program needs to be slowed down so we can actually see the Neopixel transition smoothly.

    pixels.show();
    delay(5);                                     
  }

The Second for loop is the same as the first for-loop with the exception that the count is started from 255 and counts down to 0. This allows Neopixel number 0 to start at 255 and count down. The same inverse relationship is kept with Neopixel number 0 and Neopixel number 1.

  for (uint8_t i = 255; i > 0; i--) {
    pixels.setPixelColor(0, pixels.Color(i, 0, 0));
    pixels.setPixelColor(1, pixels.Color(255 - i, 0, 0));
    pixels.show();
    delay(5);                                      
  }

This relationship can be elegantly illustrated with a graph of two cosine waves stacked on top of each other with one 180 degrees out of phase:

When one Neopixel is at it’s peak in terms of color intensity, the other is at it’s lowest point.

Previous
Previous

Project 6.00 Using the Potentiometer

Next
Next

Project 5.04 Fading Neopixels Using Buttons