Merge branch 'MoonModules:mdev' into Strip_Level_Color_Adjust
This commit is contained in:
@@ -1126,7 +1126,7 @@ static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream ☾@!,Zone si
|
||||
uint16_t larson_scanner(bool dual) {
|
||||
uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8);
|
||||
uint16_t index = counter * SEGLEN >> 16;
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
SEGMENT.fade_out(SEGMENT.intensity);
|
||||
|
||||
@@ -1738,7 +1738,7 @@ uint16_t mode_multi_comet(void) {
|
||||
if (SEGENV.step == it) return FRAMETIME;
|
||||
if (!SEGENV.allocateData(sizeof(uint16_t) * 8)) return mode_static(); //allocation failed
|
||||
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
SEGMENT.fade_out(SEGMENT.intensity);
|
||||
|
||||
uint16_t* comets = reinterpret_cast<uint16_t*>(SEGENV.data);
|
||||
@@ -2096,7 +2096,7 @@ uint16_t mode_fire_2012() {
|
||||
const uint16_t strips = SEGMENT.nrOfVStrips();
|
||||
if (!SEGENV.allocateData(strips * SEGLEN)) return mode_static(); //allocation failed
|
||||
byte* heat = SEGENV.data;
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
const uint32_t it = strip.now >> 5; //div 32
|
||||
|
||||
@@ -2529,7 +2529,7 @@ uint16_t ripple_base()
|
||||
uint16_t dataSize = sizeof(ripple) * maxRipples;
|
||||
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
Ripple* ripples = reinterpret_cast<Ripple*>(SEGENV.data);
|
||||
|
||||
@@ -3552,7 +3552,10 @@ uint16_t mode_exploding_fireworks(void)
|
||||
if (SEGLEN == 1) return mode_static();
|
||||
const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {
|
||||
SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
SEGMENT.fill(BLACK);
|
||||
}
|
||||
|
||||
//allocate segment data
|
||||
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
|
||||
@@ -4306,7 +4309,7 @@ static const char _data_FX_MODE_FLOW[] PROGMEM = "Flow@!,Zones;;!;;m12=1"; //ver
|
||||
uint16_t mode_chunchun(void)
|
||||
{
|
||||
if (SEGLEN == 1) return mode_static();
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
SEGMENT.fade_out(254); // add a bit of trail
|
||||
uint16_t counter = strip.now * (6 + (SEGMENT.speed >> 4));
|
||||
uint16_t numBirds = 2 + (SEGLEN >> 3); // 2 + 1/8 of a segment
|
||||
@@ -4822,7 +4825,7 @@ static const char _data_FX_MODE_AURORA[] PROGMEM = "Aurora@!,!;1,2,3;!;;sx=24,pa
|
||||
// Controls are speed, # of pixels, faderate.
|
||||
uint16_t mode_perlinmove(void) {
|
||||
if (SEGLEN == 1) return mode_static();
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
SEGMENT.fade_out(255-SEGMENT.custom1);
|
||||
for (int i = 0; i < SEGMENT.intensity/16 + 1; i++) {
|
||||
uint16_t locn = inoise16(strip.now*128/(260-SEGMENT.speed)+i*15000, strip.now*128/(260-SEGMENT.speed)); // Get a new pixel location from moving noise.
|
||||
@@ -6055,7 +6058,7 @@ uint16_t mode_2Dghostrider(void) {
|
||||
|
||||
const size_t maxLighters = min(cols + rows, LIGHTERS_AM);
|
||||
|
||||
if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);}
|
||||
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
||||
SEGENV.aux0 = cols;
|
||||
SEGENV.aux1 = rows;
|
||||
@@ -6140,7 +6143,7 @@ uint16_t mode_2Dfloatingblobs(void) {
|
||||
if (!SEGENV.allocateData(sizeof(blob_t))) return mode_static(); //allocation failed
|
||||
blob_t *blob = reinterpret_cast<blob_t*>(SEGENV.data);
|
||||
|
||||
if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);}
|
||||
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
||||
SEGENV.aux0 = cols; // re-initialise if virtual size changes
|
||||
SEGENV.aux1 = rows;
|
||||
@@ -6408,6 +6411,7 @@ uint16_t mode_ripplepeak(void) { // * Ripple peak. By Andrew Tuli
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
SEGMENT.setUpLeds();
|
||||
SEGMENT.fill(BLACK);
|
||||
SEGENV.aux0 = 255;
|
||||
SEGMENT.custom1 = *binNum;
|
||||
SEGMENT.custom2 = *maxVol * 2;
|
||||
@@ -6766,18 +6770,19 @@ uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline.
|
||||
um_data = simulateSound(SEGMENT.soundSim);
|
||||
}
|
||||
float volumeSmth = *(float*) um_data->u_data[0];
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
SEGMENT.fade_out(224); // 6.25%
|
||||
uint16_t my_sampleAgc = fmax(fmin(volumeSmth, 255.0), 0);
|
||||
|
||||
for (size_t i=0; i<SEGMENT.intensity/32+1U; i++) {
|
||||
// if SEGLEN equals 1, we will always set color to the first and only pixel, but the effect is still good looking
|
||||
SEGMENT.setPixelColor(beatsin16(SEGMENT.speed/4+i*2,0,SEGLEN-1), color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(strip.now/4+i*2, false, PALETTE_SOLID_WRAP, 0), my_sampleAgc));
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_juggles()
|
||||
static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!;1v;m12=0,si=0"; // Pixels, Beatsin
|
||||
static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!;01v;m12=0,si=0"; // Pixels, Beatsin
|
||||
|
||||
|
||||
//////////////////////
|
||||
@@ -6905,7 +6910,7 @@ uint16_t mode_noisefire(void) { // Noisefire. By Andrew Tuline.
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_noisefire()
|
||||
static const char _data_FX_MODE_NOISEFIRE[] PROGMEM = "Noisefire@!,!;;;1v;m12=2,si=0"; // Arc, Beatsin
|
||||
static const char _data_FX_MODE_NOISEFIRE[] PROGMEM = "Noisefire@!,!;;;01v;m12=2,si=0"; // Arc, Beatsin
|
||||
|
||||
|
||||
///////////////////////
|
||||
@@ -6920,7 +6925,7 @@ uint16_t mode_noisemeter(void) { // Noisemeter. By Andrew Tuline.
|
||||
}
|
||||
float volumeSmth = *(float*) um_data->u_data[0];
|
||||
int16_t volumeRaw = *(int16_t*)um_data->u_data[1];
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
//uint8_t fadeRate = map(SEGMENT.speed,0,255,224,255);
|
||||
uint8_t fadeRate = map(SEGMENT.speed,0,255,200,254);
|
||||
@@ -6977,7 +6982,7 @@ uint16_t mode_pixelwave(void) { // Pixelwave. By Andrew Tuline.
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_pixelwave()
|
||||
static const char _data_FX_MODE_PIXELWAVE[] PROGMEM = "Pixelwave@!,Sensitivity;!,!;!;1v;ix=64,m12=2,si=0"; // Arc, Beatsin
|
||||
static const char _data_FX_MODE_PIXELWAVE[] PROGMEM = "Pixelwave@!,Sensitivity;!,!;!;01v;ix=64,m12=2,si=0"; // Arc, Beatsin
|
||||
|
||||
|
||||
//////////////////////
|
||||
@@ -7023,7 +7028,7 @@ uint16_t mode_plasmoid(void) { // Plasmoid. By Andrew Tuline.
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_plasmoid()
|
||||
static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels;!,!;!;1v;sx=128,ix=80,pal=8,m12=0,si=0"; // Pixels, Beatsin, Lava Palette
|
||||
static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels;!,!;!;01v;sx=128,ix=80,pal=8,m12=0,si=0"; // Pixels, Beatsin, Lava Palette
|
||||
|
||||
|
||||
///////////////////////
|
||||
@@ -7122,7 +7127,7 @@ uint16_t mode_pixels(void) { // Pixels. By Andrew Tuline.
|
||||
um_data = simulateSound(SEGMENT.soundSim);
|
||||
}
|
||||
float volumeSmth = *(float*) um_data->u_data[0];
|
||||
if (SEGENV.call == 0) SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
if (SEGENV.call == 0) {SEGENV.setUpLeds(); SEGMENT.fill(BLACK);} // WLEDMM use lossless getPixelColor()
|
||||
|
||||
myVals[strip.now%32] = volumeSmth; // filling values semi randomly
|
||||
|
||||
@@ -7178,7 +7183,7 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline.
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_blurz()
|
||||
static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz@Fade rate,Blur;!,Color mix;!;1f;m12=0,si=0"; // Pixels, Beatsin
|
||||
static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz@Fade rate,Blur;!,Color mix;!;01f;m12=0,si=0"; // Pixels, Beatsin
|
||||
|
||||
#else // original version from SR 0.13, with some enhancements by @softhack007
|
||||
uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline.
|
||||
@@ -7209,6 +7214,7 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline.
|
||||
if ((SEGENV.aux1 < SEGLEN) && (volumeSmth > 1.0f)) SEGMENT.setPixelColor(SEGENV.aux1,SEGENV.step); // "repaint" last pixel after blur
|
||||
|
||||
uint16_t segLoc = random16(SEGLEN);
|
||||
if (SEGLEN < 2) segLoc = 0; // WLEDMM just to be sure
|
||||
unsigned pixColor = (2*fftResult[SEGENV.aux0%16]*240)/max(1, SEGLEN-1); // WLEDMM avoid uint8 overflow, and preserve pixel parameters for redraw
|
||||
unsigned pixIntensity = min((unsigned)(2.0f*fftResult[SEGENV.aux0%16]), 255U);
|
||||
|
||||
@@ -7225,13 +7231,14 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline.
|
||||
|
||||
return FRAMETIME_FIXED;
|
||||
} // mode_blurz()
|
||||
static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz ☾@Fade rate,Blur;!,Color mix;!;1f;sx=48,ix=127,m12=0,si=0"; // Pixels, Beatsin
|
||||
static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz ☾@Fade rate,Blur;!,Color mix;!;01f;sx=48,ix=127,m12=0,si=0"; // Pixels, Beatsin
|
||||
#endif
|
||||
|
||||
/////////////////////////
|
||||
// ** DJLight //
|
||||
/////////////////////////
|
||||
uint16_t mode_DJLight(void) { // Written by Stefan Petrick, Adapted by Will Tatam.
|
||||
// No need to prevent from executing on single led strips, only mid will be set (mid = 0)
|
||||
const int mid = SEGLEN / 2;
|
||||
|
||||
um_data_t *um_data;
|
||||
@@ -7287,13 +7294,14 @@ uint16_t mode_DJLight(void) { // Written by Stefan Petrick, Ad
|
||||
if (SEGENV.check1) fadeVal = constrain(fadeVal, 0, 176); // "candy factory" mode - avoid complete fade-out
|
||||
SEGMENT.setPixelColor(mid, color.fadeToBlackBy(fadeVal));
|
||||
|
||||
// if SEGLEN equals 1 these loops won't execute
|
||||
for (int i = SEGLEN - 1; i > mid; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); // move to the left
|
||||
for (int i = 0; i < mid; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_DJLight()
|
||||
static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed,,,,,Candy Factory;;;1f;m12=2,si=0"; // Arc, Beatsin
|
||||
static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed,,,,,Candy Factory;;;01f;m12=2,si=0"; // Arc, Beatsin
|
||||
|
||||
|
||||
////////////////////
|
||||
@@ -7347,6 +7355,7 @@ static const char _data_FX_MODE_FREQMAP[] PROGMEM = "Freqmap@Fade rate,Starting
|
||||
// ** Freqmatrix //
|
||||
///////////////////////
|
||||
uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Pleschung.
|
||||
// No need to prevent from executing on single led strips, we simply change pixel 0 each time and avoid the shift
|
||||
um_data_t *um_data;
|
||||
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
||||
// add support for no audio
|
||||
@@ -7389,12 +7398,13 @@ uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Plesch
|
||||
|
||||
// shift the pixels one pixel up
|
||||
SEGMENT.setPixelColor(0, color);
|
||||
// if SEGLEN equals 1 this loop won't execute
|
||||
for (int i = SEGLEN - 1; i > 0; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_freqmatrix()
|
||||
static const char _data_FX_MODE_FREQMATRIX[] PROGMEM = "Freqmatrix@Speed,Sound effect,Low bin,High bin,Sensitivity;;;1f;c1=18,c2=48,c3=6,m12=3,si=0"; // Corner, Beatsin; notes range C3 to C7
|
||||
static const char _data_FX_MODE_FREQMATRIX[] PROGMEM = "Freqmatrix@Speed,Sound effect,Low bin,High bin,Sensitivity;;;01f;c1=18,c2=48,c3=6,m12=3,si=0"; // Corner, Beatsin; notes range C3 to C7
|
||||
|
||||
|
||||
//////////////////////
|
||||
@@ -7451,6 +7461,7 @@ static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Sta
|
||||
// As a compromise between speed and accuracy we are currently sampling with 10240Hz, from which we can then determine with a 512bin FFT our max frequency is 5120Hz.
|
||||
// Depending on the music stream you have you might find it useful to change the frequency mapping.
|
||||
uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschung. With some enhancements by @softhack007
|
||||
// As before, this effect can also work on single pixels, we just lose the shifting effect
|
||||
um_data_t *um_data;
|
||||
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
||||
// add support for no audio
|
||||
@@ -7506,13 +7517,14 @@ uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschun
|
||||
SEGMENT.setPixelColor(SEGLEN/2, color);
|
||||
|
||||
// shift the pixels one pixel outwards
|
||||
// if SEGLEN equals 1 these loops won't execute
|
||||
for (int i = SEGLEN - 1; i > SEGLEN/2; i--) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i-1)); //move to the left
|
||||
for (int i = 0; i < SEGLEN/2; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // move to the right
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_freqwave()
|
||||
static const char _data_FX_MODE_FREQWAVE[] PROGMEM = "Freqwave@Speed,Sound effect,Low bin,High bin,Pre-amp,Musical Scale ☾;;;1f;c1=18,c2=48,m12=2,si=0"; // notes range C3 to C7, Arc, Beatsin
|
||||
static const char _data_FX_MODE_FREQWAVE[] PROGMEM = "Freqwave@Speed,Sound effect,Low bin,High bin,Pre-amp,Musical Scale ☾;;;01f;c1=18,c2=48,m12=2,si=0"; // notes range C3 to C7, Arc, Beatsin
|
||||
|
||||
|
||||
///////////////////////
|
||||
@@ -7585,8 +7597,8 @@ uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuli
|
||||
uint8_t *fftResult = (uint8_t*)um_data->u_data[2];
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
SEGMENT.fill(BLACK);
|
||||
SEGENV.setUpLeds(); // WLEDMM use lossless getPixelColor()
|
||||
SEGMENT.fill(BLACK);
|
||||
}
|
||||
//SEGMENT.fade_out(224); // Just in case something doesn't get faded.
|
||||
int fadeoutDelay = (256 - SEGMENT.speed) / 96;
|
||||
@@ -7595,13 +7607,14 @@ uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuli
|
||||
uint8_t numBins = map(SEGMENT.intensity,0,255,0,16); // Map slider to fftResult bins.
|
||||
for (int i=0; i<numBins; i++) { // How many active bins are we using.
|
||||
uint16_t locn = inoise16(strip.now*SEGMENT.speed+i*50000, strip.now*SEGMENT.speed); // Get a new pixel location from moving noise.
|
||||
// if SEGLEN equals 1 locn will be always 0, hence we set the first pixel only
|
||||
locn = map(locn, 7500, 58000, 0, SEGLEN-1); // Map that to the length of the strand, and ensure we don't go over.
|
||||
SEGMENT.setPixelColor(locn, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(i*64, false, PALETTE_SOLID_WRAP, 0), fftResult[i % 16]*4));
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_noisemove()
|
||||
static const char _data_FX_MODE_NOISEMOVE[] PROGMEM = "Noisemove@Speed of perlin movement,Fade rate;!,!;!;1f;m12=0,si=0"; // Pixels, Beatsin
|
||||
static const char _data_FX_MODE_NOISEMOVE[] PROGMEM = "Noisemove@Speed of perlin movement,Fade rate;!,!;!;01f;m12=0,si=0"; // Pixels, Beatsin
|
||||
|
||||
|
||||
//////////////////////
|
||||
@@ -7639,12 +7652,13 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac
|
||||
frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255;
|
||||
|
||||
uint16_t i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1);
|
||||
// i will be always constrained between 0 and 0 if SEGLEN equals 1
|
||||
i = constrain(i, 0, SEGLEN-1);
|
||||
SEGMENT.addPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette((uint8_t)frTemp, false, PALETTE_SOLID_WRAP, 0), volTemp));
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_rocktaves()
|
||||
static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;1f;m12=1,si=0"; // Bar, Beatsin
|
||||
static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;01f;m12=1,si=0"; // Bar, Beatsin
|
||||
|
||||
|
||||
///////////////////////
|
||||
@@ -7652,8 +7666,9 @@ static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;1f;m12=1
|
||||
///////////////////////
|
||||
// Combines peak detection with FFT_MajorPeak and FFT_Magnitude.
|
||||
uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tuline
|
||||
if (SEGENV.call == 0) SEGMENT.fill(BLACK);
|
||||
// effect can work on single pixels, we just lose the shifting effect
|
||||
|
||||
if (SEGENV.call == 0) SEGMENT.fill(BLACK);
|
||||
um_data_t *um_data;
|
||||
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
||||
// add support for no audio
|
||||
@@ -7694,12 +7709,13 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin
|
||||
} else {
|
||||
SEGMENT.setPixelColor(SEGLEN-1, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(pixCol+SEGMENT.intensity, false, PALETTE_SOLID_WRAP, 0), (int)my_magnitude));
|
||||
}
|
||||
// loop will not execute if SEGLEN equals 1
|
||||
for (int i = 0; i < SEGLEN-1; i++) SEGMENT.setPixelColor(i, SEGMENT.getPixelColor(i+1)); // shift left
|
||||
}
|
||||
|
||||
return FRAMETIME;
|
||||
} // mode_waterfall()
|
||||
static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color,Select bin,Volume (min);!,!;!;1f;c1=8,c2=48,m12=2,si=0"; // Arc, Beatsin
|
||||
static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color,Select bin,Volume (min);!,!;!;01f;c1=8,c2=48,m12=2,si=0"; // Arc, Beatsin
|
||||
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
@@ -7906,7 +7922,7 @@ uint16_t mode_2DAkemi(void) {
|
||||
const uint16_t cols = SEGMENT.virtualWidth();
|
||||
const uint16_t rows = SEGMENT.virtualHeight();
|
||||
|
||||
// if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
||||
if (SEGENV.call == 0) {SEGMENT.setUpLeds(); SEGMENT.fill(BLACK);}
|
||||
|
||||
uint16_t counter = (strip.now * ((SEGMENT.speed >> 2) +2)) & 0xFFFF;
|
||||
counter = counter >> 8;
|
||||
@@ -8049,7 +8065,8 @@ uint16_t mode_2Dsoap() {
|
||||
random16_set_seed(535);
|
||||
USER_PRINTF("SuperSync\n");
|
||||
}
|
||||
SEGMENT.setUpLeds();
|
||||
SEGENV.setUpLeds();
|
||||
SEGMENT.fill(BLACK);
|
||||
*noise32_x = random16();
|
||||
*noise32_y = random16();
|
||||
*noise32_z = random16();
|
||||
|
||||
@@ -139,4 +139,5 @@ void onAlexaChange(EspalexaDevice* dev)
|
||||
#else
|
||||
void alexaInit(){}
|
||||
void handleAlexa(){}
|
||||
#pragma message "Alexa interface disabled"
|
||||
#endif
|
||||
|
||||
@@ -313,7 +313,27 @@ void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
|
||||
//does no index check
|
||||
uint32_t BusPwm::getPixelColor(uint16_t pix) {
|
||||
if (!_valid) return 0;
|
||||
#if 1
|
||||
// WLEDMM stick with the old code - we don't have cctICused
|
||||
return RGBW32(_data[0], _data[1], _data[2], _data[3]);
|
||||
#else
|
||||
// TODO getting the reverse from CCT is involved (a quick approximation when CCT blending is ste to 0 implemented)
|
||||
switch (_type) {
|
||||
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
||||
return RGBW32(0, 0, 0, _data[0]);
|
||||
case TYPE_ANALOG_2CH: //warm white + cold white
|
||||
if (cctICused) return RGBW32(0, 0, 0, _data[0]);
|
||||
else return RGBW32(0, 0, 0, _data[0] + _data[1]);
|
||||
case TYPE_ANALOG_5CH: //RGB + warm white + cold white
|
||||
if (cctICused) return RGBW32(_data[0], _data[1], _data[2], _data[3]);
|
||||
else return RGBW32(_data[0], _data[1], _data[2], _data[3] + _data[4]);
|
||||
case TYPE_ANALOG_4CH: //RGBW
|
||||
return RGBW32(_data[0], _data[1], _data[2], _data[3]);
|
||||
case TYPE_ANALOG_3CH: //standard dumb RGB
|
||||
return RGBW32(_data[0], _data[1], _data[2], 0);
|
||||
}
|
||||
return RGBW32(_data[0], _data[0], _data[0], _data[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BusPwm::show() {
|
||||
@@ -465,6 +485,7 @@ void BusNetwork::cleanup() {
|
||||
// ***************************************************************************
|
||||
|
||||
#ifdef WLED_ENABLE_HUB75MATRIX
|
||||
#warning "HUB75 driver enabled (experimental)"
|
||||
|
||||
BusHub75Matrix::BusHub75Matrix(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||
|
||||
@@ -713,12 +734,12 @@ uint32_t BusManager::memUsage(BusConfig &bc) {
|
||||
|
||||
int BusManager::add(BusConfig &bc) {
|
||||
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
|
||||
USER_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
||||
DEBUG_PRINTF("BusManager::add(bc.type=%u)\n", bc.type);
|
||||
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
||||
busses[numBusses] = new BusNetwork(bc);
|
||||
#ifdef WLED_ENABLE_HUB75MATRIX
|
||||
} else if (bc.type >= TYPE_HUB75MATRIX && bc.type <= (TYPE_HUB75MATRIX + 10)) {
|
||||
USER_PRINTLN("BusManager::add - Adding BusHub75Matrix");
|
||||
DEBUG_PRINTLN("BusManager::add - Adding BusHub75Matrix");
|
||||
busses[numBusses] = new BusHub75Matrix(bc);
|
||||
#endif
|
||||
} else if (IS_DIGITAL(bc.type)) {
|
||||
|
||||
@@ -389,6 +389,13 @@ class PolyBus {
|
||||
}
|
||||
};
|
||||
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) {
|
||||
#if defined(ARDUINO_ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
|
||||
#if defined(WLEDMM_FASTPATH) && !defined(WLEDMM_SLOWPATH) // WLEDMM only for fastpath builds
|
||||
// NOTE: "channel" is only used on ESP32 (and its variants) for RMT channel allocation
|
||||
// since 0.15.0-b3 I2S1 is favoured for classic ESP32 and moved to position 0 (channel 0) so we need to subtract 1 for correct RMT allocation
|
||||
if (channel > 0) channel--; // accommodate I2S1 which is used as 1st bus on classic ESP32
|
||||
#endif
|
||||
#endif
|
||||
void* busPtr = nullptr;
|
||||
switch (busType) {
|
||||
case I_NONE: break;
|
||||
@@ -1192,8 +1199,8 @@ class PolyBus {
|
||||
if (num > 7) return I_NONE;
|
||||
#else
|
||||
if (num > 8) return I_NONE;
|
||||
if (num == 1) offset = 2; // use I2S#1 as 2nd bus - seems to be a good compromise for performance, and reduces flickering for some users
|
||||
// if (num == 0) offset = 2; // un-comment to use I2S#1 as 1st bus - sometimes helps, if you experience flickering during Wifi or filesystem activity.
|
||||
//if (num == 1) offset = 2; // use I2S#1 as 2nd bus - seems to be a good compromise for performance, and reduces flickering for some users
|
||||
if (num == 0) offset = 2; // un-comment to use I2S#1 as 1st bus - sometimes helps, if you experience flickering during Wifi or filesystem activity.
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -351,6 +351,7 @@
|
||||
#define ERR_LOW_MEM 33 // WLEDMM: low memory (RAM)
|
||||
#define ERR_LOW_SEG_MEM 34 // WLEDMM: low memory (segment data RAM)
|
||||
#define ERR_LOW_WS_MEM 35 // WLEDMM: low memory (ws)
|
||||
#define ERR_LOW_AJAX_MEM 36 // WLEDMM: low memory (oappend)
|
||||
|
||||
// Timer mode types
|
||||
#define NL_MODE_SET 0 //After nightlight time elapsed, set to target brightness
|
||||
|
||||
@@ -680,6 +680,7 @@ function populateInfo(i)
|
||||
if (i.ver.includes("0.14.0-b2")) vcn = "This is the way"; // recently watched The Mandalorian? I have spoken ;-)
|
||||
if (i.ver.includes("0.14.0-b15.22")) vcn = "Lupo";
|
||||
if (i.ver.includes("0.14.1-b3")) vcn = "Fried Chicken"; // final line of "One Vision" by Queen
|
||||
if (i.ver.includes("0.14.3-b")) vcn = "Fried Chicken";
|
||||
cn += `v${i.ver} <i>"${vcn}"</i><p>(WLEDMM_${i.ver} ${i.rel}.bin)</p><p><em>build ${i.vid}</em></p><table>
|
||||
${urows}
|
||||
${urows===""?'':'<tr><td colspan=2><hr style="height:1px;border-width:0;color:SeaGreen;background-color:Seagreen"></td></tr>'}
|
||||
@@ -690,24 +691,22 @@ ${inforow("Build",i.vid)}
|
||||
${inforow("Estimated current",pwru)}
|
||||
${inforow("Average FPS",i.leds.fps)}
|
||||
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
|
||||
${inforow("MAC address",i.mac)}
|
||||
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
||||
<!-- WLEDMM begin-->
|
||||
<tr><td colspan=2><hr style="height:2px;border-width:0;color:SeaGreen;background-color:SeaGreen"></td></tr>
|
||||
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB, " +Math.round(i.fs.u*100/i.fs.t) + "%")}
|
||||
${theap>0?inforow("Heap ☾",((i.totalheap-i.freeheap)/1000).toFixed(0)+"/"+theap.toFixed(0)+" kB",", "+Math.round((i.totalheap-i.freeheap)/(10*theap))+"%"):inforow("Free heap",heap," kB")} <!--WLEDMM different for 8266-->
|
||||
${i.minfreeheap?inforow("Max used heap ☾",((i.totalheap-i.minfreeheap)/1000).toFixed(0)+" kB",", "+Math.round((i.totalheap-i.minfreeheap)/(10*theap))+"%"):""}
|
||||
${i.psram?inforow("PSRAM ☾",((i.tpram-i.psram)/1024).toFixed(0)+"/"+(i.tpram/1024).toFixed(0)+" kB",", "+((i.tpram-i.psram)*100.0/i.tpram).toFixed(1)+"%"):""}
|
||||
${i.psusedram?inforow("Max used PSRAM ☾",((i.tpram-i.psusedram)/1024).toFixed(0)+" kB",", "+((i.tpram-i.psusedram)*100.0/i.tpram).toFixed(1)+"%"):""}
|
||||
${i.freestack?inforow("Free stack ☾",(i.freestack/1000).toFixed(3)," kB"):""} <!--WLEDMM-->
|
||||
<tr><td colspan=2><hr style="height:1px;border-width:0;color:SeaGreen;background-color:SeaGreen"></td></tr>
|
||||
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
|
||||
${theap>0?inforow("Heap ☾",((i.totalheap-i.freeheap)/1000).toFixed(0)+"/"+theap.toFixed(0)+" kB"," ("+Math.round((i.totalheap-i.freeheap)/(10*theap))+"%)"):""}
|
||||
${i.minfreeheap?inforow("Max used heap ☾",((i.totalheap-i.minfreeheap)/1000).toFixed(1)+" kB"," ("+Math.round((i.totalheap-i.minfreeheap)/(10*theap))+"%)"):""}
|
||||
${inforow("Free heap",heap," kB")}
|
||||
${i.freestack?inforow("Free stack ☾",(i.freestack/1024).toFixed(3)," kB"):""} <!--WLEDMM-->
|
||||
${inforow("Flash Size ☾",flashsize," kB")} <!--WLEDMM and Athom-->
|
||||
${i.tpram?inforow("PSRAM ☾",(i.tpram/1024).toFixed(1)," kB"):""}
|
||||
${i.psram?((i.tpram-i.psram)>16383?inforow("Used PSRAM ☾",((i.tpram-i.psram)/1024).toFixed(1)," kB"):inforow("Used PSRAM ☾",(i.tpram-i.psram)," B")):""}
|
||||
${i.psusedram?((i.tpram-i.psusedram)>16383?inforow("Max used PSRAM ☾",((i.tpram-i.psusedram)/1024).toFixed(1)," kB"):inforow("Max used PSRAM ☾",(i.tpram-i.psusedram)," B")):""}
|
||||
${i.psram?inforow("Free PSRAM",(i.psram/1024).toFixed(1)," kB"):""}
|
||||
${inforow("MAC address",i.mac)}
|
||||
${i.tpram?inforow("PSRAM " + (i.psrmode?"("+i.psrmode+" mode) ":"") + " ☾",(i.tpram/1024/1024).toFixed(0)," MB"):""}
|
||||
${i.e32flash?inforow("Flash mode "+i.e32flashmode+i.e32flashtext + " ☾",i.e32flash+" MB, "+i.e32flashspeed," Mhz"):""}
|
||||
${i.e32model?inforow(i.e32model + " ☾",i.e32cores +" core(s),"," "+i.e32speed+" Mhz"):""}
|
||||
${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
|
||||
<tr><td colspan=2><hr style="height:1px;border-width:0;color:SeaGreen;background-color:SeaGreen"></td></tr>
|
||||
${i.e32model?inforow(i.e32model + " ☾",i.e32cores +" core(s)"," "+i.e32speed+" Mhz"):""}
|
||||
${i.e32flash?inforow("Flash "+i.e32flash+"MB"+" mode "+i.e32flashmode+i.e32flashtext + " ☾",i.e32flashspeed," Mhz"):""}
|
||||
${i.e32code?inforow("Last ESP Restart ☾",i.e32code+" "+i.e32text):""}
|
||||
${i.e32core0code?inforow("Core0 rst reason ☾",i.e32core0code, " "+i.e32core0text):""}
|
||||
${i.e32core1code?inforow("Core1 rst reason ☾",i.e32core1code, " "+i.e32core1text):""}
|
||||
@@ -1976,6 +1975,9 @@ function readState(s,command=false)
|
||||
case 35:
|
||||
errstr = "Low Memory (WS data).";
|
||||
break;
|
||||
case 36:
|
||||
errstr = "Low Memory (oappend buffer).";
|
||||
break;
|
||||
}
|
||||
showToast('Error ' + s.error + ": " + errstr, true);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "wled.h"
|
||||
|
||||
#ifdef WLED_ENABLE_DMX_INPUT
|
||||
#pragma message "DMX physical input driver enabled"
|
||||
|
||||
#ifdef ESP8266
|
||||
#error DMX input is only supported on ESP32
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
#pragma message "DMX network output enabled"
|
||||
|
||||
// WLEDMM: seems that DMX output triggers watchdog resets when compiling for IDF 4.4.x
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
|
||||
@@ -93,6 +93,7 @@ bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest
|
||||
bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest);
|
||||
void updateFSInfo();
|
||||
void closeFile();
|
||||
void invalidateFileNameCache(); // WLEDMM call when new files were uploaded
|
||||
|
||||
//hue.cpp
|
||||
void handleHue();
|
||||
|
||||
115
wled00/file.cpp
115
wled00/file.cpp
@@ -35,6 +35,14 @@ static File f; // don't export to other cpp files
|
||||
|
||||
//wrapper to find out how long closing takes
|
||||
void closeFile() {
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// WLEDMM: file.close() triggers flash writing. While flash is writing, the NPB RMT driver cannot fill its buffer which may create glitches.
|
||||
unsigned long t_wait = millis();
|
||||
while(strip.isUpdating() && (millis() - t_wait < 72)) delay(1); // WLEDMM try to catch a moment when strip is idle
|
||||
while(strip.isUpdating() && (millis() - t_wait < 96)) delay(0); // try harder
|
||||
//if (strip.isUpdating()) USER_PRINTLN("closeFile: strip still updating.");
|
||||
delay(2); // might help
|
||||
#endif
|
||||
#ifdef WLED_DEBUG_FS
|
||||
DEBUGFS_PRINT(F("Close -> "));
|
||||
uint32_t s = millis();
|
||||
@@ -399,19 +407,122 @@ static String getContentType(AsyncWebServerRequest* request, String filename){
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
#if defined(BOARD_HAS_PSRAM) && (defined(WLED_USE_PSRAM) || defined(WLED_USE_PSRAM_JSON))
|
||||
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssistant polls WLED
|
||||
// original idea by @akaricchi (https://github.com/Akaricchi)
|
||||
// returns a pointer to the PSRAM buffer, updates size parameter
|
||||
static const uint8_t *getPresetCache(size_t &size) {
|
||||
static unsigned long presetsCachedTime = 0;
|
||||
static uint8_t *presetsCached = nullptr;
|
||||
static size_t presetsCachedSize = 0;
|
||||
static byte presetsCachedValidate = 0;
|
||||
|
||||
if (!psramFound()) {
|
||||
size = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//if (presetsModifiedTime != presetsCachedTime) DEBUG_PRINTLN(F("getPresetCache(): presetsModifiedTime changed."));
|
||||
//if (presetsCachedValidate != cacheInvalidate) DEBUG_PRINTLN(F("getPresetCache(): cacheInvalidate changed."));
|
||||
|
||||
if ((presetsModifiedTime != presetsCachedTime) || (presetsCachedValidate != cacheInvalidate)) {
|
||||
if (presetsCached) {
|
||||
free(presetsCached);
|
||||
presetsCached = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!presetsCached) {
|
||||
File file = WLED_FS.open("/presets.json", "r");
|
||||
if (file) {
|
||||
presetsCachedTime = presetsModifiedTime;
|
||||
presetsCachedValidate = cacheInvalidate;
|
||||
presetsCachedSize = 0;
|
||||
presetsCached = (uint8_t*)ps_malloc(file.size() + 1);
|
||||
if (presetsCached) {
|
||||
presetsCachedSize = file.size();
|
||||
file.read(presetsCached, presetsCachedSize);
|
||||
presetsCached[presetsCachedSize] = 0;
|
||||
file.close();
|
||||
//USER_PRINTLN(F("getPresetCache(): /presets.json cached in PSRAM."));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//USER_PRINTLN(F("getPresetCache(): /presets.json served from PSRAM."));
|
||||
}
|
||||
|
||||
size = presetsCachedSize;
|
||||
return presetsCached;
|
||||
}
|
||||
#endif
|
||||
|
||||
// WLEDMM
|
||||
static bool haveLedmapFile = true;
|
||||
static bool haveIndexFile = true;
|
||||
static bool haveSkinFile = true;
|
||||
static bool haveICOFile = true;
|
||||
static bool haveCpalFile = true;
|
||||
void invalidateFileNameCache() { // reset "file not found" cache
|
||||
haveLedmapFile = true;
|
||||
haveIndexFile = true;
|
||||
haveSkinFile = true;
|
||||
haveICOFile = true;
|
||||
haveCpalFile = true;
|
||||
|
||||
#if defined(BOARD_HAS_PSRAM) && (defined(WLED_USE_PSRAM) || defined(WLED_USE_PSRAM_JSON))
|
||||
// WLEDMM hack to clear presets.json cache
|
||||
size_t dummy;
|
||||
unsigned long realpresetsTime = presetsModifiedTime;
|
||||
presetsModifiedTime = toki.second(); // pretend we have changes
|
||||
(void) getPresetCache(dummy); // clear presets.json cache
|
||||
presetsModifiedTime = realpresetsTime; // restore correct value
|
||||
#endif
|
||||
//USER_PRINTLN("WS FileRead cache cleared");
|
||||
}
|
||||
|
||||
bool handleFileRead(AsyncWebServerRequest* request, String path){
|
||||
DEBUG_PRINTLN("WS FileRead: " + path);
|
||||
if(path.endsWith("/")) path += "index.htm";
|
||||
if(path.indexOf("sec") > -1) return false;
|
||||
|
||||
// WLEDMM shortcuts
|
||||
if ((haveLedmapFile == false) && path.equals("/ledmap.json")) return false;
|
||||
if ((haveIndexFile == false) && path.equals("/index.htm")) return false;
|
||||
if ((haveSkinFile == false) && path.equals("/skin.css")) return false;
|
||||
if ((haveICOFile == false) && path.equals("/favicon.ico")) return false;
|
||||
if ((haveCpalFile == false) && path.equals("/cpal.htm")) return false;
|
||||
// WLEDMM toDO: add file caching (PSRAM) for /presets.json an /cfg.json
|
||||
|
||||
String contentType = getContentType(request, path);
|
||||
/*String pathWithGz = path + ".gz";
|
||||
if(WLED_FS.exists(pathWithGz)){
|
||||
request->send(WLED_FS, pathWithGz, contentType);
|
||||
return true;
|
||||
}*/
|
||||
if(WLED_FS.exists(path)) {
|
||||
request->send(WLED_FS, path, contentType);
|
||||
|
||||
#if defined(BOARD_HAS_PSRAM) && (defined(WLED_USE_PSRAM) || defined(WLED_USE_PSRAM_JSON))
|
||||
if (path.endsWith("/presets.json")) {
|
||||
size_t psize;
|
||||
const uint8_t *presets = getPresetCache(psize);
|
||||
if (presets) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, contentType, presets, psize);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(WLED_FS.exists(path) || WLED_FS.exists(path + ".gz")) {
|
||||
request->send(WLED_FS, path, String(), request->hasArg(F("download")));
|
||||
return true;
|
||||
}
|
||||
//USER_PRINTLN("WS FileRead failed: " + path + " (" + contentType + ")");
|
||||
|
||||
// WLEDMM cache "file not found" results (reduces LED flickering during UI activities)
|
||||
if (path.equals("/ledmap.json")) haveLedmapFile = false;
|
||||
if (path.equals("/index.htm")) haveIndexFile = false;
|
||||
if (path.equals("/skin.css")) haveSkinFile = false;
|
||||
if (path.equals("/favicon.ico")) haveICOFile = false;
|
||||
if (path.equals("/cpal.htm")) haveCpalFile = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -205,4 +205,5 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
|
||||
#else
|
||||
void handleHue(){}
|
||||
void reconnectHue(){}
|
||||
#pragma message "Philips HUE bridge interface disabled"
|
||||
#endif
|
||||
|
||||
@@ -210,7 +210,7 @@ void sendImprovInfoResponse() {
|
||||
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||
char vString[32];
|
||||
snprintf_P(vString, sizeof(vString)-1, PSTR("0.14.1-b30.37/%i"),VERSION);
|
||||
snprintf_P(vString, sizeof(vString)-1, PSTR("0.14.1-b31.38/%i"),VERSION);
|
||||
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
||||
|
||||
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#if defined(WLED_DISABLE_INFRARED)
|
||||
#pragma message "IR remote support disabled"
|
||||
void handleIR(){}
|
||||
#else
|
||||
|
||||
|
||||
@@ -597,6 +597,8 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
}
|
||||
|
||||
doAdvancePlaylist = root[F("np")] | doAdvancePlaylist; //advances to next preset in playlist when true
|
||||
|
||||
stateUpdated(callMode);
|
||||
if (presetToRestore) currentPreset = presetToRestore;
|
||||
|
||||
@@ -1032,6 +1034,14 @@ void serializeInfo(JsonObject root)
|
||||
if(ESP.getChipCores() > 1) // WLEDMM
|
||||
root[F("resetReason1")] = (int)rtc_get_reset_reason(1);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
unsigned long t_wait = millis();
|
||||
while(strip.isUpdating() && (millis() - t_wait < 125)) delay(1); // WLEDMM try to catch a moment when strip is idle
|
||||
while(strip.isUpdating() && (millis() - t_wait < 160)) yield(); // try harder
|
||||
//if (strip.isUpdating()) USER_PRINTLN("serializeInfo: strip still updating.");
|
||||
#endif
|
||||
|
||||
root[F("lwip")] = 0; //deprecated
|
||||
root[F("totalheap")] = ESP.getHeapSize(); //WLEDMM
|
||||
#else
|
||||
@@ -1056,6 +1066,13 @@ void serializeInfo(JsonObject root)
|
||||
root[F("tpram")] = ESP.getPsramSize(); //WLEDMM
|
||||
root[F("psram")] = ESP.getFreePsram();
|
||||
root[F("psusedram")] = ESP.getMinFreePsram();
|
||||
#if CONFIG_ESP32S3_SPIRAM_SUPPORT // WLEDMM -S3 has "qspi" or "opi" PSRAM mode
|
||||
#if CONFIG_SPIRAM_MODE_OCT
|
||||
root[F("psrmode")] = F("🚀 OPI");
|
||||
#elif CONFIG_SPIRAM_MODE_QUAD
|
||||
root[F("psrmode")] = F("qspi 🛻");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// for testing
|
||||
@@ -1521,6 +1538,8 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
#ifdef WLED_ENABLE_JSONLIVE
|
||||
#define MAX_LIVE_LEDS 180
|
||||
|
||||
#warning "JSON Live enabled"
|
||||
|
||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||
{
|
||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||
|
||||
@@ -68,4 +68,6 @@ void parseLxJson(int lxValue, byte segId, bool secondary)
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#pragma message "Loxone support disabled"
|
||||
#endif
|
||||
|
||||
@@ -195,4 +195,6 @@ bool initMqtt()
|
||||
mqtt->connect();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
#pragma message "MQTT disabled"
|
||||
#endif
|
||||
|
||||
@@ -26,4 +26,6 @@ size_t NetworkDebugPrinter::write(const uint8_t *buf, size_t size) {
|
||||
|
||||
NetworkDebugPrinter NetDebug;
|
||||
|
||||
#else
|
||||
#pragma message "Net debug disabled"
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
|
||||
#ifdef WLED_USE_ETHERNET
|
||||
#pragma message "Ethernet support enabled"
|
||||
|
||||
// The following six pins are neither configurable nor
|
||||
// can they be re-assigned through IOMUX / GPIO matrix.
|
||||
// See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit-v1.1.html#ip101gri-phy-interface
|
||||
|
||||
@@ -137,7 +137,7 @@ void handlePlaylist() {
|
||||
return; // but don't progress to next extry, and don't shuffle
|
||||
}
|
||||
|
||||
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
||||
if (millis() - presetCycledTime > (100 * playlistEntryDur) || doAdvancePlaylist) {
|
||||
presetCycledTime = millis();
|
||||
if (bri == 0 || nightlightActive) return;
|
||||
|
||||
@@ -159,6 +159,7 @@ void handlePlaylist() {
|
||||
transitionDelayTemp = playlistEntries[playlistIndex].tr * 100;
|
||||
playlistEntryDur = playlistEntries[playlistIndex].dur;
|
||||
applyPreset(playlistEntries[playlistIndex].preset);
|
||||
doAdvancePlaylist = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
#define WIZMOTE_BUTTON_BRIGHT_UP 9
|
||||
#define WIZMOTE_BUTTON_BRIGHT_DOWN 8
|
||||
|
||||
#define WIZ_SMART_BUTTON_ON 100
|
||||
#define WIZ_SMART_BUTTON_OFF 101
|
||||
#define WIZ_SMART_BUTTON_BRIGHT_UP 102
|
||||
#define WIZ_SMART_BUTTON_BRIGHT_DOWN 103
|
||||
|
||||
#ifdef WLED_DISABLE_ESPNOW
|
||||
void handleRemote(){}
|
||||
#else
|
||||
#pragma message "ESP-NOW remote driver enabled"
|
||||
|
||||
#if !defined(ARDUINO_ARCH_ESP32) && !defined(ESP_OK)
|
||||
#define ESP_OK 0 // add missing constant for stupid esp8266
|
||||
@@ -148,7 +154,6 @@ void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
USER_PRINT(F("\nIncoming ESP Now Packet["));
|
||||
USER_PRINT(cur_seq);
|
||||
USER_PRINT(F("] from sender["));
|
||||
@@ -165,8 +170,11 @@ void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
|
||||
case WIZMOTE_BUTTON_NIGHT : activateNightMode(); stateUpdated(CALL_MODE_BUTTON); break;
|
||||
case WIZMOTE_BUTTON_BRIGHT_UP : brightnessUp(); stateUpdated(CALL_MODE_BUTTON); break;
|
||||
case WIZMOTE_BUTTON_BRIGHT_DOWN : brightnessDown(); stateUpdated(CALL_MODE_BUTTON); break;
|
||||
case WIZ_SMART_BUTTON_ON : setOn(); break;
|
||||
case WIZ_SMART_BUTTON_OFF : setOff(); break;
|
||||
case WIZ_SMART_BUTTON_BRIGHT_UP : brightnessUp(); break;
|
||||
case WIZ_SMART_BUTTON_BRIGHT_DOWN : brightnessDown(); break;
|
||||
default: break;
|
||||
|
||||
}
|
||||
|
||||
last_seq = cur_seq;
|
||||
|
||||
@@ -922,6 +922,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
applyPreset(presetCycCurr);
|
||||
}
|
||||
|
||||
pos = req.indexOf(F("NP")); //advances to next preset in a playlist
|
||||
if (pos > 0) doAdvancePlaylist = true;
|
||||
|
||||
//set brightness
|
||||
updateVal(req.c_str(), "&A=", &bri);
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ bool oappend(const char* txt)
|
||||
USER_PRINTF("%2u bytes \t\"", len /*1 + olen + len - SETTINGS_STACK_BUF_SIZE*/);
|
||||
USER_PRINT(txt);
|
||||
USER_PRINTLN(F("\""));
|
||||
errorFlag = ERR_LOW_AJAX_MEM;
|
||||
}
|
||||
return false; // buffer full
|
||||
}
|
||||
@@ -433,6 +434,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
||||
static float volumeSmth;
|
||||
static uint16_t volumeRaw;
|
||||
static float my_magnitude;
|
||||
static uint16_t zeroCrossingCount = 0; // number of zero crossings in the current batch of 512 samples
|
||||
|
||||
//arrays
|
||||
uint8_t *fftResult;
|
||||
@@ -447,7 +449,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
||||
// NOTE!!!
|
||||
// This may change as AudioReactive usermod may change
|
||||
um_data = new um_data_t;
|
||||
um_data->u_size = 11;
|
||||
um_data->u_size = 12;
|
||||
um_data->u_type = new um_types_t[um_data->u_size];
|
||||
um_data->u_data = new void*[um_data->u_size];
|
||||
um_data->u_data[0] = &volumeSmth;
|
||||
@@ -461,6 +463,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
||||
um_data->u_data[8] = &FFT_MajorPeak; // dummy (FFT Peak smoothed)
|
||||
um_data->u_data[9] = &volumeSmth; // dummy (soundPressure)
|
||||
um_data->u_data[10] = &volumeSmth; // dummy (agcSensitivity)
|
||||
um_data->u_data[11] = &zeroCrossingCount;
|
||||
} else {
|
||||
// get arrays from um_data
|
||||
fftResult = (uint8_t*)um_data->u_data[2];
|
||||
@@ -527,6 +530,7 @@ um_data_t* simulateSound(uint8_t simulationId)
|
||||
volumeRaw = volumeSmth;
|
||||
my_magnitude = 10000.0f / 8.0f; //no idea if 10000 is a good value for FFT_Magnitude ???
|
||||
if (volumeSmth < 1 ) my_magnitude = 0.001f; // noise gate closed - mute
|
||||
zeroCrossingCount = floorf(FFT_MajorPeak / 36.0f); // 9Khz max frequency => 255 zero crossings
|
||||
|
||||
return um_data;
|
||||
}
|
||||
|
||||
@@ -611,10 +611,12 @@ void WLED::setup()
|
||||
DEBUG_PRINTLN(F("PSRAM not used."));
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARDUINO_ESP32_PICO)
|
||||
// special handling for PICO-D4: gpio16+17 are in use for onboard SPI FLASH (not PSRAM)
|
||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (strncmp("ESP32-PICO", ESP.getChipModel(), 10) == 0) { // WLEDMM detect pico board at runtime
|
||||
// special handling for PICO-D4: gpio16+17 are in use for onboard SPI FLASH (not PSRAM)
|
||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
||||
}
|
||||
#endif
|
||||
|
||||
//DEBUG_PRINT(F("LEDs inited. heap usage ~"));
|
||||
@@ -681,7 +683,7 @@ pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), Pin
|
||||
updateFSInfo();
|
||||
|
||||
USER_PRINT(F("done Mounting FS; "));
|
||||
USER_PRINT(((fsBytesTotal-fsBytesUsed)/1024)); USER_PRINTLN(F(" kB free."));
|
||||
USER_PRINT(((fsBytesTotal-fsBytesUsed)/1024)); USER_PRINTLN(F(" kB free.\n"));
|
||||
|
||||
// generate module IDs must be done before AP setup
|
||||
escapedMac = WiFi.macAddress();
|
||||
@@ -705,7 +707,7 @@ pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), Pin
|
||||
beginStrip();
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
|
||||
USER_PRINTLN(F("Usermods setup ..."));
|
||||
USER_PRINTLN(F("\nUsermods setup ..."));
|
||||
userSetup();
|
||||
usermods.setup();
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
@@ -721,7 +723,7 @@ pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), Pin
|
||||
//Serial RX (Adalight, Improv, Serial JSON) only possible if GPIO3 unused
|
||||
//Serial TX (Debug, Improv, Serial JSON) only possible if GPIO1 unused
|
||||
if (!pinManager.isPinAllocated(hardwareRX) && !pinManager.isPinAllocated(hardwareTX)) {
|
||||
if (Serial) Serial.println(F("Ada"));
|
||||
if (Serial) Serial.println(F("\nAda"));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -852,7 +854,7 @@ pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), Pin
|
||||
// repeat Ada prompt
|
||||
#ifdef WLED_ENABLE_ADALIGHT
|
||||
if (!pinManager.isPinAllocated(hardwareRX) && !pinManager.isPinAllocated(hardwareTX)) {
|
||||
if (Serial) Serial.println(F("Ada"));
|
||||
if (Serial) Serial.println(F("\nAda"));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1031,6 +1033,12 @@ bool WLED::initEthernet()
|
||||
|
||||
void WLED::initConnection()
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
unsigned long t_wait = millis();
|
||||
while(strip.isUpdating() && (millis() - t_wait < 86)) delay(1); // WLEDMM try to catch a moment when strip is idle
|
||||
//if (strip.isUpdating()) USER_PRINTLN("WLED::initConnection: strip still updating.");
|
||||
#endif
|
||||
|
||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||
ws.onEvent(wsEvent);
|
||||
#endif
|
||||
@@ -1208,7 +1216,7 @@ void WLED::handleConnection()
|
||||
static unsigned retryCount = 0; // WLEDMM
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// reconnect WiFi to clear stale allocations if heap gets too low
|
||||
if (now - heapTime > 5000) { // WLEDMM: updated with better logic for small heap available by block, not total.
|
||||
if ((!strip.isUpdating()) && (now - heapTime > 5000)) { // WLEDMM: updated with better logic for small heap available by block, not total. // WLEDMM trying to use a moment when the strip is idle
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
uint32_t heap = ESP.getFreeHeap(); // WLEDMM works better on -S2
|
||||
#else
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2404201
|
||||
#define VERSION 2405040
|
||||
|
||||
// WLEDMM - you can check for this define in usermods, to only enabled WLEDMM specific code in the "right" fork. Its not defined in AC WLED.
|
||||
#define _MoonModules_WLED_
|
||||
@@ -184,6 +184,12 @@
|
||||
// There is a code that will still not use PSRAM though:
|
||||
// AsyncJsonResponse is a derived class that implements DynamicJsonDocument (AsyncJson-v6.h)
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && (defined(WLED_USE_PSRAM) || defined(WLED_USE_PSRAM_JSON)) // WLEDMM
|
||||
// WLEDMM the JSON_TO_PSRAM feature works, so use it by default
|
||||
#undef WLED_USE_PSRAM_JSON
|
||||
#define WLED_USE_PSRAM_JSON
|
||||
#undef ALL_JSON_TO_PSRAM
|
||||
#define ALL_JSON_TO_PSRAM
|
||||
|
||||
struct PSRAM_Allocator {
|
||||
void* allocate(size_t size) {
|
||||
if (psramFound()) return ps_malloc(size); // use PSRAM if it exists
|
||||
@@ -533,7 +539,8 @@ WLED_GLOBAL byte macroDoublePress[WLED_MAX_BUTTONS] _INIT({0});
|
||||
WLED_GLOBAL bool otaLock _INIT(false); // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks
|
||||
WLED_GLOBAL bool wifiLock _INIT(false); // prevents access to WiFi settings when OTA lock is enabled
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WLED_GLOBAL bool aOtaEnabled _INIT(true); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on
|
||||
// WLEDMM disabled as default - arduinoOTA is a relic, only useful when using ArduinoIDE
|
||||
WLED_GLOBAL bool aOtaEnabled _INIT(false); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on
|
||||
#else
|
||||
WLED_GLOBAL bool aOtaEnabled _INIT(false); // WLEDMM: start with OTA disabled, as it seems to be unstable on 8266
|
||||
#endif
|
||||
@@ -646,6 +653,7 @@ WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255,
|
||||
WLED_GLOBAL byte timerMonth[] _INIT_N(({28,28,28,28,28,28,28,28}));
|
||||
WLED_GLOBAL byte timerDay[] _INIT_N(({1,1,1,1,1,1,1,1}));
|
||||
WLED_GLOBAL byte timerDayEnd[] _INIT_N(({31,31,31,31,31,31,31,31}));
|
||||
WLED_GLOBAL bool doAdvancePlaylist _INIT(false);
|
||||
|
||||
//improv
|
||||
WLED_GLOBAL byte improvActive _INIT(0); //0: no improv packet received, 1: improv active, 2: provisioning
|
||||
@@ -802,7 +810,7 @@ WLED_GLOBAL int8_t spi_sclk _INIT(HW_PIN_CLOCKSPI);
|
||||
WLED_GLOBAL PSRAMDynamicJsonDocument doc;
|
||||
#else
|
||||
WLED_GLOBAL PSRAMDynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||
#warning experimental - trying to always use dynamic JSON
|
||||
//#warning trying to always use dynamic JSON in PSRAM
|
||||
#endif
|
||||
#else
|
||||
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> doc;
|
||||
|
||||
@@ -229,6 +229,8 @@ void handleSerial()
|
||||
//#ifdef WLED_DEBUG
|
||||
if ((millis() - startTime) > SERIAL_MAXTIME_MILLIS) { USER_PRINTLN(F("handleSerial(): need a break after >100ms of activity.")); }
|
||||
//#endif
|
||||
#else
|
||||
#pragma message "Serial protocols (AdaLight, Serial JSON, Serial LED driver, improv) disabled"
|
||||
#endif
|
||||
|
||||
// If Continuous Serial Streaming is enabled, send new LED data as bytes
|
||||
|
||||
@@ -58,6 +58,7 @@ void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t
|
||||
request->_tempFile.close();
|
||||
USER_PRINT(F("File uploaded: ")); // WLEDMM
|
||||
USER_PRINTLN(filename); // WLEDMM
|
||||
invalidateFileNameCache(); // WLEDMM
|
||||
if (filename.equalsIgnoreCase("/cfg.json") || filename.equalsIgnoreCase("cfg.json")) { // WLEDMM
|
||||
request->send(200, "text/plain", F("Configuration restore successful.\nRebooting..."));
|
||||
doReboot = true;
|
||||
|
||||
@@ -313,4 +313,5 @@ void handleWs()
|
||||
#else
|
||||
void handleWs() {}
|
||||
void sendDataWs(AsyncWebSocketClient * client) {}
|
||||
#pragma message "WebSockets disabled - no live preview."
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user