Fading Hourglass

Our previous code simply waited at each NeoPixel the computed amount of time DT, and then turned the NeoPixel off. Now let's change things so that the NeoPixel fades out over this period of time.

Basically, we need to go one level deeper on our time line. Now, within each time slice DT, instead of doing nothing, we'll be fading the NeoPixel. See the figure below.

The value N is just an arbitrary number of steps over which the fading will occur. This further divides the time slice DT into smaller slices, called FADE_DT in the figure above.

The simplest way to fade a NeoPixel is to linearly change the setting from its starting value down to zero. The NeoPixels on the Circuit Playground have red, green, and blue LEDs in them, so we do the same thing for each of the color components individually. This idea is shown in the figure below.

So at each of the fading time steps, we decrease the red, green, and blue values by a small amount. After doing this N times, the values will reach 0.

OK, here's our final code, with flip-to-reset and fading NeoPixel grains of sand.

Download: file
///////////////////////////////////////////////////////////////////////////////
// Circuit Playground Fading Hourglass
//
// Author: Carter Nelson
// MIT License (https://opensource.org/licenses/MIT)

#include <Adafruit_CircuitPlayground.h>

#define COUNT_TIME    30000 // milliseconds
#define FADE_STEPS    100   // NeoPixel fade steps
#define R_SAND        255   // Sand color RED value
#define G_SAND        255   // Sand color GREEN value
#define B_SAND        255   // Sand color BLUE value

unsigned long DT;
float r, g, b;
float dr, dg, db;

///////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(9600);
  
  // Initialize the Circuit Playground
  CircuitPlayground.begin();

  // Compute per NeoPixel wait time
  DT = COUNT_TIME / 10;
  
  // Compute the color value change per fade step
  dr = float(R_SAND) / float(FADE_STEPS);
  dg = float(G_SAND) / float(FADE_STEPS);
  db = float(B_SAND) / float(FADE_STEPS);
}

///////////////////////////////////////////////////////////////////////////////
void loop() {
  // Turn ON all the NeoPixels
  for (int p=0; p<10; p++) {
    CircuitPlayground.setPixelColor(p, uint8_t(R_SAND), 
                                       uint8_t(G_SAND), 
                                       uint8_t(B_SAND));
  }
  
  // Loop over each NeoPixel
  for (int p=0; p<10; p++) {
    // Set the start RGB values
    r = float(R_SAND);
    g = float(G_SAND);
    b = float(B_SAND);
    // Loop over each fading step
    for (int n=0; n<FADE_STEPS; n++) {
      delay(DT/FADE_STEPS); // Per fade step delay
      r = r - dr;           // Decrease the red value
      g = g - dg;           //    "      "  green "
      b = b - db;           //    "      "  blue  "
      CircuitPlayground.setPixelColor(p, uint8_t(r),
                                         uint8_t(g),
                                         uint8_t(b));      
    }
  }
  
  // Wait for Circuit Playground to be flipped over (face down)
  while (CircuitPlayground.motionZ() > 0) {};

  // A little debounce
  delay(500);

  // Wait for Circuit Playground to be flipped back over (face up)
  while (CircuitPlayground.motionZ() < 0) {};
}
This guide was first published on Dec 29, 2016. It was last updated on Dec 29, 2016. This page (Fading Hourglass) was last updated on Jun 16, 2019.