Added spots and two dots effects

This commit is contained in:
cschwinne 2019-12-04 12:15:12 +01:00
parent 3b70488828
commit 173c752d62
6 changed files with 118 additions and 234 deletions

1
.gitignore vendored
View File

@ -2,7 +2,6 @@
.pioenvs
.piolibdeps
.vscode
platformio.ini
!.vscode/extensions.json
/wled00/Release
/wled00/extLibs

View File

@ -262,7 +262,7 @@ uint16_t WS2812FX::mode_dynamic(void) {
*/
uint16_t WS2812FX::mode_breath(void) {
uint16_t var = 0;
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)) & 0xFFFF;
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10));
counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048
if (counter < 16384) {
if (counter > 8192) counter = 8192 - (counter - 8192);
@ -282,9 +282,8 @@ uint16_t WS2812FX::mode_breath(void) {
* Fades the LEDs between two colors
*/
uint16_t WS2812FX::mode_fade(void) {
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)) & 0xFFFF;
if (counter > 32767) counter = 32768 - (counter - 32768);
uint8_t lum = counter >> 7;
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10));
uint8_t lum = triwave16(counter) >> 8;
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum));
@ -1100,182 +1099,56 @@ uint16_t WS2812FX::mode_loading(void) {
}
/*
* Lights all LEDs after each other up starting from the outer edges and
* finishing in the middle. Then turns them in reverse order off. Repeat.
*/
uint16_t WS2812FX::mode_dual_color_wipe_in_out(void) {
int end = SEGLEN - SEGENV.step - 1;
bool odd = (SEGLEN % 2) == 1;
int mid = odd ? ((SEGLEN / 2) + 1) : (SEGLEN / 2);
if (SEGENV.step < mid) {
byte pindex = map(SEGENV.step, 0, mid -1, 0, 255);
uint32_t col = color_from_palette(pindex, false, false, 0);
setPixelColor(SEGMENT.start + SEGENV.step, col);
setPixelColor(SEGMENT.start + end, col);
} else {
if (odd) {
// If odd, we need to 'double count' the center LED (once to turn it on,
// once to turn it off). So trail one behind after the middle LED.
setPixelColor(SEGMENT.start + SEGENV.step - 1, SEGCOLOR(1));
setPixelColor(SEGMENT.start + end + 1, SEGCOLOR(1));
} else {
setPixelColor(SEGMENT.start + SEGENV.step, SEGCOLOR(1));
setPixelColor(SEGMENT.start + end, SEGCOLOR(1));
}
}
SEGENV.step++;
if (odd) {
if (SEGENV.step > SEGLEN) {
SEGENV.step = 0;
}
} else {
if (SEGENV.step >= SEGLEN) {
SEGENV.step = 0;
}
}
return SPEED_FORMULA_L;
//American Police Light with all LEDs Red and Blue
uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2)
{
uint16_t counter = now * ((SEGMENT.speed >> 3) +1);
uint16_t idexR = (counter * SEGLEN) >> 16;
if (idexR >= SEGLEN) idexR = 0;
uint16_t topindex = SEGLEN >> 1;
uint16_t idexB = idexR + topindex;
if (idexR > topindex) idexB -= SEGLEN;
if (idexB >= SEGLEN) idexB = 0; //otherwise overflow on odd number of LEDs
setPixelColor(SEGMENT.start + idexR, color1);
setPixelColor(SEGMENT.start + idexB, color2);
return FRAMETIME;
}
/*
* Lights all LEDs after each other up starting from the outer edges and
* finishing in the middle. Then turns them in that order off. Repeat.
*/
uint16_t WS2812FX::mode_dual_color_wipe_in_in(void) {
bool odd = (SEGLEN % 2) == 1;
int mid = SEGLEN / 2;
byte pindex = 0;
uint32_t col = 0;
if (SEGENV.step <= mid)
{
pindex = map(SEGENV.step, 0, mid, 0, 255);
col = color_from_palette(pindex, false, false, 0);
}
if (odd) {
if (SEGENV.step <= mid) {
setPixelColor(SEGMENT.start + SEGENV.step, col);
setPixelColor(SEGMENT.start + SEGLEN - SEGENV.step - 1, col);
} else {
int i = SEGENV.step - mid;
setPixelColor(SEGMENT.start + i - 1, SEGCOLOR(1));
setPixelColor(SEGMENT.start + SEGLEN - i, SEGCOLOR(1));
}
} else {
if (SEGENV.step < mid) {
setPixelColor(SEGMENT.start + SEGENV.step, col);
setPixelColor(SEGMENT.start + SEGLEN - SEGENV.step - 1, col);
} else {
int i = SEGENV.step - mid;
setPixelColor(SEGMENT.start + i, SEGCOLOR(1));
setPixelColor(SEGMENT.start + SEGLEN - i - 1, SEGCOLOR(1));
}
}
SEGENV.step++;
if (odd) {
if (SEGENV.step > SEGLEN) {
SEGENV.step = 0;
}
} else {
if (SEGENV.step >= SEGLEN) {
SEGENV.step = 0;
}
}
return SPEED_FORMULA_L;
//American Police Light with all LEDs Red and Blue
uint16_t WS2812FX::mode_police_all()
{
return police_base(RED, BLUE);
}
/*
* Lights all LEDs after each other up starting from the middle and
* finishing at the edges. Then turns them off in that order. Repeat.
*/
uint16_t WS2812FX::mode_dual_color_wipe_out_out(void) {
int end = SEGLEN - SEGENV.step - 1;
bool odd = (SEGLEN % 2) == 1;
int mid = SEGLEN / 2;
byte pindex = 0;
uint32_t col = 0;
if (SEGENV.step <= mid)
{
pindex = map(SEGENV.step, 0, mid, 255, 0);
col = color_from_palette(pindex, false, false, 0);
}
if (odd) {
if (SEGENV.step <= mid) {
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
setPixelColor(SEGMENT.start + mid - SEGENV.step, col);
} else {
setPixelColor(SEGMENT.start + SEGENV.step - 1, SEGCOLOR(1));
setPixelColor(SEGMENT.start + end + 1, SEGCOLOR(1));
}
} else {
if (SEGENV.step < mid) {
setPixelColor(SEGMENT.start + mid - SEGENV.step - 1, col);
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
} else {
setPixelColor(SEGMENT.start + SEGENV.step, SEGCOLOR(1));
setPixelColor(SEGMENT.start + end, SEGCOLOR(1));
}
}
SEGENV.step++;
if (odd) {
if (SEGENV.step > SEGLEN) {
SEGENV.step = 0;
}
} else {
if (SEGENV.step >= SEGLEN) {
SEGENV.step = 0;
}
}
return SPEED_FORMULA_L;
}
//Police Lights Red and Blue
uint16_t WS2812FX::mode_police()
{
fill(SEGCOLOR(1));
return police_base(RED, BLUE);
}
/*
* Lights all LEDs after each other up starting from the middle and
* finishing at the edges. Then turns them off in reverse order. Repeat.
*/
uint16_t WS2812FX::mode_dual_color_wipe_out_in(void) {
bool odd = (SEGLEN % 2) == 1;
int mid = SEGLEN / 2;
byte pindex = 0;
uint32_t col = 0;
if (SEGENV.step <= mid)
{
pindex = map(SEGENV.step, 0, mid, 255, 0);
col = color_from_palette(pindex, false, false, 0);
}
if (odd) {
if (SEGENV.step <= mid) {
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
setPixelColor(SEGMENT.start + mid - SEGENV.step, col);
} else {
int i = SEGENV.step - mid;
setPixelColor(SEGMENT.start + i - 1, SEGCOLOR(1));
setPixelColor(SEGMENT.start + SEGLEN - i, SEGCOLOR(1));
}
} else {
if (SEGENV.step < mid) {
setPixelColor(SEGMENT.start + mid - SEGENV.step - 1, col);
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
} else {
int i = SEGENV.step - mid;
setPixelColor(SEGMENT.start + i, SEGCOLOR(1));
setPixelColor(SEGMENT.start + SEGLEN - i - 1, SEGCOLOR(1));
}
}
SEGENV.step++;
if (odd) {
if (SEGENV.step > SEGLEN) {
SEGENV.step = 0;
}
} else {
if (SEGENV.step >= SEGLEN) {
SEGENV.step = 0;
}
}
return SPEED_FORMULA_L;
//Police All with custom colors
uint16_t WS2812FX::mode_two_areas()
{
return police_base(SEGCOLOR(0), SEGCOLOR(1));
}
//Police Lights with custom colors
uint16_t WS2812FX::mode_two_dots()
{
fill(SEGCOLOR(2));
uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1);
return police_base(SEGCOLOR(0), color2);
}
@ -2197,7 +2070,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
// "CalculateOneTwinkle" on each pixel. It then displays
// either the twinkle color of the background color,
// whichever is brighter.
void WS2812FX::twinklefox_base(bool cat)
uint16_t WS2812FX::twinklefox_base(bool cat)
{
// "PRNG16" is the pseudorandom number generator
// It MUST be reset to the same starting value each time
@ -2253,18 +2126,17 @@ void WS2812FX::twinklefox_base(bool cat)
setPixelColor(i, bg.r, bg.g, bg.b);
}
}
return FRAMETIME;
}
uint16_t WS2812FX::mode_twinklefox()
{
twinklefox_base(false);
return FRAMETIME;
return twinklefox_base(false);
}
uint16_t WS2812FX::mode_twinklecat()
{
twinklefox_base(true);
return FRAMETIME;
return twinklefox_base(true);
}
@ -2370,41 +2242,46 @@ uint16_t WS2812FX::mode_tri_static_pattern()
return FRAMETIME;
}
//American Police Light with all LEDs Red and Blue
uint16_t WS2812FX::mode_policeall()
{
SEGENV.step++;
if (SEGENV.step >= SEGLEN) {
SEGENV.step = 0;
}
uint16_t idexR = SEGENV.step;
uint16_t topindex = SEGLEN >> 1;
uint16_t idexB = idexR + topindex;
if (idexR >= topindex) idexB -= SEGLEN;
setPixelColor(idexR, RED);
setPixelColor(idexB, BLUE);
return SPEED_FORMULA_L;
}
//Police Lights Red and Blue
uint16_t WS2812FX::mode_police()
uint16_t WS2812FX::spots_base(uint16_t threshold)
{
fill(SEGCOLOR(1));
uint16_t maxZones = SEGLEN >> 2;
uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8);
uint16_t zoneLen = SEGLEN / zones;
uint16_t offset = (SEGLEN - zones * zoneLen) >> 1;
return mode_policeall();
for (uint16_t z = 0; z < zones; z++)
{
uint16_t pos = offset + z * zoneLen;
for (uint16_t i = 0; i < zoneLen; i++)
{
uint16_t wave = triwave16((i * 0xFFFF) / zoneLen);
if (wave > threshold) {
uint16_t index = SEGMENT.start + pos + i;
uint8_t s = (wave - threshold)*255 / (0xFFFF - threshold);
setPixelColor(index, color_blend(color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s));
}
}
}
return FRAMETIME;
}
//Speed slider sets number of "lights", intensity sets LEDs per light
/*uint16_t WS2812FX::mode_static_pattern2()
//Intensity slider sets number of "lights", speed sets LEDs per light
uint16_t WS2812FX::mode_spots()
{
uint16_t maxlights = SEGLEN >> 1;
uint16_t zones = 1 + (SEGMENT.speed);
return FRAMETIME;
}*/
return spots_base((255 - SEGMENT.speed) << 8);
}
//Intensity slider sets number of "lights", LEDs per light fade in and out
uint16_t WS2812FX::mode_spots_fade()
{
uint16_t counter = now * ((SEGMENT.speed >> 2) +8);
uint16_t t = triwave16(counter);
uint16_t tr = (t >> 1) + (t >> 2);
return spots_base(tr);
}

View File

@ -134,10 +134,10 @@
#define FX_MODE_FIRE_FLICKER 45
#define FX_MODE_GRADIENT 46
#define FX_MODE_LOADING 47
#define FX_MODE_DUAL_COLOR_WIPE_IN_OUT 48
#define FX_MODE_DUAL_COLOR_WIPE_IN_IN 49
#define FX_MODE_DUAL_COLOR_WIPE_OUT_OUT 50
#define FX_MODE_DUAL_COLOR_WIPE_OUT_IN 51
#define FX_MODE_POLICE 48
#define FX_MODE_POLICE_ALL 49
#define FX_MODE_TWO_DOTS 50
#define FX_MODE_TWO_AREAS 51
#define FX_MODE_CIRCUS_COMBUSTUS 52
#define FX_MODE_HALLOWEEN 53
#define FX_MODE_TRICOLOR_CHASE 54
@ -149,7 +149,6 @@
#define FX_MODE_DUAL_LARSON_SCANNER 60
#define FX_MODE_RANDOM_CHASE 61
#define FX_MODE_OSCILLATE 62
//Modes that use FastLED -->
#define FX_MODE_PRIDE_2015 63
#define FX_MODE_JUGGLE 64
#define FX_MODE_PALETTE 65
@ -172,8 +171,8 @@
#define FX_MODE_HALLOWEEN_EYES 82
#define FX_MODE_STATIC_PATTERN 83
#define FX_MODE_TRI_STATIC_PATTERN 84
#define FX_MODE_POLICE 85
#define FX_MODE_POLICE_ALL 86
#define FX_MODE_SPOTS 85
#define FX_MODE_SPOTS_FADE 86
class WS2812FX {
@ -277,10 +276,10 @@ class WS2812FX {
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_OUT] = &WS2812FX::mode_dual_color_wipe_in_out;
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_IN] = &WS2812FX::mode_dual_color_wipe_in_in;
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_OUT] = &WS2812FX::mode_dual_color_wipe_out_out;
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_IN] = &WS2812FX::mode_dual_color_wipe_out_in;
_mode[FX_MODE_POLICE] = &WS2812FX::mode_police;
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
@ -316,8 +315,8 @@ class WS2812FX {
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern;
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
_mode[FX_MODE_POLICE] = &WS2812FX::mode_police;
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_policeall;
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
_brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black);
@ -387,6 +386,7 @@ class WS2812FX {
uint16_t
ablMilliampsMax,
currentMilliamps,
triwave16(uint16_t),
getUsableCount();
uint32_t
@ -459,10 +459,10 @@ class WS2812FX {
mode_fire_flicker(void),
mode_gradient(void),
mode_loading(void),
mode_dual_color_wipe_in_out(void),
mode_dual_color_wipe_in_in(void),
mode_dual_color_wipe_out_out(void),
mode_dual_color_wipe_out_in(void),
mode_police(void),
mode_police_all(void),
mode_two_dots(void),
mode_two_areas(void),
mode_circus_combustus(void),
mode_bicolor_chase(void),
mode_tricolor_chase(void),
@ -496,8 +496,8 @@ class WS2812FX {
mode_halloween_eyes(void),
mode_static_pattern(void),
mode_tri_static_pattern(void),
mode_police(void),
mode_policeall(void);
mode_spots(void),
mode_spots_fade(void);
private:
NeoPixelWrapper *bus;
@ -515,7 +515,6 @@ class WS2812FX {
void handle_palette(void);
void fill(uint32_t);
bool modeUsesLock(uint8_t);
void twinklefox_base(bool);
bool
_modeUsesLock,
@ -540,8 +539,11 @@ class WS2812FX {
dissolve(uint32_t),
chase(uint32_t, uint32_t, uint32_t, bool),
gradient_base(bool),
police_base(uint32_t, uint32_t),
running(uint32_t, uint32_t),
tricolor_chase(uint32_t, uint32_t);
tricolor_chase(uint32_t, uint32_t),
twinklefox_base(bool),
spots_base(uint16_t);
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
@ -564,11 +566,11 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"Scan","Dual Scan","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
"Sparkle","Dark Sparkle","Sparkle+","Strobe","Strobe Rainbow","Mega Strobe","Blink Rainbow","Android","Chase","Chase Random",
"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",
"Out Out","Out In","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
"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",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Tri Color Pattern", "Police","Police All"
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade"
])=====";

View File

@ -645,6 +645,12 @@ void WS2812FX::blur(uint8_t blur_amount)
}
}
uint16_t WS2812FX::triwave16(uint16_t in)
{
if (in < 0x8000) return in *2;
return 0xFFFF - (in - 0x8000)*2;
}
/*
* Put a value 0 to 255 in to get a color value.
* The colours are a transition r -> g -> b -> back to r

View File

@ -97,7 +97,7 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1912033
#define VERSION 1912042
char versionString[] = "0.8.7-dev";

View File

@ -169,7 +169,6 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
root["pal"] = seg.palette;
root["sel"] = seg.isSelected();
root["rev"] = seg.getOption(1);
root["cln"] = -1;
}
@ -217,6 +216,7 @@ void serializeInfo(JsonObject root)
JsonObject leds = root.createNestedObject("leds");
leds["count"] = ledCount;
leds["rgbw"] = useRGBW;
leds["wv"] = useRGBW && !autoRGBtoRGBW; //should a white channel slider be displayed?
JsonArray leds_pin = leds.createNestedArray("pin");
leds_pin.add(LEDPIN);