Added Halloween Eyes effect
Added Twinklecat
This commit is contained in:
parent
4390aee1e0
commit
4b4b93ac04
@ -45,21 +45,35 @@ uint16_t WS2812FX::mode_static(void) {
|
|||||||
* if(strobe == true) then create a strobe effect
|
* if(strobe == true) then create a strobe effect
|
||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) {
|
uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) {
|
||||||
uint32_t color = ((SEGENV.call & 1) == 0) ? color1 : color2;
|
uint16_t stateTime = SEGENV.aux1;
|
||||||
|
uint32_t cycleTime = (255 - SEGMENT.speed)*20;
|
||||||
|
uint32_t onTime = 0;
|
||||||
|
uint32_t offTime = cycleTime;
|
||||||
|
|
||||||
|
if (!strobe) {
|
||||||
|
onTime = (cycleTime * SEGMENT.intensity) >> 8;
|
||||||
|
offTime = cycleTime - onTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
stateTime = ((SEGENV.aux0 & 1) == 0) ? onTime : offTime;
|
||||||
|
stateTime += 20;
|
||||||
|
|
||||||
|
if (now - SEGENV.step > stateTime)
|
||||||
|
{
|
||||||
|
SEGENV.aux0++;
|
||||||
|
SEGENV.aux1 = stateTime;
|
||||||
|
SEGENV.step = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t color = ((SEGENV.aux0 & 1) == 0) ? color1 : color2;
|
||||||
if (color == color1 && do_palette)
|
if (color == color1 && do_palette)
|
||||||
{
|
{
|
||||||
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else fill(color);
|
||||||
fill(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((SEGENV.call & 1) == 0) {
|
return 20;
|
||||||
return strobe ? 20 : (100 + ((1986 * (uint32_t)(255 - SEGMENT.speed)) / 255))*(float)(SEGMENT.intensity/128.0);
|
|
||||||
} else {
|
|
||||||
return strobe ? 50 + ((1986 * (uint32_t)(255 - SEGMENT.speed)) / 255) : (100 + ((1986 * (uint32_t)(255 - SEGMENT.speed)) / 255))*(float)(2.0-(SEGMENT.intensity/128.0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2044,7 +2058,7 @@ uint16_t WS2812FX::mode_ripple()
|
|||||||
uint16_t origin = SEGMENT.start + random16(SEGLEN);
|
uint16_t origin = SEGMENT.start + random16(SEGLEN);
|
||||||
_locked[storeI+1] = origin >> 8;
|
_locked[storeI+1] = origin >> 8;
|
||||||
_locked[storeI+2] = origin & 0xFF;
|
_locked[storeI+2] = origin & 0xFF;
|
||||||
_locked[storeI+3] = random8();
|
_locked[storeI+3] = random8(); //color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2062,7 +2076,7 @@ uint16_t WS2812FX::mode_ripple()
|
|||||||
// incandescent bulbs change color as they get dim down.
|
// incandescent bulbs change color as they get dim down.
|
||||||
#define COOL_LIKE_INCANDESCENT 1
|
#define COOL_LIKE_INCANDESCENT 1
|
||||||
|
|
||||||
CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt)
|
CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
|
||||||
{
|
{
|
||||||
// Overall twinkle speed (changed)
|
// Overall twinkle speed (changed)
|
||||||
uint16_t ticks = ms / (32 - (SEGMENT.speed >> 3));
|
uint16_t ticks = ms / (32 - (SEGMENT.speed >> 3));
|
||||||
@ -2083,6 +2097,10 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt)
|
|||||||
// This is like 'triwave8', which produces a
|
// This is like 'triwave8', which produces a
|
||||||
// symmetrical up-and-down triangle sawtooth waveform, except that this
|
// symmetrical up-and-down triangle sawtooth waveform, except that this
|
||||||
// function produces a triangle wave with a faster attack and a slower decay
|
// function produces a triangle wave with a faster attack and a slower decay
|
||||||
|
if (cat) //twinklecat, variant where the leds instantly turn on
|
||||||
|
{
|
||||||
|
bright = 255 - ph;
|
||||||
|
} else { //vanilla twinklefox
|
||||||
if (ph < 86) {
|
if (ph < 86) {
|
||||||
bright = ph * 3;
|
bright = ph * 3;
|
||||||
} else {
|
} else {
|
||||||
@ -2090,6 +2108,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt)
|
|||||||
bright = 255 - (ph + (ph/2));
|
bright = 255 - (ph + (ph/2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t hue = slowcycle8 - salt;
|
uint8_t hue = slowcycle8 - salt;
|
||||||
CRGB c;
|
CRGB c;
|
||||||
@ -2117,7 +2136,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt)
|
|||||||
// "CalculateOneTwinkle" on each pixel. It then displays
|
// "CalculateOneTwinkle" on each pixel. It then displays
|
||||||
// either the twinkle color of the background color,
|
// either the twinkle color of the background color,
|
||||||
// whichever is brighter.
|
// whichever is brighter.
|
||||||
uint16_t WS2812FX::mode_twinklefox()
|
void WS2812FX::twinklefox_base(bool cat)
|
||||||
{
|
{
|
||||||
// "PRNG16" is the pseudorandom number generator
|
// "PRNG16" is the pseudorandom number generator
|
||||||
// It MUST be reset to the same starting value each time
|
// It MUST be reset to the same starting value each time
|
||||||
@ -2125,8 +2144,6 @@ uint16_t WS2812FX::mode_twinklefox()
|
|||||||
// numbers that it generates is (paradoxically) stable.
|
// numbers that it generates is (paradoxically) stable.
|
||||||
uint16_t PRNG16 = 11337;
|
uint16_t PRNG16 = 11337;
|
||||||
|
|
||||||
uint32_t clock32 = millis();
|
|
||||||
|
|
||||||
// Set up the background color, "bg".
|
// Set up the background color, "bg".
|
||||||
// if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
|
// if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
|
||||||
// the current palette are identical, then a deeply faded version of
|
// the current palette are identical, then a deeply faded version of
|
||||||
@ -2151,13 +2168,13 @@ uint16_t WS2812FX::mode_twinklefox()
|
|||||||
PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
|
PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number
|
||||||
// use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
|
// use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths)
|
||||||
uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
|
uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF)>>4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08;
|
||||||
uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
|
uint32_t myclock30 = (uint32_t)((now * myspeedmultiplierQ5_3) >> 3) + myclockoffset16;
|
||||||
uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
|
uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel
|
||||||
|
|
||||||
// We now have the adjusted 'clock' for this pixel, now we call
|
// We now have the adjusted 'clock' for this pixel, now we call
|
||||||
// the function that computes what color the pixel should be based
|
// the function that computes what color the pixel should be based
|
||||||
// on the "brightness = f( time )" idea.
|
// on the "brightness = f( time )" idea.
|
||||||
CRGB c = twinklefox_one_twinkle(myclock30, myunique8);
|
CRGB c = twinklefox_one_twinkle(myclock30, myunique8, cat);
|
||||||
|
|
||||||
uint8_t cbright = c.getAverageLight();
|
uint8_t cbright = c.getAverageLight();
|
||||||
int16_t deltabright = cbright - backgroundBrightness;
|
int16_t deltabright = cbright - backgroundBrightness;
|
||||||
@ -2175,5 +2192,74 @@ uint16_t WS2812FX::mode_twinklefox()
|
|||||||
setPixelColor(i, bg);
|
setPixelColor(i, bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_twinklefox()
|
||||||
|
{
|
||||||
|
twinklefox_base(false);
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_twinklecat()
|
||||||
|
{
|
||||||
|
twinklefox_base(true);
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//inspired by https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectBlinkingHalloweenEyes
|
||||||
|
#define HALLOWEEN_EYE_SPACE 3
|
||||||
|
#define HALLOWEEN_EYE_WIDTH 1
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_halloween_eyes()
|
||||||
|
{
|
||||||
|
uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE;
|
||||||
|
if (eyeLength > SEGLEN) return mode_static(); //bail if segment too short
|
||||||
|
|
||||||
|
fill(SEGCOLOR(1)); //fill background
|
||||||
|
|
||||||
|
uint8_t state = SEGENV.aux1 >> 8;
|
||||||
|
uint16_t stateTime = SEGENV.call;
|
||||||
|
if (stateTime == 0) stateTime = 2000;
|
||||||
|
|
||||||
|
if (state == 0) { //spawn eyes
|
||||||
|
SEGENV.aux0 = random(SEGMENT.start, SEGMENT.stop - eyeLength); //start pos
|
||||||
|
SEGENV.aux1 = random8(); //color
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state < 2) { //fade eyes
|
||||||
|
uint16_t startPos = SEGENV.aux0;
|
||||||
|
uint16_t start2ndEye = startPos + HALLOWEEN_EYE_WIDTH + HALLOWEEN_EYE_SPACE;
|
||||||
|
|
||||||
|
uint32_t fadestage = (now - SEGENV.step)*255 / stateTime;
|
||||||
|
if (fadestage > 255) fadestage = 255;
|
||||||
|
uint32_t c = color_blend(color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage);
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < HALLOWEEN_EYE_WIDTH; i++)
|
||||||
|
{
|
||||||
|
setPixelColor(startPos + i, c);
|
||||||
|
setPixelColor(start2ndEye + i, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - SEGENV.step > stateTime)
|
||||||
|
{
|
||||||
|
state++;
|
||||||
|
if (state > 2) state = 0;
|
||||||
|
|
||||||
|
if (state < 2)
|
||||||
|
{
|
||||||
|
stateTime = 100 + (255 - SEGMENT.intensity)*10; //eye fade time
|
||||||
|
} else {
|
||||||
|
uint16_t eyeOffTimeBase = (255 - SEGMENT.speed)*10;
|
||||||
|
stateTime = eyeOffTimeBase + random(eyeOffTimeBase);
|
||||||
|
}
|
||||||
|
SEGENV.step = now;
|
||||||
|
SEGENV.call = stateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEGENV.aux1 = (SEGENV.aux1 & 0xFF) + (state << 8); //save state
|
||||||
|
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 81
|
#define MODE_COUNT 83
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -163,6 +163,8 @@
|
|||||||
#define FX_MODE_RAILWAY 78
|
#define FX_MODE_RAILWAY 78
|
||||||
#define FX_MODE_RIPPLE 79
|
#define FX_MODE_RIPPLE 79
|
||||||
#define FX_MODE_TWINKLEFOX 80
|
#define FX_MODE_TWINKLEFOX 80
|
||||||
|
#define FX_MODE_TWINKLECAT 81
|
||||||
|
#define FX_MODE_HALLOWEEN_EYES 82
|
||||||
|
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
@ -299,6 +301,8 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
|
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
|
||||||
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
|
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
|
||||||
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
||||||
|
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
||||||
|
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -469,7 +473,9 @@ class WS2812FX {
|
|||||||
mode_meteor_smooth(void),
|
mode_meteor_smooth(void),
|
||||||
mode_railway(void),
|
mode_railway(void),
|
||||||
mode_ripple(void),
|
mode_ripple(void),
|
||||||
mode_twinklefox(void);
|
mode_twinklefox(void),
|
||||||
|
mode_twinklecat(void),
|
||||||
|
mode_halloween_eyes(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -479,6 +485,7 @@ class WS2812FX {
|
|||||||
CRGBPalette16 currentPalette;
|
CRGBPalette16 currentPalette;
|
||||||
CRGBPalette16 targetPalette;
|
CRGBPalette16 targetPalette;
|
||||||
|
|
||||||
|
uint32_t now;
|
||||||
uint16_t _length;
|
uint16_t _length;
|
||||||
uint16_t _rand16seed;
|
uint16_t _rand16seed;
|
||||||
uint8_t _brightness;
|
uint8_t _brightness;
|
||||||
@ -486,6 +493,7 @@ class WS2812FX {
|
|||||||
void handle_palette(void);
|
void handle_palette(void);
|
||||||
void fill(uint32_t);
|
void fill(uint32_t);
|
||||||
bool modeUsesLock(uint8_t);
|
bool modeUsesLock(uint8_t);
|
||||||
|
void twinklefox_base(bool);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_modeUsesLock,
|
_modeUsesLock,
|
||||||
@ -513,7 +521,7 @@ class WS2812FX {
|
|||||||
running(uint32_t, uint32_t),
|
running(uint32_t, uint32_t),
|
||||||
tricolor_chase(uint32_t, uint32_t);
|
tricolor_chase(uint32_t, uint32_t);
|
||||||
|
|
||||||
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt);
|
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||||
|
|
||||||
uint32_t _lastPaletteChange = 0;
|
uint32_t _lastPaletteChange = 0;
|
||||||
uint32_t _lastShow = 0;
|
uint32_t _lastShow = 0;
|
||||||
@ -536,8 +544,9 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
||||||
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","In Out","In In",
|
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","In Out","In In",
|
||||||
"Out Out","Out In","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
"Out Out","Out In","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||||
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","BPM","Fill Noise","Noise 1",
|
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","BPM","Fill Noise",
|
||||||
"Noise 2","Noise 3","Noise 4","Colortwinkle","Lake","Meteor","Smooth Meteor","Railway","Ripple","Twinklefox"
|
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
|
||||||
|
"Twinklefox","Twinklecat","Halloween Eyes"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::service() {
|
void WS2812FX::service() {
|
||||||
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
|
now = millis(); // Be aware, millis() rolls over every 49 days
|
||||||
if (now - _lastShow < MIN_SHOW_DELAY) return;
|
if (now - _lastShow < MIN_SHOW_DELAY) return;
|
||||||
bool doShow = false;
|
bool doShow = false;
|
||||||
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
@ -69,7 +69,7 @@ void WS2812FX::service() {
|
|||||||
handle_palette();
|
handle_palette();
|
||||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||||
SEGENV.next_time = now + delay;
|
SEGENV.next_time = now + delay;
|
||||||
SEGENV.call++;
|
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
|
|
||||||
|
|
||||||
//version code in format yymmddb (b = daily build)
|
//version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 1909194
|
#define VERSION 1910012
|
||||||
char versionString[] = "0.8.5";
|
char versionString[] = "0.8.5";
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user