Merge pull request #1 from Aircoookie/master

Update to recent version
This commit is contained in:
srg74 2019-12-31 21:27:27 -05:00 committed by GitHub
commit cf12ab4b74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 258 additions and 66 deletions

View File

@ -41,6 +41,8 @@ lib_deps_external =
IRremoteESP8266@2.5.5
#Time@1.5
#Timezone@1.2.1
#For use SSD1306 0.91" OLED display uncomment following
#U8g2@~2.27.2
[common:esp8266]
# ------------------------------------------------------------------------------
@ -214,4 +216,4 @@ build_flags =
-D WLED_ENABLE_5CH_LEDS
lib_deps =
${common.lib_deps_external}

View File

@ -4,5 +4,5 @@ This code uses Aircookie's WLED software. It has a premade file for user modific
To install:
Add the enties in the WLED00 file to the top of the same file from Aircoookies WLED.
Add the entries in the WLED00 file to the top of the same file from Aircoookies WLED.
Replace the WLED06_usermod.ino file in Aircoookies WLED folder.

View File

@ -1,7 +1,7 @@
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
//The SCL and SDA pins are defined here.
//Lolin32 boards use SCL=4 SDA=5
//Lolin32 boards use SCL=5 SDA=4
#define U8X8_PIN_SCL 5
#define U8X8_PIN_SDA 4

View File

@ -242,7 +242,7 @@ uint16_t WS2812FX::mode_dynamic(void) {
uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*15;
uint32_t it = now / cycleTime;
if (it != SEGENV.step) //new color
if (it != SEGENV.step && SEGMENT.speed != 0) //new color
{
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
if (random8() <= SEGMENT.intensity) _locked[i] = random8();
@ -414,7 +414,6 @@ uint16_t WS2812FX::mode_theater_chase(void) {
* Inspired by the Adafruit examples.
*/
uint16_t WS2812FX::mode_theater_chase_rainbow(void) {
SEGENV.step = (SEGENV.step + 1) & 0xFF;
return theater_chase(color_wheel(SEGENV.step), SEGCOLOR(1), false);
}
@ -961,6 +960,10 @@ uint16_t WS2812FX::mode_halloween(void) {
* Random colored pixels running.
*/
uint16_t WS2812FX::mode_running_random(void) {
uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed));
uint32_t it = now / cycleTime;
if (SEGENV.aux1 == it) return FRAMETIME;
for(uint16_t i=SEGLEN-1; i > 0; i--) {
setPixelColor(SEGMENT.start + i, getPixelColor(SEGMENT.start + i - 1));
}
@ -975,7 +978,9 @@ uint16_t WS2812FX::mode_running_random(void) {
{
SEGENV.step = 0;
}
return SPEED_FORMULA_L;
SEGENV.aux1 = it;
return FRAMETIME;
}
@ -1091,6 +1096,10 @@ uint16_t WS2812FX::mode_rain()
* Fire flicker function
*/
uint16_t WS2812FX::mode_fire_flicker(void) {
uint32_t cycleTime = 40 + (255 - SEGMENT.speed);
uint32_t it = now / cycleTime;
if (SEGENV.step == it) return FRAMETIME;
byte w = (SEGCOLOR(0) >> 24) & 0xFF;
byte r = (SEGCOLOR(0) >> 16) & 0xFF;
byte g = (SEGCOLOR(0) >> 8) & 0xFF;
@ -1105,7 +1114,9 @@ uint16_t WS2812FX::mode_fire_flicker(void) {
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker));
}
}
return 20 + random((255 - SEGMENT.speed),(2 * (uint16_t)(255 - SEGMENT.speed)));
SEGENV.step = it;
return FRAMETIME;
}
@ -1294,20 +1305,38 @@ uint16_t WS2812FX::mode_icu(void) {
*/
uint16_t WS2812FX::mode_tricolor_wipe(void)
{
if(SEGENV.step < SEGLEN) {
uint32_t led_offset = SEGENV.step;
setPixelColor(SEGMENT.start + led_offset, SEGCOLOR(0));
} else if (SEGENV.step < SEGLEN*2) {
uint32_t led_offset = SEGENV.step - SEGLEN;
setPixelColor(SEGMENT.start + led_offset, SEGCOLOR(1));
} else
uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200;
uint32_t perc = now % cycleTime;
uint16_t prog = (perc * 65535) / cycleTime;
uint16_t ledIndex = (prog * SEGLEN * 3) >> 16;
uint16_t ledOffset = ledIndex;
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{
uint32_t led_offset = SEGENV.step - SEGLEN*2;
setPixelColor(SEGMENT.start + led_offset, color_from_palette(SEGMENT.start + led_offset, true, PALETTE_SOLID_WRAP, 2));
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2));
}
if(ledIndex < SEGLEN) { //wipe from 0 to 1
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{
setPixelColor(i, (i - SEGMENT.start > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1));
}
} else if (ledIndex < SEGLEN*2) { //wipe from 1 to 2
ledOffset = ledIndex - SEGLEN;
for (uint16_t i = SEGMENT.start +ledOffset +1; i < SEGMENT.stop; i++)
{
setPixelColor(i, SEGCOLOR(1));
}
} else //wipe from 2 to 0
{
ledOffset = ledIndex - SEGLEN*2;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.start +ledOffset; i++)
{
setPixelColor(i, SEGCOLOR(0));
}
}
SEGENV.step = (SEGENV.step + 1) % (SEGLEN * 3);
return SPEED_FORMULA_L;
return FRAMETIME;
}
@ -1318,14 +1347,17 @@ uint16_t WS2812FX::mode_tricolor_wipe(void)
*/
uint16_t WS2812FX::mode_tricolor_fade(void)
{
uint16_t counter = now * ((SEGMENT.speed >> 3) +1);
uint32_t prog = (counter * 768) >> 16;
uint32_t color1 = 0, color2 = 0;
byte stage = 0;
if(SEGENV.step < 256) {
if(prog < 256) {
color1 = SEGCOLOR(0);
color2 = SEGCOLOR(1);
stage = 0;
} else if(SEGENV.step < 512) {
} else if(prog < 512) {
color1 = SEGCOLOR(1);
color2 = SEGCOLOR(2);
stage = 1;
@ -1335,7 +1367,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void)
stage = 2;
}
byte stp = SEGENV.step % 256;
byte stp = prog; // % 256
uint32_t color = 0;
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
if (stage == 2) {
@ -1348,10 +1380,7 @@ uint16_t WS2812FX::mode_tricolor_fade(void)
setPixelColor(i, color);
}
SEGENV.step += 4;
if(SEGENV.step >= 768) SEGENV.step = 0;
return 5 + ((uint32_t)(255 - SEGMENT.speed) / 10);
return FRAMETIME;
}
@ -1361,6 +1390,10 @@ uint16_t WS2812FX::mode_tricolor_fade(void)
*/
uint16_t WS2812FX::mode_multi_comet(void)
{
uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed));
uint32_t it = now / cycleTime;
if (SEGENV.step == it) return FRAMETIME;
fade_out(SEGMENT.intensity);
static uint16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX};
@ -1382,7 +1415,9 @@ uint16_t WS2812FX::mode_multi_comet(void)
}
}
}
return SPEED_FORMULA_L;
SEGENV.step = it;
return FRAMETIME;
}
@ -2402,3 +2437,118 @@ uint16_t WS2812FX::mode_candle()
return FRAMETIME;
}
/*
/ Fireworks in starburst effect
/ based on the video: https://www.reddit.com/r/arduino/comments/c3sd46/i_made_this_fireworks_effect_for_my_led_strips/
/ Speed sets frequency of new starbursts, intensity is the intensity of the burst
*/
#define STARBURST_MAX_FRAG 12
typedef struct particle {
CRGB color;
uint32_t birth =0;
uint32_t last =0;
float vel =0;
uint16_t pos =-1;
float fragment[STARBURST_MAX_FRAG];
} star;
uint16_t WS2812FX::mode_starburst(void) {
uint32_t it = millis();
const uint8_t numStars = 15;
static star stars[numStars];
float maxSpeed = 375.0f; // Max velocity
float particleIgnition = 250.0f; // How long to "flash"
float particleFadeTime = 1500.0f; // Fade out time
for (int j = 0; j < numStars; j++)
{
// speed to adjust chance of a burst, max is nearly always.
if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0)
{
// Pick a random color and location.
uint16_t startPos = random16(SEGLEN-1);
float multiplier = (float)(random8())/255.0 * 1.0;
stars[j].color = col_to_crgb(color_wheel(random8()));
stars[j].pos = startPos;
stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier;
stars[j].birth = it;
stars[j].last = it;
// more fragments means larger burst effect
int num = random8(3,6 + (SEGMENT.intensity >> 5));
for (int i=0; i < STARBURST_MAX_FRAG; i++) {
if (i < num) stars[j].fragment[i] = startPos;
else stars[j].fragment[i] = -1;
}
}
}
fill(SEGCOLOR(1));
for (int j=0; j<numStars; j++)
{
if (stars[j].birth != 0) {
float dt = (it-stars[j].last)/1000.0;
for (int i=0; i < STARBURST_MAX_FRAG; i++) {
int var = i >> 1;
if (stars[j].fragment[i] > 0) {
//all fragments travel right, will be mirrored on other side
stars[j].fragment[i] += stars[j].vel * dt * (float)var/3.0;
}
}
stars[j].last = it;
stars[j].vel -= 3*stars[j].vel*dt;
}
CRGB c = stars[j].color;
// If the star is brand new, it flashes white briefly.
// Otherwise it just fades over time.
float fade = 0.0f;
float age = it-stars[j].birth;
if (age < particleIgnition) {
c = col_to_crgb(color_blend(WHITE, crgb_to_col(c), 254.5f*((age / particleIgnition))));
} else {
// Figure out how much to fade and shrink the star based on
// its age relative to its lifetime
if (age > particleIgnition + particleFadeTime) {
fade = 1.0f; // Black hole, all faded out
stars[j].birth = 0;
c = col_to_crgb(SEGCOLOR(1));
} else {
age -= particleIgnition;
fade = (age / particleFadeTime); // Fading star
byte f = 254.5f*fade;
c = col_to_crgb(color_blend(crgb_to_col(c), SEGCOLOR(1), f));
}
}
float particleSize = (1.0 - fade) * 2;
for (uint8_t index=0; index < STARBURST_MAX_FRAG*2; index++) {
bool mirrored = index & 0x1;
uint8_t i = index >> 1;
if (stars[j].fragment[i] > 0) {
float loc = stars[j].fragment[i];
if (mirrored) loc -= (loc-stars[j].pos)*2;
int start = loc - particleSize;
int end = loc + particleSize;
if (start < 0) start = 0;
if (start == end) end++;
if (end > SEGLEN) end = SEGLEN;
for (int p = start; p < end; p++) {
setPixelColor(SEGMENT.start+p, c.r, c.g, c.b);
}
}
}
}
return FRAMETIME;
}

View File

@ -44,10 +44,17 @@
#define WLED_FPS 42
#define FRAMETIME (1000/WLED_FPS)
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#define MAX_NUM_SEGMENTS 10
/* How much data bytes all segments combined may allocate */
#ifdef ESP8266
#define MAX_SEGMENT_DATA 2048
#else
#define MAX_SEGMENT_DATA 8192
#endif
#define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index]
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
@ -84,7 +91,7 @@
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
#define MODE_COUNT 89
#define MODE_COUNT 90
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
@ -175,6 +182,7 @@
#define FX_MODE_SPOTS_FADE 86
#define FX_MODE_GLITTER 87
#define FX_MODE_CANDLE 88
#define FX_MODE_STARBURST 89
class WS2812FX {
@ -221,13 +229,35 @@ class WS2812FX {
} segment;
// segment runtime parameters
typedef struct Segment_runtime { // 16 bytes
typedef struct Segment_runtime { // 28 bytes
unsigned long next_time;
uint32_t step;
uint32_t call;
uint16_t aux0;
uint16_t aux1;
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;};
byte* data = nullptr;
bool allocateData(uint16_t len){
if (data && _dataLen == len) return true; //already allocated
deallocateData();
if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
data = new (std::nothrow) byte[len];
if (!data) return false; //allocation failed
WS2812FX::_usedSegmentData += len;
_dataLen = len;
memset(data, 0, len);
return true;
}
void deallocateData(){
if (data) {
delete[] data;
}
data = nullptr;
WS2812FX::_usedSegmentData -= _dataLen;
_dataLen = 0;
}
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
private:
uint16_t _dataLen = 0;
} segment_runtime;
WS2812FX() {
@ -321,6 +351,7 @@ class WS2812FX {
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
_mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst;
_brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black);
@ -503,7 +534,8 @@ class WS2812FX {
mode_spots(void),
mode_spots_fade(void),
mode_glitter(void),
mode_candle(void);
mode_candle(void),
mode_starburst(void);
private:
@ -518,6 +550,7 @@ class WS2812FX {
uint16_t _length, _lengthRaw, _usableCount;
uint16_t _rand16seed;
uint8_t _brightness;
static uint16_t _usedSegmentData;
void handle_palette(void);
void fill(uint32_t);
@ -564,7 +597,8 @@ class WS2812FX {
// start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
};
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
friend class Segment_runtime;
};
@ -576,9 +610,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",
"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",
"Scanner Dual ","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle"
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst"
])=====";

View File

@ -473,7 +473,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
void WS2812FX::resetSegments() {
memset(_segments, 0, sizeof(_segments));
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
//memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
_segment_index = 0;
_segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR;
@ -484,7 +484,9 @@ void WS2812FX::resetSegments() {
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
{
_segments[i].colors[0] = color_wheel(i*51);
_segment_runtimes[i].reset();
}
_segment_runtimes[0].reset();
}
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
@ -862,3 +864,5 @@ uint32_t WS2812FX::gamma32(uint32_t color)
b = gammaT[b];
return ((w << 24) | (r << 16) | (g << 8) | (b));
}
uint16_t WS2812FX::_usedSegmentData = 0;

View File

@ -130,26 +130,25 @@ public:
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
#endif
_pGrbw->Begin();
break;
#ifdef WLED_USE_ANALOG_LEDS
//init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); pinMode(W2PIN, OUTPUT); break;
#else
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break;
#endif
}
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#ifdef WLED_USE_ANALOG_LEDS
pinMode(WPIN, OUTPUT);
#ifdef WLED_USE_5CH_LEDS
pinMode(W2PIN, OUTPUT);
#endif
#endif
break;
}
#ifdef WLED_USE_ANALOG_LEDS
//init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#endif
}
#ifdef WLED_USE_ANALOG_LEDS

View File

@ -98,7 +98,7 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1912232
#define VERSION 1912312
char versionString[] = "0.9.0-b2";

View File

@ -622,6 +622,10 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
//cronixie
#ifndef WLED_DISABLE_CRONIXIE
//mode, 1 countdown
pos = req.indexOf("NM=");
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
pos = req.indexOf("NX="); //sets digits to code
if (pos > 0) {
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
@ -636,9 +640,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
overlayRefreshedTime = 0;
}
#endif
//mode, 1 countdown
pos = req.indexOf("NM=");
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
pos = req.indexOf("U0="); //user var 0
if (pos > 0) {

View File

@ -163,13 +163,16 @@ void setCountdown()
//returns true if countdown just over
bool checkCountdown()
{
long diff = countdownTime - now();
local = abs(diff);
if (diff <0 && !countdownOverTriggered)
{
if (macroCountdown != 0) applyMacro(macroCountdown);
countdownOverTriggered = true;
return true;
unsigned long n = now();
local = countdownTime - n;
if (n > countdownTime) {
local = n - countdownTime;
if (!countdownOverTriggered)
{
if (macroCountdown != 0) applyMacro(macroCountdown);
countdownOverTriggered = true;
return true;
}
}
return false;
}

View File

@ -147,7 +147,6 @@ void _overlayCronixie()
{
if (countdownMode) checkCountdown();
#ifndef WLED_DISABLE_CRONIXIE
byte h = hour(local);
byte h0 = h;
byte m = minute(local);

View File

@ -243,7 +243,7 @@ void serializeInfo(JsonObject root)
leds_pin.add(LEDPIN);
leds["pwr"] = strip.currentMilliamps;
leds["maxpwr"] = strip.ablMilliampsMax;
leds["maxpwr"] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
leds["maxseg"] = strip.getMaxSegments();
leds["seglock"] = false; //will be used in the future to prevent modifications to segment config