My version of Mark's holiday lights....

My version of Mark’s holiday lights…

never quite got the density right…but I’m from the school of coding where I just start changing numbers in the sketch to see what it do & if I like it or not…

f34e6380de5b6b5617860a29bdc6bfb3.gif

Wait, is this legit? You’ve installed LED strips inside the back panels of a bunch of servers?

I have indeed…gonna be a prop on a TV show…they don’t like fans :wink: AND they’re shooting in a fer-reals data center which means heat is an issue as well…plus, the network switches don’t really light up unless you’re passing network traffic…so a strip or so and a wee proc & off we go!

Bravo! Can we submit code to appear in every new episode? Haha
Are you guys hiring BTW? :wink:

heh…if you’re in NY & in IATSE, I could use ya! (but I DO need some code help…I’m clueless…for instance, I wanted to make the pattern more dense-more lights on/flickering at once, with that activity light feel, and this was as close as I got…thanks to Mark’s great commenting in the sketch…) the 2nd server is actually using a box I had made & coded with some preset patterns in it & controls…doesn’t use FastLED though…all c++ sketching which makes me more confused…

Well, I’m on the west coast…if figured TV “he’s in LA”. I specialize in metal work/welding.

If you share the code here, I’m sure plenty of people will chime in, or if you want to keep it private you can email it to me. I’m no professional programmer, but I make up for it in patience and persistence.

its just Mark’s holiday twinkle code & I changed the numbers I saw to try and make more ‘activity light-ish’ I cranked up the density trying to get more pixels on at once…it sorta worked, but I wanted more…

#include “FastLED.h”

#define LED_PIN 8
#define LED_TYPE WS2811
#define COLOR_ORDER RGB
#define NUM_LEDS 225
CRGB leds[NUM_LEDS];

// Twinkling ‘holiday’ lights that fade up and down in brightness.
// Colors are chosen from a palette; a few palettes are provided.
//
// The basic operation is that all pixels stay black until they
// are ‘seeded’ with a relatively dim color. The dim colors
// are repeatedly brightened until they reach full brightness, then
// are darkened repeatedly until they are fully black again.
//
// A set of ‘directionFlags’ is used to track whether a given
// pixel is presently brightening up or darkening down.
//
// For illustration purposes, two implementations of directionFlags
// are provided: a simple one-byte-per-pixel flag, and a more
// complicated, more compact one-BIT-per-pixel flag.
//
// Darkening colors accurately is relatively easy: scale down the
// existing color channel values. Brightening colors is a bit more
// error prone, as there’s some loss of precision. If your colors
// aren’t coming our ‘right’ at full brightness, try increasing the
// STARTING_BRIGHTNESS value.
//
// -Mark Kriegsman, December 2014

#define MASTER_BRIGHTNESS 200

#define STARTING_BRIGHTNESS 100
#define FADE_IN_SPEED 250
#define FADE_OUT_SPEED 150
#define DENSITY 500000

void setup() {
delay(2);
FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MASTER_BRIGHTNESS);
}

void loop()
{
chooseColorPalette();
colortwinkles();
FastLED.show();
FastLED.delay(1);
}

CRGBPalette16 gPalette;

void chooseColorPalette()
{
uint8_t numberOfPalettes = 5;
uint8_t secondsPerPalette = 10;
uint8_t whichPalette = (millis()/(1*secondsPerPalette)) % numberOfPalettes;

CRGB r(CRGB::Red), b(CRGB::Blue), w(85,85,85), g(CRGB::Green), W(CRGB::White), l(0xE1A024);

switch( whichPalette) {
case 0: // Red, Green, and White
gPalette = CRGBPalette16( r,r,r,r, b,b,b,b, g,g,g,g, w,w,w,w );
break;
case 1: // Blue and White
//gPalette = CRGBPalette16( b,b,b,b, b,b,b,b, w,w,w,w, w,w,w,w );
gPalette = CloudColors_p; // Blues and whites!
break;
case 2: // Rainbow of colors
gPalette = RainbowColors_p;
break;
case 3: // Incandescent “fairy lights”
gPalette = CRGBPalette16( l,l,l,l, l,l,l,l, l,l,l,l, l,l,l,l );
break;
case 4: // Snow
gPalette = CRGBPalette16( W,W,W,W, w,w,w,w, w,w,w,w, w,w,w,w );
break;
}
}

enum { GETTING_DARKER = 0, GETTING_BRIGHTER = 1 };

void colortwinkles()
{
// Make each pixel brighter or darker, depending on
// its ‘direction’ flag.
brightenOrDarkenEachPixel( FADE_IN_SPEED, FADE_OUT_SPEED);

// Now consider adding a new random twinkle
if( random8() < DENSITY ) {
int pos = random16(NUM_LEDS);
if( !leds[pos]) {
leds[pos] = ColorFromPalette( gPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
setPixelDirection(pos, GETTING_BRIGHTER);
}
}
}

void brightenOrDarkenEachPixel( fract8 fadeUpAmount, fract8 fadeDownAmount)
{
for( uint16_t i = 0; i < NUM_LEDS; i++) {
if( getPixelDirection(i) == GETTING_DARKER) {
// This pixel is getting darker
leds[i] = makeDarker( leds[i], fadeDownAmount);
} else {
// This pixel is getting brighter
leds[i] = makeBrighter( leds[i], fadeUpAmount);
// now check to see if we’ve maxxed out the brightness
if( leds[i].r == 255 || leds[i].g == 255 || leds[i].b == 255) {
// if so, turn around and start getting darker
setPixelDirection(i, GETTING_DARKER);
}
}
}
}

CRGB makeBrighter( const CRGB& color, fract8 howMuchBrighter)
{
CRGB incrementalColor = color;
incrementalColor.nscale8( howMuchBrighter);
return color + incrementalColor;
}

CRGB makeDarker( const CRGB& color, fract8 howMuchDarker)
{
CRGB newcolor = color;
newcolor.nscale8( 255 - howMuchDarker);
return newcolor;
}

// For illustration purposes, there are two separate implementations
// provided here for the array of ‘directionFlags’:
// - a simple one, which uses one byte (8 bits) of RAM for each pixel, and
// - a compact one, which uses just one BIT of RAM for each pixel.

// Set this to 1 or 8 to select which implementation
// of directionFlags is used. 1=more compact, 8=simpler.
#define BITS_PER_DIRECTION_FLAG 1

#if BITS_PER_DIRECTION_FLAG == 8
// Simple implementation of the directionFlags array,
// which takes up one byte (eight bits) per pixel.
uint8_t directionFlags[NUM_LEDS];

bool getPixelDirection( uint16_t i) {
return directionFlags[i];
}

void setPixelDirection( uint16_t i, bool dir) {
directionFlags[i] = dir;
}
#endif

#if BITS_PER_DIRECTION_FLAG == 1
// Compact (but more complicated) implementation of
// the directionFlags array, using just one BIT of RAM
// per pixel. This requires a bunch of bit wrangling,
// but conserves precious RAM. The cost is a few
// cycles and about 100 bytes of flash program memory.
uint8_t directionFlags[ (NUM_LEDS+7) / 8];

bool getPixelDirection( uint16_t i) {
uint16_t index = i / 8;
uint8_t bitNum = i & 0x07;
// using Arduino ‘bitRead’ function; expanded code below
return bitRead( directionFlags[index], bitNum);
// uint8_t andMask = 1 << bitNum;
// return (directionFlags[index] & andMask) != 0;
}

void setPixelDirection( uint16_t i, bool dir) {
uint16_t index = i / 8;
uint8_t bitNum = i & 0x07;
// using Arduino ‘bitWrite’ function; expanded code below
bitWrite( directionFlags[index], bitNum, dir);
// uint8_t orMask = 1 << bitNum;
// uint8_t andMask = 255 - orMask;
// uint8_t value = directionFlags[index] & andMask;
// if( dir ) {
// value += orMask;
// }
// directionFlags[index] = value;
}
#endif

“Routers don’t look like routers on TV, you gotta use a ColecoVision…”

Uh, Sir, why don

Here’s how I added more density: see the part of the code where it says this?
// Now consider adding a new random twinkle
if( random8() < DENSITY ) {
int pos = random16(NUM_LEDS);
if( !leds[pos]) {
leds[pos] = ColorFromPalette( gPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
setPixelDirection(pos, GETTING_BRIGHTER);
}
}

Just wrap that with a little for loop that does that two or three times:

for( int repeat=0; repeat<3; repeat++) {
// Now consider adding a new random twinkle
if( random8() < DENSITY ) {
int pos = random16(NUM_LEDS);
if( !leds[pos]) {
leds[pos] = ColorFromPalette( gPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
setPixelDirection(pos, GETTING_BRIGHTER);
}
}
}

The other thing you can do is put in a line that says “if the first random pixel position chosen is already lit, try picking another, once”:

for( int repeat=0; repeat<3; repeat++) {
// Now consider adding a new random twinkle
if( random8() < DENSITY ) {
int pos = random16(NUM_LEDS);
if( leds[pos]) pos = random16(NUM_LEDS); // try again
if( !leds[pos]) {
leds[pos] = ColorFromPalette( gPalette, random8(), STARTING_BRIGHTNESS, NOBLEND);
setPixelDirection(pos, GETTING_BRIGHTER);
}
}
}

And did I mention that this looks super cool!!? Can you share what show this is for? Looks great!

thanks for the suggestion! I’ll give that a shop later today…was making the density variable 5000000 fruitless? where should that live?

its for a new show called ‘Odyssey’ pretty sure it’s NBC…things are crazy stooped busy in NY right now with a bunch of new shows…to the point where I can’t keep it all straight…holiday hiatus can’t come fast enough!

Yah, DENSITY maxes out at 255. More is the same as that.

But if you add the repeat loop and that line about “try again if that one’s lit” you’ll get much more light.

gotcha…and for my edumakation, what exactly do ‘density’ mean in this instance? 255, to me signifies that it’s based on a color value…or is it something else? (part of me would think it would relate to number of pixels in the strip, but as I’m learning, and having trouble with, things are different meanings in code-world)

“255” is the highest value that you can have in any one-byte (8-bit) variable, so it shows up all over the place.

In this case, when I wrote the code, I was coding on a smallish strip of maybe 30 pixels, and they seemed to be “on too much of the time” for me, subjectively. So instead of trying to re-light a new pixel each time through the loop, I put this around the re-light code:

if( random8() < DENSITY) {
… light a new pixel …
}

random8() returns a single byte, and 8-bit value between 0 and 255. By putting this random condition around the ‘light a new pixel’ code, it would only execute it some of the time, and how often was controlled by DENSITY. E.g., if DENSITY was 50, then a new light would be attempted only when the random number [0…255] was less than 50. That works out to 50/256ths of the time, which is 19.53125%; we’ll call it about 20%. So 20% of the time it would try to light a new pixel, and 80% of the time it would skip that: presto, lower ‘density’ of lights. So it’s actually a density- reduction system: it’s skipping light some of the time, not adding more light, if you see what I mean.

But you can also see how if you set DENSITY to anything 256 or higher, the “if” statement will just always be true:

if( random8() < DENSITY) {
… light a new pixel …
}

If DENSITY is 10000, that’ll always be greater than the one-byte random number returned by random8().

And this is why if you want to light more lights, you just have to execute that part of the code multiple times: try to light two lights each time, or three, or five – and you’ll actually add more light.

ahhh…English! I love it! many thinks…now off to the tinker bench!