Adding ability to turn off specified number of LEDs. Added to LED settings.

Also added FX for Tri Color Static, defaults tri to white.
This commit is contained in:
emerrill 2019-11-29 10:53:01 -07:00
parent 896bdaf124
commit 0b5ac7a139
11 changed files with 86 additions and 20 deletions

1
.gitignore vendored
View File

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

View File

@ -2346,6 +2346,29 @@ uint16_t WS2812FX::mode_static_pattern()
return FRAMETIME; return FRAMETIME;
} }
uint16_t WS2812FX::mode_tri_static_pattern()
{
uint8_t segSize = (SEGMENT.intensity >> 5) +1;
uint8_t currSeg = 0;
uint16_t currSegCount = 0;
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
if ( currSeg % 3 == 0 ) {
setPixelColor(i, SEGCOLOR(0));
} else if( currSeg % 3 == 1) {
setPixelColor(i, SEGCOLOR(1));
} else {
setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE));
}
currSegCount += 1;
if (currSegCount >= segSize) {
currSeg +=1;
currSegCount = 0;
}
}
return FRAMETIME;
}
//American Police Light with all LEDs Red and Blue //American Police Light with all LEDs Red and Blue
uint16_t WS2812FX::mode_policeall() uint16_t WS2812FX::mode_policeall()

View File

@ -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 86 #define MODE_COUNT 87
#define FX_MODE_STATIC 0 #define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1 #define FX_MODE_BLINK 1
@ -171,8 +171,9 @@
#define FX_MODE_TWINKLECAT 81 #define FX_MODE_TWINKLECAT 81
#define FX_MODE_HALLOWEEN_EYES 82 #define FX_MODE_HALLOWEEN_EYES 82
#define FX_MODE_STATIC_PATTERN 83 #define FX_MODE_STATIC_PATTERN 83
#define FX_MODE_POLICE 84 #define FX_MODE_TRI_STATIC_PATTERN 84
#define FX_MODE_POLICE_ALL 85 #define FX_MODE_POLICE 85
#define FX_MODE_POLICE_ALL 86
class WS2812FX { class WS2812FX {
@ -312,6 +313,7 @@ class WS2812FX {
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat; _mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes; _mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern; _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] = &WS2812FX::mode_police;
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_policeall; _mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_policeall;
@ -328,7 +330,7 @@ class WS2812FX {
} }
void void
init(bool supportWhite, uint16_t countPixels, bool skipFirs), init(bool supportWhite, uint16_t countPixels, bool skipFirs, uint8_t disableNLeds),
service(void), service(void),
blur(uint8_t), blur(uint8_t),
fade_out(uint8_t r), fade_out(uint8_t r),
@ -370,6 +372,7 @@ class WS2812FX {
paletteBlend = 0, paletteBlend = 0,
colorOrder = 0, colorOrder = 0,
milliampsPerLed = 55, milliampsPerLed = 55,
_disableNLeds = 0,
getBrightness(void), getBrightness(void),
getMode(void), getMode(void),
getSpeed(void), getSpeed(void),
@ -383,7 +386,8 @@ class WS2812FX {
uint16_t uint16_t
ablMilliampsMax, ablMilliampsMax,
currentMilliamps; currentMilliamps,
_usableCount;
uint32_t uint32_t
timebase, timebase,
@ -491,6 +495,7 @@ class WS2812FX {
mode_twinklecat(void), mode_twinklecat(void),
mode_halloween_eyes(void), mode_halloween_eyes(void),
mode_static_pattern(void), mode_static_pattern(void),
mode_tri_static_pattern(void),
mode_police(void), mode_police(void),
mode_policeall(void); mode_policeall(void);
@ -563,7 +568,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"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", "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","Police","Police All" "Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Tri Color Pattern", "Police","Police All"
])====="; ])=====";

View File

@ -30,25 +30,40 @@
#define LED_SKIP_AMOUNT 1 #define LED_SKIP_AMOUNT 1
#define MIN_SHOW_DELAY 15 #define MIN_SHOW_DELAY 15
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uint8_t disableNLeds)
{ {
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL) return; if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && disableNLeds == _disableNLeds) return;
RESET_RUNTIME; RESET_RUNTIME;
_rgbwMode = supportWhite; _rgbwMode = supportWhite;
_skipFirstMode = skipFirst; _skipFirstMode = skipFirst;
_length = countPixels; _length = countPixels;
if (disableNLeds > 0) {
uint16_t groupCount = disableNLeds +1;
//since 1st led is lit, even partial group has a led lit, whereas int division truncates decimal.
bool hasExtraLight = _length % groupCount != 0;
_usableCount = _length/groupCount;
_usableCount += hasExtraLight ? 1 : 0;
} else {
_usableCount = _length;
}
_disableNLeds = disableNLeds;
uint8_t ty = 1; uint8_t ty = 1;
if (supportWhite) ty =2; if (supportWhite) ty =2;
uint16_t lengthRaw = _length; uint16_t lengthRaw = _length;
if (_skipFirstMode) lengthRaw += LED_SKIP_AMOUNT; if (_skipFirstMode) {
lengthRaw += LED_SKIP_AMOUNT;
}
bus->Begin((NeoPixelType)ty, lengthRaw); bus->Begin((NeoPixelType)ty, lengthRaw);
delete[] _locked; delete[] _locked;
_locked = new byte[_length]; _locked = new byte[_length];
_segments[0].start = 0; _segments[0].start = 0;
_segments[0].stop = _length; _segments[0].stop = _usableCount;
unlockAll(); unlockAll();
setBrightness(_brightness); setBrightness(_brightness);
@ -99,8 +114,9 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{ {
uint16_t actualPixelLocation = i * (_disableNLeds+1);
if (_locked[i] && !_modeUsesLock) return; if (_locked[i] && !_modeUsesLock) return;
if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment if (IS_REVERSE) i = SEGMENT.stop -1 -actualPixelLocation + SEGMENT.start; //reverse just individual segment
byte tmpg = g; byte tmpg = g;
switch (colorOrder) //0 = Grb, default switch (colorOrder) //0 = Grb, default
{ {
@ -111,14 +127,18 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
} }
if (!_cronixieMode) if (!_cronixieMode)
{ {
if (reverseMode) i = _length -1 -i; if (reverseMode) i = _usableCount -1 -i;
if (_skipFirstMode) if (_skipFirstMode)
{ {
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0)); if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
i += LED_SKIP_AMOUNT; i += LED_SKIP_AMOUNT;
} }
bus->SetPixelColor(actualPixelLocation, RgbwColor(r,g,b,w));
bus->SetPixelColor(i, RgbwColor(r,g,b,w)); if (_disableNLeds > 0) {
for(uint16_t offCount=0; offCount < _disableNLeds; offCount++) {
bus->SetPixelColor((actualPixelLocation+offCount+1), RgbwColor(0,0,0,0));
}
}
} else { } else {
if(i>6)return; if(i>6)return;
byte o = 10*i; byte o = 10*i;

Binary file not shown.

View File

@ -187,7 +187,8 @@ Palette blending:
<option value=3>None (not recommended)</option> <option value=3>None (not recommended)</option>
</select><br> </select><br>
Reverse LED order (rotate 180): <input type=checkbox name=RV><br> Reverse LED order (rotate 180): <input type=checkbox name=RV><br>
Skip first LED: <input type=checkbox name=SL><hr> Skip first LED: <input type=checkbox name=SL><br>
Disable repeating N LED: <input type=number min=0 max=255 name=DL>(Spaces out patterns by turning off leds between colors)<hr>
<button type=button onclick=B()>Back</button><button type=submit>Save</button> <button type=button onclick=B()>Back</button><button type=submit>Save</button>
</form></body> </form></body>
</html>)====="; </html>)=====";

View File

@ -155,6 +155,7 @@ uint16_t transitionDelay = 750; //default crossfade duration in ms
//bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h //bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
uint8_t disableNLeds = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look)
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)

View File

@ -244,6 +244,8 @@ void saveSettingsToEEPROM()
saveCurrPresetCycConf = false; saveCurrPresetCycConf = false;
} }
EEPROM.write(2213, disableNLeds);
writeStringToEEPROM(2220, blynkApiKey, 35); writeStringToEEPROM(2220, blynkApiKey, 35);
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
@ -515,6 +517,8 @@ void loadSettingsFromEEPROM(bool first)
presetApplyFx = EEPROM.read(2212); presetApplyFx = EEPROM.read(2212);
} }
disableNLeds = EEPROM.read(2213);
bootPreset = EEPROM.read(389); bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393); wifiLock = EEPROM.read(393);
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00); utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);

View File

@ -272,6 +272,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('i',"PB",strip.paletteBlend); sappend('i',"PB",strip.paletteBlend);
sappend('c',"RV",strip.reverseMode); sappend('c',"RV",strip.reverseMode);
sappend('c',"SL",skipFirstLed); sappend('c',"SL",skipFirstLed);
sappend('v',"DL",disableNLeds);
} }
if (subPage == 3) if (subPage == 3)

View File

@ -85,10 +85,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
colS[0] = request->arg("CR").toInt(); colS[0] = request->arg("CR").toInt();
colS[1] = request->arg("CG").toInt(); colS[1] = request->arg("CG").toInt();
colS[2] = request->arg("CB").toInt(); colS[2] = request->arg("CB").toInt();
colS[3] = request->arg("CW").toInt();
colSecS[0] = request->arg("SR").toInt(); colSecS[0] = request->arg("SR").toInt();
colSecS[1] = request->arg("SG").toInt(); colSecS[1] = request->arg("SG").toInt();
colSecS[2] = request->arg("SB").toInt(); colSecS[2] = request->arg("SB").toInt();
colS[3] = request->arg("CW").toInt();
colSecS[3] = request->arg("SW").toInt(); colSecS[3] = request->arg("SW").toInt();
briS = request->arg("CA").toInt(); briS = request->arg("CA").toInt();
effectDefault = request->arg("FX").toInt(); effectDefault = request->arg("FX").toInt();
@ -120,6 +120,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (t >= 0 && t < 4) strip.paletteBlend = t; if (t >= 0 && t < 4) strip.paletteBlend = t;
strip.reverseMode = request->hasArg("RV"); strip.reverseMode = request->hasArg("RV");
skipFirstLed = request->hasArg("SL"); skipFirstLed = request->hasArg("SL");
disableNLeds = request->arg("DL").toInt();
t = request->arg("BF").toInt(); t = request->arg("BF").toInt();
if (t > 0) briMultiplier = t; if (t > 0) briMultiplier = t;
} }
@ -310,7 +313,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
} }
} }
if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed); if (subPage == 2) {
strip.init(useRGBW,ledCount,skipFirstLed,disableNLeds);
}
if (subPage == 4) alexaInit(); if (subPage == 4) alexaInit();
} }

View File

@ -7,6 +7,11 @@ void wledInit()
EEPROM.begin(EEPSIZE); EEPROM.begin(EEPSIZE);
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30;
disableNLeds = EEPROM.read(2213);
//this was reading 255 after inital flash causing bootloop. Don't know why.
disableNLeds = disableNLeds != 255 ? disableNLeds : 0;
#ifdef ESP8266 #ifdef ESP8266
#if LEDPIN == 3 #if LEDPIN == 3
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
@ -25,7 +30,7 @@ void wledInit()
DEBUG_PRINT("heap "); DEBUG_PRINT("heap ");
DEBUG_PRINTLN(ESP.getFreeHeap()); DEBUG_PRINTLN(ESP.getFreeHeap());
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204),disableNLeds); //init LEDs quickly
strip.setBrightness(0); strip.setBrightness(0);
DEBUG_PRINT("LEDs inited. heap usage ~"); DEBUG_PRINT("LEDs inited. heap usage ~");