Anytime I immerse myself in a project like this I come away with a newfound respect for the sheer genius of the Apollo-era NASA engineers.  To the moon - and back!  Having far, far less with which to work!

Much of the code below had been pounded heavily to fit in the PIC's RAM.  A few things have been re-re-re-re-written to use less program memory but I think one of the biggest challenges came from holding firm to the requirement to support up to 256 NeoPixels.  Clinging (sometimes desperately!) to that capability colored how most of the algorithms were finally implemented.

Alternating Foreground/Background Floods

{   /* style 1: alternating foreground/background floods */

  FloodParams_t*  pFlood1;

  FloodParams_t*  pFlood2;



  pFlood1 = (SCALED_RAND( 2 ) == 0) ? (FloodParams_t*) &FloodAllOff : &Flood1;



  /* If I'm to use them, fill in the first set of flood parameters. */

  if( pFlood1 != &FloodAllOff )
    {

      SetFloodParams( pFlood1 /* pFloodParams */,
                      0 /* FirstPixel */,
                      NumPixelsToDrive - 1 /* LastPixel */,
                      SCALED_RAND( 19 ) /* ForegroundRed */,
                      SCALED_RAND( 19 ) /* ForegroundGreen */,
                      SCALED_RAND( 19 ) /* ForegroundBlue */,
                      RANGED_RAND( 3, 17 ) /* Stride */,
                      SCALED_RAND( 3 ) /* BackgroundRed */,
                      SCALED_RAND( 3 ) /* BackgroundGreen */,
                      SCALED_RAND( 3 ) /* BackgroundBlue */ );



      pFlood2 = (SCALED_RAND( 2 ) == 0) ? (FloodParams_t*) &FloodAllOff : &Flood2;


    }
  else   /* pFlood1 calls for "all off"... */
    {

      pFlood2 = &Flood2;


    }   /* close if( pFlood1 ... */



  /* If I'm to use them, fill in the second set of flood parameters. */

  if( pFlood2 != &FloodAllOff )
    {

      SetFloodParams( pFlood2 /* pFloodParams */,
                      1 /* FirstPixel */,
                      NumPixelsToDrive - 1 /* LastPixel */,
                      SCALED_RAND( 2 ) /* ForegroundRed */,
                      SCALED_RAND( 2 ) /* ForegroundGreen */,
                      SCALED_RAND( 2 ) /* ForegroundBlue */,
                      RANGED_RAND( 3, 17 ) /* Stride */,
                      SCALED_RAND( 8 ) /* BackgroundRed */,
                      SCALED_RAND( 8 ) /* BackgroundGreen */,
                      SCALED_RAND( 8 ) /* BackgroundBlue */ );


    }   /* close if( pFlood2 ... */



  Alternate( pFlood1 /* pForeFlood */,
             RANGED_RAND( 17, 377 ) /* ForeHold_mSec */,
             pFlood2 /* pBackFlood */,
             RANGED_RAND( 40, 730 ) /* BackHold_mSec */,
             RANGED_RAND( 793, 4076 ) /* Duration_mSec */ );


}

"Fib Rand Sine"

{   /* style 2: Fib Rand Sine (with hat tip to Auld Lang Syne) */

  SetFloodParams( &Flood1 /* pFloodParams */,
                  0 /* FirstPixel */,
                  NumPixelsToDrive - 1 /* LastPixel */,
                  0 /* ForegroundRed */,
                  0 /* ForegroundGreen */,
                  0 /* ForegroundBlue */,
                  0 /* Stride */,
                  0 /* BackgroundRed */,
                  0 /* BackgroundGreen */,
                  0 /* BackgroundBlue */ );



  Red_AmplitudeOffset = 0;

  Red_MaxAmplitude = RANGED_RAND( 1, 12 );

  Red_PhaseShift = 0.0;

  Red_ArgMultiplicand = Factors[ SCALED_RAND( NUMELEMS( Factors ) ) ];

  Red_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ];



  Green_AmplitudeOffset = 0;

  Green_MaxAmplitude = RANGED_RAND( 1, 12 );

  Green_PhaseShift = 0.0;

  Green_ArgMultiplicand = Factors[ SCALED_RAND( NUMELEMS( Factors ) ) ];

  Green_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ];



  Blue_AmplitudeOffset = 0;

  Blue_MaxAmplitude = RANGED_RAND( 1, 12 );

  Blue_PhaseShift = 0.0;

  Blue_ArgMultiplicand = Factors[ SCALED_RAND( NUMELEMS( Factors ) ) ];

  Blue_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ];



  FloodRgbFunc( &Flood1 /* pFloodParams */ );


}

Strobies in a Flood Field

{   /* style 3: strobies in a flood field (or whatever is lingering). */

  SetFloodParams( &Flood1 /* pFloodParams */,
                  0 /* FirstPixel */,
                  NumPixelsToDrive - 1 /* LastPixel */,
                  RANGED_RAND( 0, 3 ) /* ForegroundRed */,
                  RANGED_RAND( 1, 3 ) /* ForegroundGreen */,
                  RANGED_RAND( 0, 3 ) /* ForegroundBlue */,
                  RANGED_RAND( 50, 200 ) /* Stride/NumStrobies */,
                  RANGED_RAND( 70, 137 ) /* BackgroundRed */,
                  RANGED_RAND( 70, 137 ) /* BackgroundGreen */,
                  RANGED_RAND( 70, 137 ) /* BackgroundBlue */ );



  Strobies( &Flood1 );



  Delay_mSec( RANGED_RAND( 400, 1200 ) /* Milliseconds */ );


}

Intensity Ramp

{   /* style 4: intensity ramp */

  /* Select a color and ramp it up or down. */

  Red = RANGED_RAND( 0, 1 );

  Green = RANGED_RAND( 0, 1 );

  Blue = RANGED_RAND( 0, 1 );



  /* Disallow "all-off": bail and just make it BlueGreen. */

  if( (Red == 0) &&
      (Green == 0) &&
      (Blue == 0) )
    {

      Green = 1;

      Blue = 1;


    }   /* close if( (Red ... */



  RampUp = (SCALED_RAND( 2 ) == 0) ? TRUE : FALSE;



  NumSteps = RANGED_RAND( 10, 27 );


  NumSteps += 1;   /* Ensure the limit (either the maximum intensity or 0) is rendered. */



  RampDelay_mSec = RANGED_RAND( 30, 170 );



  Intensity = RampUp ? 0 : NumSteps;   /* Set the intensity starting point (high or low). */



  for( Step = 0; Step < NumSteps; Step++ )
    {

      SetFloodParams( &Flood1 /* pFloodParams */,
                      0 /* FirstPixel */,
                      NumPixelsToDrive - 1 /* LastPixel */,
                      Red * Intensity /* ForegroundRed */,
                      Green * Intensity /* ForegroundGreen */,
                      Blue * Intensity /* ForegroundBlue */,
                      0 /* Stride/NumStrobies */,
                      0 /* BackgroundRed */,
                      0 /* BackgroundGreen */,
                      0 /* BackgroundBlue */ );



      Flood( &Flood1 );



      Delay_mSec( RampDelay_mSec /* Milliseconds */ );



      /* Adjust the intensity according to the ramp direction. */

      Intensity = RampUp ? (Intensity + 1) : (Intensity - 1);


    }   /* close for( Step ... */



  Delay_mSec( 150 );

}

Sine Springboard

{   /* style 5: sine springboard */

  SetFloodParams( &Flood1 /* pFloodParams */,
                  0 /* FirstPixel */,
                  NumPixelsToDrive - 1 /* LastPixel */,
                  0 /* ForegroundRed */,
                  0 /* ForegroundGreen */,
                  0 /* ForegroundBlue */,
                  0 /* Stride */,
                  0 /* BackgroundRed */,
                  0 /* BackgroundGreen */,
                  0 /* BackgroundBlue */ );



  Red_AmplitudeOffset = 0;

  Red_MaxAmplitude = RANGED_RAND( 1, 7 );

  Red_PhaseShift = 0.0;

  Red_ArgMultiplicand = M_PI;

  Red_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ];



  Green_AmplitudeOffset = 0;

  Green_MaxAmplitude = Red_MaxAmplitude + RANGED_RAND( 0, 4 ); 

  Green_PhaseShift = 0.0;
  
  Green_ArgMultiplicand = M_PI;

  Green_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ]; 



  Blue_AmplitudeOffset = 0;

  Blue_MaxAmplitude = Red_MaxAmplitude + RANGED_RAND( 0, 7 );

  Blue_PhaseShift = 0.0;

  Blue_ArgMultiplicand = M_PI;

  Blue_ArgDivisor = Fib[ RANGED_RAND( 6, NUMELEMS( Fib ) ) ];



  FloodRgbFunc( &Flood1 /* pFloodParams */ );


}

Color Component Leach

{   /* style 6: color component leach */

  uint8_t  RedCeiling;

  uint8_t  GreenCeiling;

  uint8_t  BlueCeiling;



  /* Select a color and accrete up or leach down. */

  RedCeiling = RANGED_RAND( 0, 21 );

  GreenCeiling = RANGED_RAND( 0, 21 );

  BlueCeiling = RANGED_RAND( 0, 21 );



  /* Disallow "all-off": bail and just make it some nice violet. */

  if( (Red == 0) &&
      (Green == 0) &&
      (Blue == 0) )
    {

      RedCeiling = RANGED_RAND( 1, 21 );

      BlueCeiling = RANGED_RAND( 1, 21 );


    }   /* close if( (Red ... */



  RampUp = (SCALED_RAND( 2 ) == 0) ? TRUE : FALSE;



  NumSteps = max( RedCeiling, GreenCeiling );

  NumSteps = max( NumSteps, BlueCeiling );



  NumSteps += 1;   /* Ensure the limit (either the maximum ceiling or 0) is rendered. */



  RampDelay_mSec = RANGED_RAND( 30, 170 );



  /* Set the starting points based on if I'm accreting up or leaching down. */

  if( RampUp )
    {

      Red = 0;

      Green = 0;

      Blue = 0;


    }
  else   /* going down... */
    {

      Red = RedCeiling;

      Green = GreenCeiling;

      Blue = BlueCeiling;


    }   /* close if( RampUp ... else */



  for( Step = 0; Step < NumSteps; Step++ )
    {

      SetFloodParams( &Flood1 /* pFloodParams */,
                      0 /* FirstPixel */,
                      NumPixelsToDrive - 1 /* LastPixel */,
                      Red /* ForegroundRed */,
                      Green /* ForegroundGreen */,
                      Blue /* ForegroundBlue */,
                      0 /* Stride/NumStrobies */,
                      0 /* BackgroundRed */,
                      0 /* BackgroundGreen */,
                      0 /* BackgroundBlue */ );



      Flood( &Flood1 );



      Delay_mSec( RampDelay_mSec /* Milliseconds */ );



      /* Adjust the colors according to the ramp direction. */

      if( RampUp )
        {

          Red = (Red < RedCeiling) ? Red + 1 : Red;

          Green = (Green < GreenCeiling) ? Green + 1 : Green;

          Blue = (Blue < BlueCeiling) ? Blue + 1 : Blue;


        }
      else   /* going down... */
        {

          Red = (Red > 0) ? Red - 1 : 0;

          Green = (Green > 0) ? Green - 1 : 0;

          Blue = (Blue > 0) ? Blue - 1 : 0;


        }   /* close if( RampUp ... else */


    }   /* close for( Step ... */



  Delay_mSec( 376 /* Milliseconds */ );


}

Strobies Leaving a Random Terminal Color

{   /* style 7: strobies in a flood field (or whatever is lingering) leaving a random terminal color -
     * candy!.
     *
     ***/

  SetFloodParams( &Flood1 /* pFloodParams */,
                  0 /* FirstPixel */,
                  NumPixelsToDrive - 1 /* LastPixel */,
                  0 /* ForegroundRed */,
                  0 /* ForegroundGreen */,
                  0 /* ForegroundBlue */,
                  RANGED_RAND( 100, 250 ) /* Stride/NumStrobies */,
                  RANGED_RAND( 70, 137 ) /* BackgroundRed */,
                  RANGED_RAND( 70, 137 ) /* BackgroundGreen */,
                  RANGED_RAND( 70, 137 ) /* BackgroundBlue */ );



  Strobies( &Flood1 );



  Delay_mSec( RANGED_RAND( 700, 1400 ) /* Milliseconds */ );


}

This guide was first published on Oct 28, 2014. It was last updated on Oct 28, 2014.

This page (Software: set some bits, clear some bits: stuff happens) was last updated on Oct 23, 2014.

Text editor powered by tinymce.