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
.piolibdeps
.vscode
platformio.ini
!.vscode/extensions.json
/wled00/Release
/wled00/extLibs

View File

@ -141,7 +141,7 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) {
SEGENV.step = 0;
}
}
uint16_t ledIndex = (prog * SEGLEN) >> 15;
uint16_t rem = 0;
rem = (prog * SEGLEN) * 2; //mod 0xFFFF
@ -2346,6 +2346,29 @@ uint16_t WS2812FX::mode_static_pattern()
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
uint16_t WS2812FX::mode_policeall()

View File

@ -84,7 +84,7 @@
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
#define MODE_COUNT 86
#define MODE_COUNT 87
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
@ -171,8 +171,9 @@
#define FX_MODE_TWINKLECAT 81
#define FX_MODE_HALLOWEEN_EYES 82
#define FX_MODE_STATIC_PATTERN 83
#define FX_MODE_POLICE 84
#define FX_MODE_POLICE_ALL 85
#define FX_MODE_TRI_STATIC_PATTERN 84
#define FX_MODE_POLICE 85
#define FX_MODE_POLICE_ALL 86
class WS2812FX {
@ -312,6 +313,7 @@ class WS2812FX {
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
_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;
@ -328,7 +330,7 @@ class WS2812FX {
}
void
init(bool supportWhite, uint16_t countPixels, bool skipFirs),
init(bool supportWhite, uint16_t countPixels, bool skipFirs, uint8_t disableNLeds),
service(void),
blur(uint8_t),
fade_out(uint8_t r),
@ -370,6 +372,7 @@ class WS2812FX {
paletteBlend = 0,
colorOrder = 0,
milliampsPerLed = 55,
_disableNLeds = 0,
getBrightness(void),
getMode(void),
getSpeed(void),
@ -383,7 +386,8 @@ class WS2812FX {
uint16_t
ablMilliampsMax,
currentMilliamps;
currentMilliamps,
_usableCount;
uint32_t
timebase,
@ -491,6 +495,7 @@ class WS2812FX {
mode_twinklecat(void),
mode_halloween_eyes(void),
mode_static_pattern(void),
mode_tri_static_pattern(void),
mode_police(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",
"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","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 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;
_rgbwMode = supportWhite;
_skipFirstMode = skipFirst;
_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;
if (supportWhite) ty =2;
uint16_t lengthRaw = _length;
if (_skipFirstMode) lengthRaw += LED_SKIP_AMOUNT;
if (_skipFirstMode) {
lengthRaw += LED_SKIP_AMOUNT;
}
bus->Begin((NeoPixelType)ty, lengthRaw);
delete[] _locked;
_locked = new byte[_length];
_segments[0].start = 0;
_segments[0].stop = _length;
_segments[0].stop = _usableCount;
unlockAll();
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)
{
uint16_t actualPixelLocation = i * (_disableNLeds+1);
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;
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 (reverseMode) i = _length -1 -i;
if (reverseMode) i = _usableCount -1 -i;
if (_skipFirstMode)
{
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
i += LED_SKIP_AMOUNT;
}
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
bus->SetPixelColor(actualPixelLocation, 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 {
if(i>6)return;
byte o = 10*i;

Binary file not shown.

View File

@ -187,7 +187,8 @@ Palette blending:
<option value=3>None (not recommended)</option>
</select><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>
</form></body>
</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 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)

View File

@ -244,6 +244,8 @@ void saveSettingsToEEPROM()
saveCurrPresetCycConf = false;
}
EEPROM.write(2213, disableNLeds);
writeStringToEEPROM(2220, blynkApiKey, 35);
for (int i = 0; i < 8; ++i)
@ -515,6 +517,8 @@ void loadSettingsFromEEPROM(bool first)
presetApplyFx = EEPROM.read(2212);
}
disableNLeds = EEPROM.read(2213);
bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393);
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('c',"RV",strip.reverseMode);
sappend('c',"SL",skipFirstLed);
sappend('v',"DL",disableNLeds);
}
if (subPage == 3)

View File

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

View File

@ -7,6 +7,11 @@ void wledInit()
EEPROM.begin(EEPSIZE);
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
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
#if LEDPIN == 3
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_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);
DEBUG_PRINT("LEDs inited. heap usage ~");