Cory Potter
Published © Apache-2.0

Making a Lightshow with Arduino

Using an Arduino Nano on an expansion board with a push-button to change the color palette mode of the RGB LED strip.

IntermediateFull instructions provided1 hour7,969
Making a Lightshow with Arduino

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Arduino Nano Expansion Board
×1
WS2811 / WS2812 RGB Light Strips
×1
Push-button switch
×1

Story

Read more

Schematics

Nano Expansion Board

Code

FastLED

C/C++
Use FastLED library and examples
No preview (download only).

Custom FastLED

C/C++
my custom library
/*
* @file CustomFastLED.h
* Copyright (C) 2018 Cory J. Potter - All Rights Reserved
* You may use, distribute and modify this code under the
* terms of the LICENSE.txt
* NOT INTENDED FOR COMMERCIAL USE!
* You should have received a copy of the LICENSE.txt with
* this file. If not, please write to: <bitsandbots@gmail.com>
*/

#ifndef __CUSTOM_FASTLED_H__
#define __CUSTOM_FASTLED_H__

#ifdef ARDUINO

#define NUM_STRIPS 1
#define NUM_LEDS_PER_STRIP 10
// #define NUM_STRIPS 1
// #define NUM_LEDS_PER_STRIP 24
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS
#define BRIGHTNESS 200
uint8_t brightness = BRIGHTNESS;
#define COLOR_ORDER RGB
//#define COLOR_ORDER RGB
//#define COLOR_ORDER BRG
CRGBPalette16 currentPalette;
TBlendType    currentBlending;

CRGB leds[NUM_LEDS];

bool gReverseDirection = false;
// Fire2012 with programmable Color Palette
//
CRGBPalette16 gPal;
// Default 55, suggested range 20-100
int COOLING = 55;
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire.  Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
int SPARKING = 120;

////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t startIndex = 0;
uint8_t selectedMode = 0;
uint8_t selectedPalette = 0;


void calibrateLEDstrip();
void WhiteTwinkle( void );
void Confetti( void );
void EnergyOutput( void );
void EnergyInput( void );
void Fire2012WithPalette();
void SetupOrangeAndWhiteStripedPalette();
void SetupBlackAndWhiteStripedPalette();
void SetupPurpleAndGreenPalette();
void SetupYellowAndOrangePalette();
void SetupRainbowPalette();
void SetupBoyGeorgePalette();
void SetupRedWhiteBluePalette();

void calibrateLEDstrip()
{
	leds[0] = CRGB(255,0,0);
	leds[1] = CRGB(0,255,0);
	leds[2] = CRGB(0,255,0);
	leds[3] = CRGB(0,0,255);
	leds[4] = CRGB(0,0,255);
	leds[5] = CRGB(0,0,255);
	FastLED.show();
	delay(1000);

	for(int i = 0; i < NUM_LEDS; i++) {
		leds[i] = CRGB::Red;
		FastLED.show();
		leds[i] = CRGB::Black;
		delay(100);
	}
}

void WhiteTwinkle( void )
{
	for( int x = NUM_LEDS; x >= 0; x-- )
	{
		leds[x] = CRGB(0,0,0);
		leds[x] = CRGB::AntiqueWhite;
	}
	FastLED.setBrightness(1);
	FastLED.show();
}


void Confetti( void ) {
	FastLED.setBrightness( random( brightness,BRIGHTNESS ) );
	// Dim a color by ~6% (16/256ths), eventually fading to full black.
	fadeToBlackBy(leds, NUM_LEDS, 16);
	int r = random16(NUM_LEDS);
//	if (DEBUG) { Serial.print("r16 = "); Serial.println(r); }
	int r8 = random8();
//	if (DEBUG) { Serial.print("r8 = "); Serial.println(r8); }
	if (!leds[r]) { leds[r] += CHSV( r8, 255, 255); }
	FastLED.show();
	uint8_t control = random(0,2);
	if ( control == 1 ) {
		FastLED.delay(random(50, 100));
	}
}

void EnergyOutput( void )
{
	// First slide the led in one direction
	for(int y = 0; y <= NUM_LEDS; y++) {
		// Set the i'th led to color
		leds[y] = CRGB::AntiqueWhite;
		// Show the leds
		FastLED.show();
		// now that we've shown the leds, reset the i'th led to black
		leds[y] = CRGB::Black;
		// Wait a little bit before we loop around and do it again
		delay( 60 );
		if (DEBUG) { Serial.print("power "); Serial.println(y); }
	}
}

void EnergyInput( void )
{
	// Now go in the other direction.
	for(int n = NUM_LEDS; n >= 0; n--) {
		// Set the i'th led to color
		leds[n] = CRGB::AntiqueWhite;
		// Show the leds
		FastLED.show();
		// now that we've shown the leds, reset the i'th led to black
		leds[n] = CRGB::Black;
		// Wait a little bit before we loop around and do it again
		delay(60);
	}
	
}

void Fire2012WithPalette()
{
	// Array of temperature readings at each simulation cell
	static byte heat[NUM_LEDS];

	// Step 1.  Cool down every cell a little
	for( int i = 0; i < NUM_LEDS; i++) {
		heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
	}
	
	// Step 2.  Heat from each cell drifts 'up' and diffuses a little
	for( int k= NUM_LEDS - 1; k >= 2; k--) {
		heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
	}
	
	// Step 3.  Randomly ignite new 'sparks' of heat near the bottom
	if( random8() < SPARKING ) {
		int y = random8(7);
		heat[y] = qadd8( heat[y], random8(160,255) );
	}

	// Step 4.  Map from heat cells to LED colors
	for( int j = 0; j < NUM_LEDS; j++) {
		// Scale the heat value from 0-255 down to 0-240
		// for best results with color palettes.
		byte colorindex = scale8( heat[j], 240);
		CRGB color = ColorFromPalette( gPal, colorindex);
		int pixelnumber;
		if( gReverseDirection ) {
			pixelnumber = (NUM_LEDS-1) - j;
			} else {
			pixelnumber = j;
		}
		leds[pixelnumber] = color;
	}
}


/********************* COLOR PALETTES *********************/

void SetupOrangeAndWhiteStripedPalette()
{
	// 'black out' all 16 palette entries...
	fill_solid( currentPalette, 16, CRGB::Orange);
	// and set even to white.
	currentPalette[0] = CRGB::White;
	currentPalette[2] = CRGB::White;
	currentPalette[4] = CRGB::White;
	currentPalette[6] = CRGB::White;
	currentPalette[8] = CRGB::White;
	currentPalette[10] = CRGB::White;
	currentPalette[12] = CRGB::White;
	currentPalette[14] = CRGB::White;
}

void SetupBlackAndWhiteStripedPalette()
{
	// 'black out' all 16 palette entries...
	fill_solid( currentPalette, 16, CRGB::Black);
	// and set even to white.
	currentPalette[0] = CRGB::White;
	currentPalette[2] = CRGB::White;
	currentPalette[4] = CRGB::White;
	currentPalette[6] = CRGB::White;
	currentPalette[8] = CRGB::White;
	currentPalette[10] = CRGB::White;
	currentPalette[12] = CRGB::White;
	currentPalette[14] = CRGB::White;
}

// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
	CRGB purple = CHSV( HUE_PURPLE, 255, 255);
	CRGB green  = CHSV( HUE_GREEN, 255, 255);
	CRGB black  = CRGB::Black;
	currentPalette = CRGBPalette16(
	green,  black, purple,
	green,  black, purple,
	green,  black, purple,
	green,  black, purple,
	green,  black, purple, black );
}

// This function sets up a palette of purple and green stripes.
void SetupYellowAndOrangePalette()
{
	CRGB yellow = CHSV( HUE_YELLOW, 255, 255);
	CRGB orange  = CHSV( HUE_ORANGE, 255, 255);
	CRGB black  = CRGB::Black;
	currentPalette = CRGBPalette16(
	yellow,  black, orange,
	yellow,  black, orange,
	yellow,  black, orange,
	yellow,  black, orange,
	yellow,  black, orange,black);
}

void SetupRainbowPalette()
{
	// 'black out' all 16 palette entries...
	fill_solid( currentPalette, 16, CRGB::Black);
	currentPalette[0] = CRGB::Red;
	currentPalette[1] = CRGB::Orange;
	currentPalette[2] = CRGB::Yellow;
	currentPalette[3] = CRGB::Green;
	currentPalette[4] = CRGB::Blue;
	currentPalette[5] = CRGB::Purple;
	currentPalette[6] = CRGB::Red;
	currentPalette[7] = CRGB::Orange;
	currentPalette[8] = CRGB::Yellow;
	currentPalette[9] = CRGB::Green;
	currentPalette[10] = CRGB::Blue;
	currentPalette[11] = CRGB::Purple;
	currentPalette[12] = CRGB::Red;
	currentPalette[13] = CRGB::Orange;
	currentPalette[14] = CRGB::Yellow;
	currentPalette[15] = CRGB::Green;
}

void SetupBoyGeorgePalette()
{
	currentPalette[0] = CRGB::Red;
	currentPalette[1] = CRGB::Gold;
	currentPalette[2] = CRGB::Green;
	currentPalette[3] = CRGB::Red;
	currentPalette[4] = CRGB::Gold;
	currentPalette[5] = CRGB::Green;
	currentPalette[6] = CRGB::Red;
	currentPalette[7] = CRGB::Gold;
	currentPalette[8] = CRGB::Green;
	currentPalette[9] = CRGB::Red;
	currentPalette[10] = CRGB::Gold;
	currentPalette[11] = CRGB::Green;
	currentPalette[12] = CRGB::Red;
	currentPalette[13] = CRGB::Gold;
	currentPalette[14] = CRGB::Green;
	currentPalette[15] = CRGB::Red;
}
void SetupRedWhiteBluePalette()
{
	// 'black out' all 16 palette entries...
	fill_solid( currentPalette, 16, CRGB::Black);
	currentPalette[0] = CRGB::Red;
	currentPalette[1] = CRGB::White;
	currentPalette[2] = CRGB::Blue;
	currentPalette[4] = CRGB::Red;
	currentPalette[5] = CRGB::White;
	currentPalette[6] = CRGB::Blue;
	currentPalette[7] = CRGB::Red;
	currentPalette[8] = CRGB::White;
	currentPalette[9] = CRGB::Blue;
	currentPalette[10] = CRGB::Red;
	currentPalette[11] = CRGB::White;
	currentPalette[12] = CRGB::Blue;
	currentPalette[13] = CRGB::Red;
	currentPalette[14] = CRGB::White;
	currentPalette[15] = CRGB::Blue;
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
	for( int i = 0; i < NUM_LEDS; i++) {
		leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
		colorIndex += 1;
	}
}

void ChangePalette( uint8_t mode )
{
	switch ( mode )
	{
		case 1:  currentPalette = RainbowColors_p;
		break;
		case 2:   currentPalette = CloudColors_p;
		break;
		case 3:   currentPalette = OceanColors_p;
		break;
		case 4:  currentPalette = PartyColors_p;
		break;
		case 5:  currentPalette = ForestColors_p;
		break;
		case 6:	 SetupRainbowPalette();
		break;
		case 7:  SetupBoyGeorgePalette();
		break;
		case 8:  SetupRedWhiteBluePalette();
		break;
		case 9:  SetupOrangeAndWhiteStripedPalette();
		break;
		case 10:  SetupBlackAndWhiteStripedPalette();
		break;
		case 11:  SetupPurpleAndGreenPalette();
		break;
		case 12:  SetupYellowAndOrangePalette();
		break;
	}
}


#else
#error This code is only for use on Arduino.
#endif // ARDUINO
#endif // __CUSTOM_FASTLED_H__

Credits

Cory Potter

Cory Potter

9 projects • 88 followers
Technical Craftsman specializing in bridging the gap between electronics and software engineering, with unconventional approach to problems.

Comments