What started out as an just excuse to tinker with the ESP32 turned into

What started out as an just excuse to tinker with the ESP32 turned into a more extensive project. Since the ESP32 support wasn’t great before I had been using custom code on the RMT channel to drive the LEDs, but now have moved back to FastLED which makes my life a lot simpler! This video was made before the port to FastLED, so it lacks fades and a few effects I’ve added since. Most of these came from Tweaking4All, some are original.

I’m now making the web UI and REST API for interfacing with the box.
https://www.youtube.com/watch?v=3gwKMuuCgJI

The bouncing balls are always fun! I like your spin on them. Flame is great looking too.

Thanks! Since going back to FastLED I’ve added palette based effects like puffy clouds, rainbow stripe animations, and so on. The fire is still my favorite. Wish I knew who wrote the original, it’s clever.

any chance you want to share your code? those are some awesome effects! I am finishing up a holiday light show I put on the outside of my house, and I would love to add some of your effects to it.

It’ll take me some time to package the whole controller up but I’m happy to share some of the effect code. Any few in particular?

I really liked the fire effect, the bouncing balls are cool too!

The bouncing balls are pretty self contained, so here’s an example. It relies on a base class you won’t have to set pixels and so on but it should be easy to reuse.

//+------------------------------------------------------------------------
//
// ESP32LEDStrip - (c) 2018 Dave Plummer. All Rights Reserved. See license.txt.
//
// File: BouncingBallsEffect.h
//
// Description:
//
// Displays N bouncing colored balls, optiponally from both sides.
//
// Origin: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects
// No license årequirements listed
//
// History: Aug-1-2018 Davepl Adapted
//
//-------------------------------------------------------------------------

#pragma once

#if !defined(max)
#define max(a,b) (a > b ? a : b)
#endif

class BouncingBallsEffect : public LEDStripEffect
{
protected:

virtual const char * FriendlyName() const
{
	return "Bouncing Balls";
}

void BouncingColoredBalls(int BallCount, bool bStaggered) 
{
	float Gravity = -9.81;
	int StartHeight = 1;

	float Height[BallCount];
	float ImpactVelocityStart = sqrt(-2 * Gravity * StartHeight);
	float ImpactVelocity[BallCount];
	float TimeSinceLastBounce[BallCount];
	int   Position[BallCount];
	long  ClockTimeSinceLastBounce[BallCount];
	float Dampening[BallCount];
	CRGB  Color[BallCount];

	for (int i = 0; i < BallCount; i++) 
	{
		ClockTimeSinceLastBounce[i] = millis();
		Height[i] = StartHeight;
		Position[i] = 0;
		ImpactVelocity[i] = ImpactVelocityStart;
		TimeSinceLastBounce[i] = 0;
		Dampening[i] = 0.90 - float(i) / pow(BallCount, 2);  

		// The first up to N balls have their initial colors set, the rest are random.  When they
		// get kicked for lack of velocity, their color will be randomized as well either way.

		if (i == 0)
			Color[i] = CRGB::Red;
		else if (i == 1)
			Color[i] = CRGB::Green;
		else if (i == 2)
			Color[i] = CRGB::Blue;
		else if (i == 3)
			Color[i] = CRGB::Violet;
		else
			Color[i] = RandomRainbowColor();
	}

	while (true) 
	{
		for (int i = 0; i < BallCount; i++) 
		{
			TimeSinceLastBounce[i] = (millis() - ClockTimeSinceLastBounce[i]) / 6;
			Height[i] = 0.5 * Gravity * pow(TimeSinceLastBounce[i] / 1000, 2.0) + ImpactVelocity[i] * TimeSinceLastBounce[i] / 1000;

			if (Height[i] < 0) 
			{
				Height[i] = 0;
				ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
				ClockTimeSinceLastBounce[i] = millis();

				if (ImpactVelocity[i] < 0.01)			// Ball is almost motionless, so kick it hard
				{
					ImpactVelocity[i] = ImpactVelocityStart;
					Color[i] = RandomRainbowColor();
				}
			}
			Position[i] = round(Height[i] * (_cLEDs - 1) / StartHeight);
		}

		for (int i = 0; i < BallCount; i++) 
		{
			int x = (bStaggered && (i % 2 == 1)) ? Position[i] : (_cLEDs - Position[i]);

			setPixel(x,
				Color[i].r,
				Color[i].g,
				Color[i].b);
			/*
			setPixel(x + 1,
				max(128, Color[i].r),			// This works becaue it's a fully saturated color in one of r/g/b
				max(128, Color[i].g),
				max(128, Color[i].b));
			setPixel(x + 2,
				Color[i].r,
				Color[i].g,
				Color[i].b);
			*/
		}
		if (gStopEffect)
			return;
		delay(5);
		showStrip();
		setAll(0, 0, 0);
	}
}
virtual void Draw(float fSecondsElapsed, byte baseHue)
{
	BouncingColoredBalls(3, false);
}

};

class DoubleBouncingBallsEffect : public BouncingBallsEffect
{
virtual const char * FriendlyName() const
{
return “Double Balls”;
}

virtual void Draw(float fSecondsElapsed, byte baseHue)
{
	BouncingColoredBalls(6, true);
}

};

@Dave_Plummer Please post code to http://gist.github.com and share a link to it here so G+ doesn’t accidently mangle it, it can be viewed correctly on all devices, and line numbers can be referenced for discussion.
http://gist.github.com