mirror of
https://github.com/wled/WLED.git
synced 2025-07-23 10:46:33 +00:00
Added Glitter and Candle effects
This commit is contained in:
parent
4ffeb05120
commit
6122a8371a
@ -533,11 +533,18 @@ uint16_t WS2812FX::mode_dissolve_random(void) {
|
|||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_sparkle(void) {
|
uint16_t WS2812FX::mode_sparkle(void) {
|
||||||
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, 1));
|
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
|
||||||
}
|
}
|
||||||
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2;
|
||||||
|
uint32_t it = now / cycleTime;
|
||||||
|
if (it != SEGENV.step)
|
||||||
|
{
|
||||||
|
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
||||||
|
SEGENV.step = it;
|
||||||
|
}
|
||||||
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0));
|
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0));
|
||||||
return 10 + (uint16_t)(255 - SEGMENT.speed);
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -546,15 +553,10 @@ uint16_t WS2812FX::mode_sparkle(void) {
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_flash_sparkle(void) {
|
uint16_t WS2812FX::mode_flash_sparkle(void) {
|
||||||
if(SEGENV.call == 0) {
|
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i = SEGMENT.start + SEGENV.aux0;
|
|
||||||
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
|
||||||
|
|
||||||
if(random8(5) == 0) {
|
if(random8(5) == 0) {
|
||||||
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
||||||
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(1));
|
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(1));
|
||||||
@ -613,7 +615,6 @@ uint16_t WS2812FX::mode_multi_strobe(void) {
|
|||||||
uint16_t WS2812FX::mode_android(void) {
|
uint16_t WS2812FX::mode_android(void) {
|
||||||
if (SEGENV.call == 0)
|
if (SEGENV.call == 0)
|
||||||
{
|
{
|
||||||
SEGENV.aux0 = 0;
|
|
||||||
SEGENV.step = SEGMENT.start;
|
SEGENV.step = SEGMENT.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,13 +1531,13 @@ uint16_t WS2812FX::mode_palette()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0));
|
bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0));
|
||||||
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
|
for (uint16_t i = 0; i < SEGLEN; i++)
|
||||||
{
|
{
|
||||||
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
||||||
|
|
||||||
if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end"
|
if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end"
|
||||||
|
|
||||||
setPixelColor(i, color_from_palette(colorIndex, false, true, 255));
|
setPixelColor(SEGMENT.start + i, color_from_palette(colorIndex, false, true, 255));
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
@ -2285,3 +2286,65 @@ uint16_t WS2812FX::mode_spots_fade()
|
|||||||
uint16_t tr = (t >> 1) + (t >> 2);
|
uint16_t tr = (t >> 1) + (t >> 2);
|
||||||
return spots_base(tr);
|
return spots_base(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6
|
||||||
|
uint16_t WS2812FX::mode_glitter()
|
||||||
|
{
|
||||||
|
mode_palette();
|
||||||
|
|
||||||
|
if (SEGMENT.intensity > random8())
|
||||||
|
{
|
||||||
|
setPixelColor(SEGMENT.start + random16(SEGLEN), ULTRAWHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_candle()
|
||||||
|
{
|
||||||
|
if (SEGENV.call == 0) {
|
||||||
|
SEGENV.aux0 = 128; SEGENV.aux1 = 132; SEGENV.step = 1;
|
||||||
|
}
|
||||||
|
bool newTarget = false;
|
||||||
|
|
||||||
|
uint8_t s = SEGENV.aux0, target = SEGENV.aux1, fadeStep = SEGENV.step;
|
||||||
|
|
||||||
|
if (target > s) { //fade up
|
||||||
|
s = qadd8(s, fadeStep);
|
||||||
|
if (s >= target) newTarget = true;
|
||||||
|
} else {
|
||||||
|
s = qsub8(s, fadeStep);
|
||||||
|
if (s <= target) newTarget = true;
|
||||||
|
}
|
||||||
|
SEGENV.aux0 = s;
|
||||||
|
|
||||||
|
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
|
setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTarget)
|
||||||
|
{
|
||||||
|
uint8_t valrange = SEGMENT.intensity;
|
||||||
|
uint8_t rndval = valrange >> 1;
|
||||||
|
target = random8(rndval) + random8(rndval);
|
||||||
|
if (target < (rndval >> 1)) target += random8(rndval >> 1);
|
||||||
|
uint8_t offset = (255 - valrange) >> 1;
|
||||||
|
target += offset;
|
||||||
|
|
||||||
|
uint8_t dif = (target > s) ? target - s : s - target;
|
||||||
|
uint16_t fadeSpeed = 50 + ((255-SEGMENT.speed) >> 1);
|
||||||
|
|
||||||
|
//how much to move closer to target per frame
|
||||||
|
fadeStep = dif;
|
||||||
|
uint8_t frames = 1;
|
||||||
|
if (fadeSpeed > FRAMETIME) fadeStep = dif / (fadeSpeed / FRAMETIME);
|
||||||
|
if (fadeStep == 0) fadeStep = 1;
|
||||||
|
|
||||||
|
SEGENV.step = fadeStep;
|
||||||
|
SEGENV.aux1 = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
15
wled00/FX.h
15
wled00/FX.h
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME 1000/WLED_FPS
|
#define FRAMETIME (1000/WLED_FPS)
|
||||||
|
|
||||||
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
@ -84,7 +84,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 87
|
#define MODE_COUNT 89
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -173,6 +173,8 @@
|
|||||||
#define FX_MODE_TRI_STATIC_PATTERN 84
|
#define FX_MODE_TRI_STATIC_PATTERN 84
|
||||||
#define FX_MODE_SPOTS 85
|
#define FX_MODE_SPOTS 85
|
||||||
#define FX_MODE_SPOTS_FADE 86
|
#define FX_MODE_SPOTS_FADE 86
|
||||||
|
#define FX_MODE_GLITTER 87
|
||||||
|
#define FX_MODE_CANDLE 88
|
||||||
|
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
@ -317,6 +319,8 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
||||||
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
||||||
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
||||||
|
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
|
||||||
|
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -497,7 +501,10 @@ class WS2812FX {
|
|||||||
mode_static_pattern(void),
|
mode_static_pattern(void),
|
||||||
mode_tri_static_pattern(void),
|
mode_tri_static_pattern(void),
|
||||||
mode_spots(void),
|
mode_spots(void),
|
||||||
mode_spots_fade(void);
|
mode_spots_fade(void),
|
||||||
|
mode_glitter(void),
|
||||||
|
mode_candle(void);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -570,7 +577,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
"Two Dots","Two Areas","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",
|
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||||
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
|
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
|
||||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade"
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
@ -711,7 +711,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
_segment_index_palette_last = _segment_index;
|
_segment_index_palette_last = _segment_index;
|
||||||
|
|
||||||
byte paletteIndex = SEGMENT.palette;
|
byte paletteIndex = SEGMENT.palette;
|
||||||
if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4;
|
if (SEGMENT.mode == FX_MODE_GLITTER && paletteIndex == 0) paletteIndex = 11;
|
||||||
|
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
|
||||||
|
|
||||||
switch (paletteIndex)
|
switch (paletteIndex)
|
||||||
{
|
{
|
||||||
@ -725,6 +726,7 @@ void WS2812FX::handle_palette(void)
|
|||||||
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
||||||
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
||||||
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
||||||
|
//case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break;
|
||||||
|
|
||||||
default: targetPalette = PartyColors_p; break;//palette, bpm
|
default: targetPalette = PartyColors_p; break;//palette, bpm
|
||||||
}
|
}
|
||||||
@ -763,7 +765,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
case 5: {//based on primary + secondary
|
case 5: {//based on primary + secondary
|
||||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;}
|
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||||
|
targetPalette = CRGBPalette16(ter,sec,prim); break;}
|
||||||
case 6: //Party colors
|
case 6: //Party colors
|
||||||
targetPalette = PartyColors_p; break;
|
targetPalette = PartyColors_p; break;
|
||||||
case 7: //Cloud colors
|
case 7: //Cloud colors
|
||||||
|
@ -941,8 +941,8 @@ function requestJson(command, verbose = true) {
|
|||||||
e1 = d.getElementById('fxlist');
|
e1 = d.getElementById('fxlist');
|
||||||
e2 = d.getElementById('selectPalette');
|
e2 = d.getElementById('selectPalette');
|
||||||
|
|
||||||
//url = command ? 'http://10.10.1.26/json/state':'http://10.10.1.26/json';
|
|
||||||
url = command ? '/json/state':'/json';
|
url = command ? '/json/state':'/json';
|
||||||
|
url = command ? 'http://10.10.1.26/json/state':'http://10.10.1.26/json';
|
||||||
type = command ? 'post':'get';
|
type = command ? 'post':'get';
|
||||||
if (command)
|
if (command)
|
||||||
{
|
{
|
||||||
@ -1096,7 +1096,7 @@ function makeSeg() {
|
|||||||
<div class="segin expanded">
|
<div class="segin expanded">
|
||||||
Start LED: <input class="starts" id="seg${lowestUnused}s" type="number" min="0" max="${ledCount-1}" value="${ns}" oninput="updateLen(this)"><br>
|
Start LED: <input class="starts" id="seg${lowestUnused}s" type="number" min="0" max="${ledCount-1}" value="${ns}" oninput="updateLen(this)"><br>
|
||||||
Stop LED: <input class="stops" id="seg${lowestUnused}e" type="number" min="0" max="${ledCount}" value="${ledCount}" oninput="updateLen(this)">
|
Stop LED: <input class="stops" id="seg${lowestUnused}e" type="number" min="0" max="${ledCount}" value="${ledCount}" oninput="updateLen(this)">
|
||||||
<span class="h">(${ledCount} LEDs)</span><br>
|
<span class="h">(${ledCount - ns} LEDs)</span><br>
|
||||||
<i class="icons slider-icon cnf" id="segc${lowestUnused}" onclick="setSeg(${lowestUnused}); resetUtil();"></i>
|
<i class="icons slider-icon cnf" id="segc${lowestUnused}" onclick="setSeg(${lowestUnused}); resetUtil();"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@ -1137,8 +1137,6 @@ function setRev(s){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setX(ind) {
|
function setX(ind) {
|
||||||
selectedFx = ind;
|
|
||||||
|
|
||||||
var obj = {"seg": {"fx": parseInt(ind)}};
|
var obj = {"seg": {"fx": parseInt(ind)}};
|
||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
|
|
||||||
|
|
||||||
//version code in format yymmddb (b = daily build)
|
//version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 1912051
|
#define VERSION 1912061
|
||||||
char versionString[] = "0.9.0-dev";
|
char versionString[] = "0.9.0-dev";
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ void initInterfaces() {
|
|||||||
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||||
|
|
||||||
initBlynk(blynkApiKey);
|
initBlynk(blynkApiKey);
|
||||||
Serial.println(e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT));
|
e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT);
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
initMqtt();
|
initMqtt();
|
||||||
interfacesInited = true;
|
interfacesInited = true;
|
||||||
@ -239,11 +239,25 @@ void initInterfaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte stacO = 0;
|
byte stacO = 0;
|
||||||
|
uint32_t lastHeap;
|
||||||
|
unsigned long heapTime = 0;
|
||||||
|
|
||||||
void handleConnection() {
|
void handleConnection() {
|
||||||
//TODO: reconnect if heap <8000
|
|
||||||
if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return;
|
if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return;
|
||||||
if (lastReconnectAttempt == 0) initConnection();
|
if (lastReconnectAttempt == 0) initConnection();
|
||||||
|
|
||||||
|
//reconnect WiFi to clear stale allocations if heap gets too low
|
||||||
|
if (millis() - heapTime > 5000)
|
||||||
|
{
|
||||||
|
uint32_t heap = ESP.getFreeHeap();
|
||||||
|
if (heap < 9000 && lastHeap < 9000) {
|
||||||
|
DEBUG_PRINT("Heap too low! ");
|
||||||
|
DEBUG_PRINTLN(heap);
|
||||||
|
forceReconnect = true;
|
||||||
|
}
|
||||||
|
lastHeap = heap;
|
||||||
|
heapTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
byte stac = 0;
|
byte stac = 0;
|
||||||
if (apActive) {
|
if (apActive) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user