Merge branch 'MoonModules:mdev' into Strip_Level_Color_Adjust

This commit is contained in:
Troy
2024-05-07 09:33:46 -04:00
committed by GitHub
39 changed files with 641 additions and 194 deletions

View File

@@ -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();

View File

@@ -139,4 +139,5 @@ void onAlexaChange(EspalexaDevice* dev)
#else
void alexaInit(){}
void handleAlexa(){}
#pragma message "Alexa interface disabled"
#endif

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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

View File

@@ -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} &nbsp;<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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -7,6 +7,7 @@
*/
#if defined(WLED_DISABLE_INFRARED)
#pragma message "IR remote support disabled"
void handleIR(){}
#else

View File

@@ -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

View File

@@ -68,4 +68,6 @@ void parseLxJson(int lxValue, byte segId, bool secondary)
}
}
#else
#pragma message "Loxone support disabled"
#endif

View File

@@ -195,4 +195,6 @@ bool initMqtt()
mqtt->connect();
return true;
}
#else
#pragma message "MQTT disabled"
#endif

View File

@@ -26,4 +26,6 @@ size_t NetworkDebugPrinter::write(const uint8_t *buf, size_t size) {
NetworkDebugPrinter NetDebug;
#else
#pragma message "Net debug disabled"
#endif

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -313,4 +313,5 @@ void handleWs()
#else
void handleWs() {}
void sendDataWs(AsyncWebSocketClient * client) {}
#pragma message "WebSockets disabled - no live preview."
#endif