diff --git a/platformio.ini b/platformio.ini
index a9563b8e..10822e36 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -819,7 +819,7 @@ build_flags = ${common.build_flags_esp8266}
; RAM: [====== ] 59.3% (used 48608 bytes from 81920 bytes)
; Flash: [======== ] 77.0% (used 804176 bytes from 1044464 bytes)
-[env:esp8266_4MB_max] ;WLEDMM: WIP
+[env:esp8266_4MB_max]
extends = env:d1_mini
upload_speed = 460800 ;115200
board_build.f_cpu = 160000000L ;; we want 160Mhz (default = 80Mhz)
@@ -829,26 +829,56 @@ build_flags = ${common.build_flags_esp8266}
-D WLED_DISABLE_ALEXA
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_HUESYNC
+ -D WLED_DISABLE_LOXONE
; -D USERMOD_AUDIOREACTIVE
; -D USERMOD_CUSTOMEFFECTS ; to be done
; -UWLED_USE_MY_CONFIG
-D USERMOD_PIRSWITCH
-D USERMOD_DALLASTEMPERATURE ;; disabled because it hangs during usermod setup on -S3 (autodetect broken?)
-D USERMOD_MULTI_RELAY
- ; -D USE_ALT_DISPLAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI
- ; -D USERMOD_FOUR_LINE_DISPLAY
+ -D USE_ALT_DISPLAY ; new versions of USERMOD_FOUR_LINE_DISPLAY and USERMOD_ROTARY_ENCODER_UI
+ -D USERMOD_FOUR_LINE_DISPLAY
-D USERMOD_MPU6050_IMU ; gyro/accelero for USERMOD_GAMES (ONLY WORKS IF USERMOD_FOUR_LINE_DISPLAY NOT INCLUDED - I2C SHARING BUG)
-D USERMOD_GAMES ; WLEDMM usermod
- -D WLED_DEBUG
+ ; -D WLED_DEBUG
; monitor_filters = esp8266_exception_decoder
lib_deps = ${esp8266.lib_deps}
OneWire@~2.3.5 ; used for USERMOD_FOUR_LINE_DISPLAY and USERMOD_DALLASTEMPERATURE
- ; olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY
- ; olikraus/U8g2@ ^2.34.5 ; used for USERMOD_FOUR_LINE_DISPLAY -> need newer version with bugfixes for arduino-esp32 v2.0.4 (Wire inititialization)
+ olikraus/U8g2 @ ^2.28.8 ; used for USERMOD_FOUR_LINE_DISPLAY
ElectronicCats/MPU6050 @ 0.6.0 ; used for USERMOD_MPU6050_IMU
; RAM: [====== ] 61.5% (used 50344 bytes from 81920 bytes)
; Flash: [======== ] 81.8% (used 854444 bytes from 1044464 bytes)
+; Blaz env (for reference purposes)
+[env:d1_mini_temp]
+extends = env:d1_mini
+board_build.filesystem = littlefs
+build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266
+ -D WLED_DISABLE_ALEXA
+ -D WLED_DISABLE_BLYNK
+ -D WLED_DISABLE_HUESYNC
+ -D WLED_DISABLE_LOXONE
+ -D WLED_DISABLE_AUDIO ;WLEDMM not used anywhere
+ -D WLED_ENABLE_SIMPLE_UI
+ -D USERMOD_FOUR_LINE_DISPLAY
+ -D USE_ALT_DISPlAY
+ -D USERMOD_DALLASTEMPERATURE
+ -D TEMPERATURE_PIN=13 # (D7)
+ -D LEDPIN=2 # (D4)
+ -D RLYPIN=12 # (D6)
+ -D BTNPIN=0 # (D3)
+ -D IRPIN=14 # (D5)
+ -D USERMOD_MULTI_RELAY
+ -D MULTI_RELAY_MAX_RELAYS=2
+ -D USERMOD_PIRSWITCH
+ -D PIR_SENSOR_PIN=16
+ -D PIR_SENSOR_OFF_SEC=60
+ -UWLED_USE_MY_CONFIG
+lib_deps = ${esp8266.lib_deps}
+ paulstoffregen/OneWire@~2.3.7 ;WLEDMM Softhack, we need this as well (instead of 2.3.5)?
+ olikraus/U8g2 # @~2.33.15
+ Wire ; WLEDMM needed?
+
[env:esp8266pro_16MB_min]
extends = env:d1_mini
board = d1_mini_pro ;; "D1 mini pro": ESP8266EX, 160MHz, 80KB RAM, 16MB Flash
@@ -1083,6 +1113,7 @@ build_flags = ${common.build_flags} ${esp32.build_flagsV4} ${esp32c3.build_flags
; -DARDUINO_USB_CDC_ON_BOOT=1 ;; enable CDC USB -> needed for debugging over serial USB
-DARDUINO_USB_CDC_ON_BOOT=0 ;; disable CDC USB
-D SERVERNAME='"WLED-C3"'
+ ;-D WLEDMM_WIFI_POWERON_HACK ;; use this _only_ if your device is not able to make a WiFI connection!
;-D WLED_DISABLE_INFRARED ;; save flash space
;-D WLED_DISABLE_ALEXA ;; save flash space
-D LEDPIN=8 ;; onboard neopixel 5x5 Matrix. Attach your own LEDs to GPIO 20
@@ -1116,6 +1147,8 @@ build_flags = ${esp32_4MB_max_base.build_flags}
-D HW_PIN_SCL=22 -D HW_PIN_SDA=21
-D HW_PIN_CLOCKSPI=-1 -D HW_PIN_MOSISPI=-1 -D HW_PIN_MISOSPI=-1 ; WLEDMM: is now also default but just to show we didn't agree on wemos pins for spi yet
-D ENCODER_DT_PIN=35 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=39 ;WLEDMM spec by @SERG74: use 35 and 39 instead of 18 and 19 (conflicts)
+ -D PIR_SENSOR_PIN=-1
+ -D PWM_PIN=-1
; -D WLED_USE_MY_CONFIG
[wemos_shield_esp32_4MB_all_base]
@@ -1223,6 +1256,7 @@ build_flags = ${esp32_4MB_max_base.build_flags}
-D SR_DMTYPE=1 -D I2S_SDPIN=25 -D I2S_WSPIN=15 -D I2S_CKPIN=14
-D SR_SQUELCH=5 -D SR_GAIN=30 -D SR_FREQ_PROF=5 ; ICS-43434 specific
; -D MCLK_PIN=0
+ -D SR_ENABLE_DEFAULT ;; enable at first start - no need to manually set "enable", then reboot
; -D WLED_USE_MY_CONFIG
; -D WLED_DISABLE_LOXONE
; -D WLED_DISABLE_ALEXA
diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
index 2928c75f..9aede3a8 100644
--- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
+++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h
@@ -4,11 +4,7 @@
#ifndef PIR_SENSOR_PIN
// compatible with QuinLED-Dig-Uno
- #ifdef ARDUINO_ARCH_ESP32
- #define PIR_SENSOR_PIN 23 // Q4
- #else //ESP8266 boards
- #define PIR_SENSOR_PIN 13 // Q4 (D7 on D1 mini)
- #endif
+ #define PIR_SENSOR_PIN -1 //WLEDMM not default 23 // Q4 for esp32 or otherwise 13 // Q4 (D7 on D1 mini)
#endif
#ifndef PIR_SENSOR_OFF_SEC
diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h
index 1c3cf1bc..88719786 100644
--- a/usermods/Temperature/usermod_temperature.h
+++ b/usermods/Temperature/usermod_temperature.h
@@ -29,6 +29,7 @@ class UsermodTemperature : public Usermod {
bool degC = true;
// using parasite power on the sensor
bool parasite = false;
+ int8_t parasitePin = -1;
// how often do we read from sensor?
unsigned long readingInterval = USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL;
// set last reading as "40 sec before boot", so first reading is taken after 20 sec
@@ -53,6 +54,7 @@ class UsermodTemperature : public Usermod {
static const char _enabled[];
static const char _readInterval[];
static const char _parasite[];
+ static const char _parasitePin[];
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float readDallas() {
@@ -94,12 +96,14 @@ class UsermodTemperature : public Usermod {
DEBUG_PRINTLN(F("Requesting temperature."));
oneWire->reset();
oneWire->skip(); // skip ROM
- oneWire->write(0x44,parasite); // request new temperature reading (TODO: parasite would need special handling)
+ oneWire->write(0x44,parasite); // request new temperature reading
+ if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, HIGH); // has to happen within 10us (open MOSFET)
lastTemperaturesRequest = millis();
waitingForConversion = true;
}
void readTemperature() {
+ if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
temperature = readDallas();
lastMeasurement = millis();
waitingForConversion = false;
@@ -175,6 +179,12 @@ class UsermodTemperature : public Usermod {
delay(25); // try to find sensor
}
}
+ if (parasite && pinManager.allocatePin(parasitePin, true, PinOwner::UM_Temperature)) {
+ pinMode(parasitePin, OUTPUT);
+ digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
+ } else {
+ parasitePin = -1;
+ }
} else {
if (temperaturePin >= 0) {
USER_PRINTLN(F("Temperature pin allocation failed."));
@@ -311,10 +321,6 @@ class UsermodTemperature : public Usermod {
// if (!initDone) return; // prevent crash on boot applyPreset()
//}
- void appendConfigData() {
- oappend(SET_F("addHB('Temperature');"));
- }
-
/**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/
@@ -326,6 +332,7 @@ class UsermodTemperature : public Usermod {
top["degC"] = degC; // usermodparam
top[FPSTR(_readInterval)] = readingInterval / 1000;
top[FPSTR(_parasite)] = parasite;
+ top[FPSTR(_parasitePin)] = parasitePin;
DEBUG_PRINTLN(F("Temperature config saved."));
}
@@ -351,6 +358,7 @@ class UsermodTemperature : public Usermod {
readingInterval = top[FPSTR(_readInterval)] | readingInterval/1000;
readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms
parasite = top[FPSTR(_parasite)] | parasite;
+ parasitePin = top[FPSTR(_parasitePin)] | parasitePin;
if (!initDone) {
// first run: reading from cfg.json
@@ -365,12 +373,22 @@ class UsermodTemperature : public Usermod {
delete oneWire;
pinManager.deallocatePin(temperaturePin, PinOwner::UM_Temperature);
temperaturePin = newTemperaturePin;
+ pinManager.deallocatePin(parasitePin, PinOwner::UM_Temperature);
// initialise
setup();
}
}
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
- return !top[FPSTR(_parasite)].isNull();
+ return !top[FPSTR(_parasitePin)].isNull();
+ }
+
+ void appendConfigData()
+ {
+ oappend(SET_F("addHB('Temperature');")); // WLEDMM
+ oappend(SET_F("addInfo('Temperature:parasite-pwr"));
+ oappend(SET_F("',1,'(if no Vcc connected)');")); // 0 is field type, 1 is actual field
+ oappend(SET_F("addInfo('Temperature:parasite-pwr-pin"));
+ oappend(SET_F("',1,'(for external MOSFET)');")); // 0 is field type, 1 is actual field
}
uint16_t getId()
@@ -384,3 +402,4 @@ const char UsermodTemperature::_name[] PROGMEM = "Temperature";
const char UsermodTemperature::_enabled[] PROGMEM = "enabled";
const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
+const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin";
diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h
index 0bba5ffa..182e8d7a 100644
--- a/usermods/audioreactive/audio_reactive.h
+++ b/usermods/audioreactive/audio_reactive.h
@@ -225,17 +225,20 @@ static float FFT_MajorPeak = 1.0f; // FFT: strongest (peak) frequen
static float FFT_Magnitude = 0.0f; // FFT: volume (magnitude) of peak frequency
static uint8_t fftResult[NUM_GEQ_CHANNELS]= {0};// Our calculated freq. channel result table to be used by effects
#if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS)
-static uint64_t fftTime = 0;
-static uint64_t sampleTime = 0;
+static float fftTaskCycle = 0; // avg cycle time for FFT task
+static float fftTime = 0; // avg time for single FFT
+static float sampleTime = 0; // avg (blocked) time for reading I2S samples
#endif
// FFT Task variables (filtering and post-processing)
+static float lastFftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // backup of last FFT channels (before postprocessing)
static float fftCalc[NUM_GEQ_CHANNELS] = {0.0f}; // Try and normalize fftBin values to a max of 4096, so that 4096/16 = 256.
static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calculated frequency channel results, with smoothing (used if dynamics limiter is ON)
#ifdef SR_DEBUG
static float fftResultMax[NUM_GEQ_CHANNELS] = {0.0f}; // A table used for testing to determine how our post-processing is working.
#endif
+#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// audio source parameters and constant
constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz is a standard rate. Physical sample time -> 23ms
//constexpr SRate_t SAMPLE_RATE = 16000; // 16kHz - use if FFTtask takes more than 20ms. Physical sample time -> 32ms
@@ -245,6 +248,16 @@ constexpr SRate_t SAMPLE_RATE = 22050; // Base sample rate in Hz - 22Khz
//#define FFT_MIN_CYCLE 30 // Use with 16Khz sampling
//#define FFT_MIN_CYCLE 23 // minimum time before FFT task is repeated. Use with 20Khz sampling
//#define FFT_MIN_CYCLE 46 // minimum time before FFT task is repeated. Use with 10Khz sampling
+#else
+// slightly lower the sampling rate for -C3, to improve stability
+//constexpr SRate_t SAMPLE_RATE = 20480; // 20Khz; Physical sample time -> 25ms
+//#define FFT_MIN_CYCLE 23 // minimum time before FFT task is repeated.
+constexpr SRate_t SAMPLE_RATE = 18000; // 18Khz; Physical sample time -> 28ms
+#define FFT_MIN_CYCLE 25 // minimum time before FFT task is repeated.
+// try 16Khz in case your device still lags and responds too slowly.
+//constexpr SRate_t SAMPLE_RATE = 16000; // 16Khz -> Physical sample time -> 32ms
+//#define FFT_MIN_CYCLE 30 // minimum time before FFT task is repeated.
+#endif
// FFT Constants
constexpr uint16_t samplesFFT = 512; // Samples in an FFT batch - This value MUST ALWAYS be a power of 2
@@ -308,6 +321,11 @@ static float fftAddAvg(int from, int to) {
}
#endif
+#if defined(CONFIG_IDF_TARGET_ESP32C3)
+constexpr bool skipSecondFFT = true;
+#else
+constexpr bool skipSecondFFT = false;
+#endif
//
// FFT main task
//
@@ -317,6 +335,8 @@ void FFTcode(void * parameter)
// see https://www.freertos.org/vtaskdelayuntil.html
const TickType_t xFrequency = FFT_MIN_CYCLE * portTICK_PERIOD_MS;
+ const TickType_t xFrequencyDouble = FFT_MIN_CYCLE * portTICK_PERIOD_MS * 2;
+ static bool isFirstRun = false;
TickType_t xLastWakeTime = xTaskGetTickCount();
for(;;) {
@@ -325,6 +345,7 @@ void FFTcode(void * parameter)
// Don't run FFT computing code if we're in Receive mode or in realtime mode
if (disableSoundProcessing || (audioSyncEnabled & 0x02)) {
+ isFirstRun = false;
vTaskDelayUntil( &xLastWakeTime, xFrequency); // release CPU, and let I2S fill its buffers
continue;
}
@@ -332,6 +353,15 @@ void FFTcode(void * parameter)
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
uint64_t start = esp_timer_get_time();
bool haveDoneFFT = false; // indicates if second measurement (FFT time) is valid
+
+ static uint64_t lastCycleStart = 0;
+ static uint64_t lastLastTime = 0;
+ if ((lastCycleStart > 0) && (lastCycleStart < start)) { // filter out overflows
+ uint64_t taskTimeInMillis = ((start - lastCycleStart) +5ULL) / 10ULL; // "+5" to ensure proper rounding
+ fftTaskCycle = (((taskTimeInMillis + lastLastTime)/2) *4 + fftTaskCycle*6)/10.0; // smart smooth
+ lastLastTime = taskTimeInMillis;
+ }
+ lastCycleStart = start;
#endif
// get a fresh batch of samples from I2S
@@ -340,12 +370,13 @@ void FFTcode(void * parameter)
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
if (start < esp_timer_get_time()) { // filter out overflows
uint64_t sampleTimeInMillis = (esp_timer_get_time() - start +5ULL) / 10ULL; // "+5" to ensure proper rounding
- sampleTime = (sampleTimeInMillis*3 + sampleTime*7)/10; // smooth
+ sampleTime = (sampleTimeInMillis*3 + sampleTime*7)/10.0; // smooth
}
start = esp_timer_get_time(); // start measuring FFT time
#endif
xLastWakeTime = xTaskGetTickCount(); // update "last unblocked time" for vTaskDelay
+ isFirstRun = !isFirstRun; // toggle throtte
#ifdef MIC_LOGGER
float datMin = 0.0f;
@@ -399,38 +430,41 @@ void FFTcode(void * parameter)
// run FFT (takes 3-5ms on ESP32)
//if (fabsf(sampleAvg) > 0.25f) { // noise gate open
if (fabsf(volumeSmth) > 0.25f) { // noise gate open
+ if ((skipSecondFFT == false) || (isFirstRun == true)) {
+ // run FFT (takes 2-3ms on ESP32, ~12ms on ESP32-S2, ~30ms on -C3)
+ #ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
+ FFT.dcRemoval(); // remove DC offset
+ #if !defined(FFT_PREFER_EXACT_PEAKS)
+ FFT.windowing( FFTWindow::Flat_top, FFTDirection::Forward); // Weigh data using "Flat Top" function - better amplitude accuracy
+ #else
+ FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman- Harris" window - sharp peaks due to excellent sideband rejection
+ #endif
+ FFT.compute( FFTDirection::Forward ); // Compute FFT
+ FFT.complexToMagnitude(); // Compute magnitudes
+ #else
+ FFT.DCRemoval(); // let FFT lib remove DC component, so we don't need to care about this in getSamples()
- // run FFT (takes 3-5ms on ESP32, ~12ms on ESP32-S2)
-#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
- FFT.dcRemoval(); // remove DC offset
- #if !defined(FFT_PREFER_EXACT_PEAKS)
- FFT.windowing( FFTWindow::Flat_top, FFTDirection::Forward); // Weigh data using "Flat Top" function - better amplitude accuracy
- #else
- FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman- Harris" window - sharp peaks due to excellent sideband rejection
- #endif
- FFT.compute( FFTDirection::Forward ); // Compute FFT
- FFT.complexToMagnitude(); // Compute magnitudes
-#else
- FFT.DCRemoval(); // let FFT lib remove DC component, so we don't need to care about this in getSamples()
+ //FFT.Windowing( FFT_WIN_TYP_HAMMING, FFT_FORWARD ); // Weigh data - standard Hamming window
+ //FFT.Windowing( FFT_WIN_TYP_BLACKMAN, FFT_FORWARD ); // Blackman window - better side freq rejection
+ #if !defined(FFT_PREFER_EXACT_PEAKS)
+ FFT.Windowing( FFT_WIN_TYP_FLT_TOP, FFT_FORWARD ); // Flat Top Window - better amplitude accuracy
+ #else
+ FFT.Windowing( FFT_WIN_TYP_BLACKMAN_HARRIS, FFT_FORWARD );// Blackman-Harris - excellent sideband rejection
+ #endif
+ FFT.Compute( FFT_FORWARD ); // Compute FFT
+ FFT.ComplexToMagnitude(); // Compute magnitudes
+ #endif
- //FFT.Windowing( FFT_WIN_TYP_HAMMING, FFT_FORWARD ); // Weigh data - standard Hamming window
- //FFT.Windowing( FFT_WIN_TYP_BLACKMAN, FFT_FORWARD ); // Blackman window - better side freq rejection
- #if !defined(FFT_PREFER_EXACT_PEAKS)
- FFT.Windowing( FFT_WIN_TYP_FLT_TOP, FFT_FORWARD ); // Flat Top Window - better amplitude accuracy
- #else
- FFT.Windowing( FFT_WIN_TYP_BLACKMAN_HARRIS, FFT_FORWARD );// Blackman-Harris - excellent sideband rejection
- #endif
- FFT.Compute( FFT_FORWARD ); // Compute FFT
- FFT.ComplexToMagnitude(); // Compute magnitudes
-#endif
-
-#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
- FFT.majorPeak(FFT_MajorPeak, FFT_Magnitude); // let the effects know which freq was most dominant
-#else
- FFT.MajorPeak(&FFT_MajorPeak, &FFT_Magnitude); // let the effects know which freq was most dominant
-#endif
- FFT_MajorPeak = constrain(FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects
+ #ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
+ FFT.majorPeak(FFT_MajorPeak, FFT_Magnitude); // let the effects know which freq was most dominant
+ #else
+ FFT.MajorPeak(&FFT_MajorPeak, &FFT_Magnitude); // let the effects know which freq was most dominant
+ #endif
+ FFT_MajorPeak = constrain(FFT_MajorPeak, 1.0f, 11025.0f); // restrict value to range expected by effects
+ } else { // skip second run --> clear fft results, keep peaks
+ memset(vReal, 0, sizeof(vReal));
+ }
#if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS)
haveDoneFFT = true;
#endif
@@ -441,14 +475,16 @@ void FFTcode(void * parameter)
FFT_Magnitude = 0.001;
}
- for (int i = 0; i < samplesFFT; i++) {
- float t = fabsf(vReal[i]); // just to be sure - values in fft bins should be positive any way
- vReal[i] = t / 16.0f; // Reduce magnitude. Want end result to be scaled linear and ~4096 max.
- } // for()
+ if ((skipSecondFFT == false) || (isFirstRun == true)) {
- // mapping of FFT result bins to frequency channels
- //if (fabsf(sampleAvg) > 0.25f) { // noise gate open
- if (fabsf(volumeSmth) > 0.25f) { // noise gate open
+ for (int i = 0; i < samplesFFT; i++) {
+ float t = fabsf(vReal[i]); // just to be sure - values in fft bins should be positive any way
+ vReal[i] = t / 16.0f; // Reduce magnitude. Want end result to be scaled linear and ~4096 max.
+ } // for()
+
+ // mapping of FFT result bins to frequency channels
+ //if (fabsf(sampleAvg) > 0.25f) { // noise gate open
+ if (fabsf(volumeSmth) > 0.25f) { // noise gate open
#if 0
/* This FFT post processing is a DIY endeavour. What we really need is someone with sound engineering expertise to do a great job here AND most importantly, that the animations look GREAT as a result.
*
@@ -506,24 +542,34 @@ void FFTcode(void * parameter)
fftCalc[13] = fftAddAvg(86,104); // 18 3704 - 4479 high mid
fftCalc[14] = fftAddAvg(104,165) * 0.88f; // 61 4479 - 7106 high mid + high -- with slight damping
#endif
- } else { // noise gate closed - just decay old values
- for (int i=0; i < NUM_GEQ_CHANNELS; i++) {
- fftCalc[i] *= 0.85f; // decay to zero
- if (fftCalc[i] < 4.0f) fftCalc[i] = 0.0f;
+ } else { // noise gate closed - just decay old values
+ isFirstRun = false;
+ for (int i=0; i < NUM_GEQ_CHANNELS; i++) {
+ fftCalc[i] *= 0.85f; // decay to zero
+ if (fftCalc[i] < 4.0f) fftCalc[i] = 0.0f;
+ }
}
+
+ memcpy(lastFftCalc, fftCalc, sizeof(lastFftCalc)); // make a backup of last "good" channels
+
+ } else { // if second run skipped
+ memcpy(fftCalc, lastFftCalc, sizeof(fftCalc)); // restore last "good" channels
}
// post-processing of frequency channels (pink noise adjustment, AGC, smooting, scaling)
if (pinkIndex > MAX_PINK) pinkIndex = MAX_PINK;
//postProcessFFTResults((fabsf(sampleAvg) > 0.25f)? true : false , NUM_GEQ_CHANNELS);
- postProcessFFTResults((fabsf(volumeSmth)>0.25f)? true : false , NUM_GEQ_CHANNELS);
+ postProcessFFTResults((fabsf(volumeSmth)>0.25f)? true : false , NUM_GEQ_CHANNELS); // this function modifies fftCalc, fftAvg and fftResult
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
+ static uint64_t lastLastFFT = 0;
if (haveDoneFFT && (start < esp_timer_get_time())) { // filter out overflows
uint64_t fftTimeInMillis = ((esp_timer_get_time() - start) +5ULL) / 10ULL; // "+5" to ensure proper rounding
- fftTime = (fftTimeInMillis*3 + fftTime*7)/10; // smooth
+ fftTime = (((fftTimeInMillis + lastLastFFT)/2) *3 + fftTime*7)/10.0; // smart smooth
+ lastLastFFT = fftTimeInMillis;
}
#endif
+
// run peak detection
autoResetPeak();
detectSamplePeak();
@@ -531,8 +577,13 @@ void FFTcode(void * parameter)
#if !defined(I2S_GRAB_ADC1_COMPLETELY)
if ((audioSource == nullptr) || (audioSource->getType() != AudioSource::Type_I2SAdc)) // the "delay trick" does not help for analog ADC
#endif
- vTaskDelayUntil( &xLastWakeTime, xFrequency); // release CPU, and let I2S fill its buffers
-
+ {
+ if ((skipSecondFFT == false) || (fabsf(volumeSmth) < 0.25f)) {
+ vTaskDelayUntil( &xLastWakeTime, xFrequency); // release CPU, and let I2S fill its buffers
+ } else if (isFirstRun == true) {
+ vTaskDelayUntil( &xLastWakeTime, xFrequencyDouble); // release CPU after performing FFT in "skip second run" mode
+ }
+ }
} // for(;;)ever
} // FFTcode() task end
@@ -769,7 +820,11 @@ class AudioReactive : public Usermod {
};
// set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer)
+ #ifdef SR_ENABLE_DEFAULT
+ bool enabled = true; // WLEDMM
+ #else
bool enabled = false;
+ #endif
bool initDone = false;
// variables for UDP sound sync
@@ -1774,12 +1829,16 @@ class AudioReactive : public Usermod {
}
#if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS)
+ infoArr = user.createNestedArray(F("I2S cycle time"));
+ infoArr.add(roundf(fftTaskCycle)/100.0f);
+ infoArr.add(" ms");
+
infoArr = user.createNestedArray(F("Sampling time"));
- infoArr.add(float(sampleTime)/100.0f);
+ infoArr.add(roundf(sampleTime)/100.0f);
infoArr.add(" ms");
infoArr = user.createNestedArray(F("FFT time"));
- infoArr.add(float(fftTime)/100.0f);
+ infoArr.add(roundf(fftTime)/100.0f);
if ((fftTime/100) >= FFT_MIN_CYCLE) // FFT time over budget -> I2S buffer will overflow
infoArr.add("! ms");
else if ((fftTime/80 + sampleTime/80) >= FFT_MIN_CYCLE) // FFT time >75% of budget -> risk of instability
@@ -1787,8 +1846,9 @@ class AudioReactive : public Usermod {
else
infoArr.add(" ms");
- DEBUGSR_PRINTF("AR Sampling time: %5.2f ms\n", float(sampleTime)/100.0f);
- DEBUGSR_PRINTF("AR FFT time : %5.2f ms\n", float(fftTime)/100.0f);
+ DEBUGSR_PRINTF("AR I2S cycle time: %5.2f ms\n", roundf(fftTaskCycle)/100.0f);
+ DEBUGSR_PRINTF("AR Sampling time : %5.2f ms\n", roundf(sampleTime)/100.0f);
+ DEBUGSR_PRINTF("AR FFT time : %5.2f ms\n", roundf(fftTime)/100.0f);
#endif
}
}
diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h
index 62ded98d..276711de 100644
--- a/usermods/audioreactive/audio_source.h
+++ b/usermods/audioreactive/audio_source.h
@@ -23,7 +23,7 @@
// see https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/chip-series-comparison.html#related-documents
// and https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/i2s.html#overview-of-all-modes
-#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265)
+#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265)
// there are two things in these MCUs that could lead to problems with audio processing:
// * no floating point hardware (FPU) support - FFT uses float calculations. If done in software, a strong slow-down can be expected (between 8x and 20x)
// * single core, so FFT task might slow down other things like LED updates
diff --git a/wled00/FX.cpp b/wled00/FX.cpp
index 2a952981..9906b3de 100644
--- a/wled00/FX.cpp
+++ b/wled00/FX.cpp
@@ -5892,15 +5892,21 @@ uint16_t mode_2Dscrollingtext(void) {
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
SEGMENT.fade_out(255 - (SEGMENT.custom1>>5)); // fade to background color
}
-}
+ }
for (int i = 0; i < numberOfLetters; i++) {
if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen
- SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0));
+ uint32_t col1 = SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0);
+ uint32_t col2 = BLACK;
+ if (SEGMENT.check1 && SEGMENT.palette == 0) {
+ col1 = SEGCOLOR(0);
+ col2 = SEGCOLOR(2);
+ }
+ SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, col1, col2);
}
return FRAMETIME;
}
-static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,,,Overlay;!,!;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0";
+static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,,Gradient,Overlay;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0";
////////////////////////////
@@ -7138,6 +7144,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma.
band = constrain(band, 0, 15);
uint16_t colorIndex = band * 17;
uint16_t barHeight = map(fftResult[band], 0, 255, 0, rows); // do not subtract -1 from rows here
+ if (barHeight > rows) barHeight = rows; // WLEDMM map() can "overshoot" due to rounding errors
if (barHeight > previousBarHeight[x]) previousBarHeight[x] = barHeight; //drive the peak up
uint32_t ledColor = BLACK;
@@ -7148,7 +7155,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma.
ledColor = SEGMENT.color_from_palette(colorIndex, false, PALETTE_SOLID_WRAP, 0);
SEGMENT.setPixelColorXY(x, rows-1 - y, ledColor);
}
- if (previousBarHeight[x] > 0)
+ if ((previousBarHeight[x] > 0) && (previousBarHeight[x] < rows)) // WLEDMM avoid "overshooting" into other segments
SEGMENT.setPixelColorXY(x, rows - previousBarHeight[x], (SEGCOLOR(2) != BLACK) ? SEGCOLOR(2) : ledColor);
if (rippleTime && previousBarHeight[x]>0) previousBarHeight[x]--; //delay/ripple effect
diff --git a/wled00/FX.h b/wled00/FX.h
index 9ae94700..97019624 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -602,8 +602,8 @@ typedef struct Segment {
void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, uint32_t color, uint32_t fillColor = 0);
void drawArc(uint16_t x0, uint16_t y0, uint16_t radius, CRGB color, CRGB fillColor = BLACK) { drawArc(x0, y0, radius, RGBW32(color.r,color.g,color.b,0), RGBW32(fillColor.r,fillColor.g,fillColor.b,0)); } // automatic inline
- void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color);
- void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline
+ void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0);
+ void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0)); } // automatic inline
void wu_pixel(uint32_t x, uint32_t y, CRGB c);
void blur1d(fract8 blur_amount); // blur all rows in 1 dimension
void blur2d(fract8 blur_amount) { blur(blur_amount); }
diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp
index a6aecda3..07116d0b 100644
--- a/wled00/FX_2Dfcn.cpp
+++ b/wled00/FX_2Dfcn.cpp
@@ -531,13 +531,16 @@ void Segment::drawArc(uint16_t x0, uint16_t y0, uint16_t radius, uint32_t color,
// draws a raster font character on canvas
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
-void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {
+void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2) {
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
chr -= 32; // align with font table entries
const uint16_t cols = virtualWidth();
const uint16_t rows = virtualHeight();
const int font = w*h;
+ CRGB col = CRGB(color);
+ CRGBPalette16 grad = CRGBPalette16(col, col2 ? CRGB(col2) : col);
+
//if (w<5 || w>6 || h!=8) return;
for (int i = 0; i= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen
- addPixelColorXY(x0, y0, color);
+ addPixelColorXY(x0, y0, col);
}
}
}
diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm
index 4f92080e..c76ec8d4 100644
--- a/wled00/data/settings_leds.htm
+++ b/wled00/data/settings_leds.htm
@@ -9,6 +9,10 @@
var d=document,laprev=55,maxB=1,maxV=0,maxM=4000,maxPB=4096,maxL=1333,maxLbquot=0; //maximum bytes for LED allocation: 4kB for 8266, 32kB for 32
var customStarts=false,startsDirty=[],maxCOOverrides=5;
var loc = false, locip;
+ d.um_p = [];
+ d.rsvd = [];
+ d.ro_gpio = [];
+ d.max_gpio = 39;
function H(){window.open("https://mm.kno.wled.ge/features/settings/#led-settings");}
function B(){window.open("/settings","_self");}
function gId(n){return d.getElementById(n);}
@@ -24,10 +28,6 @@
// success event
scE.addEventListener("load", () => {
//console.log("File loaded");
- d.um_p = [];
- d.rsvd = [];
- d.ro_pins = [];
- d.max_gpio = 39;
GetV();checkSi();setABL();
if (d.um_p[0]==-1) d.um_p.shift();
});
@@ -67,7 +67,7 @@
for (k=0;ke==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(p)} can't be used.`);LCs[i].value="";LCs[i].focus();return false;}
- else if (!(nm == "IR" || nm=="BT") && d.ro_pins.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);LCs[i].value="";LCs[i].focus();return false;}
+ else if (!(nm == "IR" || nm=="BT") && d.ro_gpio.some((e)=>e==parseInt(LCs[i].value,10))) {alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);LCs[i].value="";LCs[i].focus();return false;}
for (j=i+1; j`;
- for (var j=-1; j<=d.max_gpio; j++) { // all possible pins
+ for (var j=-1; j<=50; j++) { // all possible pins WLEDMM: hardcoded to 50 as d.max_gpio is not calculated yet here (done in appendGPIOinfo)
let foundPin = -1;
for (var i=0; i max_gpio
function pinDropdownsPost() {
- // console.log('pinDropdownsPost', d.max_gpio, d.ro_pins, d.ro_gpio, d.rsvd);
+ // console.log('pinDropdownsPost', d.max_gpio, d.ro_gpio, d.rsvd);
var elements = gId("form_s").elements;
for (var i = 0, select; select = elements[i++];) {
@@ -244,14 +244,15 @@
// console.log("pinDropdownsPost option", c, c.value, d.ro_gpio.includes(c.value));
for (let j=0; j= max_gpio
+ //remove pins > max_gpio
if (c.value > d.max_gpio) {
select.removeChild(c);
i--; //decrease i by one because the index has been adjusted
}
//https://www.javascripttutorial.net/javascript-dom/javascript-add-remove-options/
//https://www.javascripttutorial.net/javascript-dom/javascript-remove-items-from-a-select-conditionally/
- if (c.text.length <= 2) c.text += " 🟢";
+ if (c.text.length <= 4) c.text += " 🟢"; //2 digit number space and ⍼/⎌. If no reserved/read only/other um, then pin can be freely used (green)
+ for (let jj=0; jj= 0) return true;
+ #endif
+ return false; // fall-through case
+ }
+
+ // returns true if gpio supports analogRead
+ bool PinManagerClass::isPinAnalog(int gpio) {
+ #if !defined(ARDUINO_ARCH_ESP32)
+ if (gpio == A0) return true; // for 8266
+ #else // for ESP32 variants
+ if (digitalPinToAnalogChannel(gpio) >= 0) return true;
+ #endif
+ return false; // fall-through case
+ }
+
+ // returns true if gpio supports analogRead, and it belongs to ADC unit 1
+ bool PinManagerClass::isPinADC1(int gpio) {
+ if ((gpio < 0) || !isPinAnalog(gpio)) return false;
+
+ #if !defined(ARDUINO_ARCH_ESP32)
+ if (gpio == A0) return true; // for 8266
+ #else // for ESP32 variants
+ #ifdef SOC_ADC_CHANNEL_NUM
+ if (digitalPinToAnalogChannel(gpio) < SOC_ADC_CHANNEL_NUM(0)) return true; // ADC1 on ESP32-S3, ESP32-S2, ESP32-C3
+ #else
+ if (digitalPinToAnalogChannel(gpio) < 8) return true; // ADC1 on classic ESP32
+ #endif
+ #endif
+ return false; // fall-through case
+ }
+
+ // returns true if gpio supports analogRead, and it belongs to ADC unit 2
+ bool PinManagerClass::isPinADC2(int gpio) {
+ if ((gpio < 0) || !isPinAnalog(gpio)) return false; // catch errors
+
+ #if !defined(ARDUINO_ARCH_ESP32)
+ return false; // for 8266 - no ADC2
+ #else // for ESP32 variants
+ if (isPinADC1(gpio) == false) return true; // analog but not ADC1 --> must be ADC2
+ #endif
+ return false; // fall-through case
+ }
+
+ // returns GPIO number for ADC unit x, channel y. 255 = no such pin
+ // see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary
+ uint8_t PinManagerClass::getADCPin(AdcIdentifier adcUnit, uint8_t adcPort)
+ {
+ #if !defined(ARDUINO_ARCH_ESP32)
+ if ((adcUnit == ADC1) && (adcPort == 0)) return A0; // for 8266
+ else return(PM_NO_PIN);
+
+ #else // for ESP32 variants
+ if ((adcUnit != ADC1) && (adcUnit != ADC2)) return(PM_NO_PIN); // catch errors
+
+ #if defined(SOC_ADC_MAX_CHANNEL_NUM) // for ESP32-S3, ESP32-S2, ESP32-C3
+ int8_t analogChannel = (adcUnit == ADC1) ? adcPort : (SOC_ADC_MAX_CHANNEL_NUM + adcPort);
+ if (adcPort >= SOC_ADC_MAX_CHANNEL_NUM) analogChannel = 255;
+ #else // for classic ESP32
+ int8_t analogChannel = (adcUnit == ADC1) ? adcPort : (10 + adcPort);
+ if (adcPort >= 10) analogChannel = 255;
+ #endif
+
+ //int analogPin = analogChannelToDigitalPin(analogChannel);
+ int analogPin = analogInputToDigitalPin(analogChannel);
+ if (analogPin >= 0) return(analogPin);
+ else return(PM_NO_PIN);
+ #endif
+
+ return(PM_NO_PIN); // fall-through case
+ }
+
+ // WLEDMM end
+
+
/* see https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/gpio.html
* The ESP32-S3 chip features 45 physical GPIO pins (GPIO0 ~ GPIO21 and GPIO26 ~ GPIO48). Each pin can be used as a general-purpose I/O
* Strapping pins: GPIO0, GPIO3, GPIO45 and GPIO46 are strapping pins. For more infomation, please refer to ESP32-S3 datasheet.
diff --git a/wled00/pin_manager.h b/wled00/pin_manager.h
index 508d9cac..21029320 100644
--- a/wled00/pin_manager.h
+++ b/wled00/pin_manager.h
@@ -67,7 +67,7 @@ static_assert(0u == static_cast(PinOwner::None), "PinOwner::None must b
class PinManagerClass {
private:
#ifdef ESP8266
- #define WLED_NUM_PINS 17
+ #define WLED_NUM_PINS 18 // WLEDMM include A0 = gpio17
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None };
PinOwner ownerConflict[WLED_NUM_PINS] = { PinOwner::None }; // WLEDMM: record pin alloc conflicts
@@ -124,10 +124,22 @@ class PinManagerClass {
bool isPinOk(byte gpio, bool output = true);
PinOwner getPinOwner(byte gpio);
+
+ // WLEDMM begin
String getOwnerText(PinOwner tag); // WLEDMM - return PIN owner tag as text
String getPinOwnerText(int gpio); // WLEDMM - return PIN owner as text
String getPinSpecialText(int gpio); // WLEDMM - return PIN special comments (if any)
String getPinConflicts(int gpio); // WLEDMM - return PIN alloc conflicts (if any)
+
+ bool isPinTouch(int gpio); // true if gpio supports touch functions
+ bool isPinAnalog(int gpio); // true if gpio supports analogRead
+ bool isPinADC1(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 1
+ bool isPinADC2(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 2
+ #define PM_NO_PIN 255
+ typedef enum { ADC_none = 0, ADC1 = 1, ADC2 = 2 } AdcIdentifier;
+ uint8_t getADCPin(AdcIdentifier adcUnit, uint8_t adcPort); // get GPIO number for ADC unit x, channel y. 255 = no such pin
+ // WLEDMM end
+
#ifdef ARDUINO_ARCH_ESP32
byte allocateLedc(byte channels);
void deallocateLedc(byte pos, byte channels);
diff --git a/wled00/wled.cpp b/wled00/wled.cpp
index 23427146..8eef3ba2 100644
--- a/wled00/wled.cpp
+++ b/wled00/wled.cpp
@@ -575,6 +575,27 @@ void WLED::setup()
USER_FLUSH(); // avoid lost lines (Serial buffer overflow)
}
}
+
+#if 0 // for testing
+ USER_PRINTLN(F("\n"));
+ USER_PRINTF("ADC1-0 = %d, ADC1-3 = %d, ADC1-7 = %d, ADC2-0 = %d, ADC2-1 = %d, ADC2-8 = %d, ADC2-10 = %d\n",
+ pinManager.getADCPin(PinManagerClass::ADC1, 0), pinManager.getADCPin(PinManagerClass::ADC1, 3), pinManager.getADCPin(PinManagerClass::ADC1, 7),
+ pinManager.getADCPin(PinManagerClass::ADC2, 0), pinManager.getADCPin(PinManagerClass::ADC2, 1), pinManager.getADCPin(PinManagerClass::ADC2, 8),
+ pinManager.getADCPin(PinManagerClass::ADC2, 10)
+ );
+ USER_PRINTLN();
+ for(int p=0; p<12; p++) {
+ if(pinManager.getADCPin(PinManagerClass::ADC1, p) < 255)
+ USER_PRINTF("ADC1-%d = %d, ", p, pinManager.getADCPin(PinManagerClass::ADC1, p));
+ }
+ USER_PRINTLN();
+ for(int p=0; p<12; p++) {
+ if(pinManager.getADCPin(PinManagerClass::ADC2, p) < 255)
+ USER_PRINTF("ADC2-%d = %d, ", p, pinManager.getADCPin(PinManagerClass::ADC2, p));
+ }
+ USER_PRINTLN(F("\n"));
+#endif
+
USER_PRINTLN(F("WLED initialization done.\n"));
delay(50);
// repeat Ada prompt
@@ -784,8 +805,10 @@ void WLED::initConnection()
WiFi.begin(clientSSID, clientPass);
#ifdef ARDUINO_ARCH_ESP32
- // WLEDMM - if your board has issues connecting to WiFi, try uncommenting this
- // WiFi.setTxPower(WIFI_POWER_5dBm); // required for ESP32-C3FH4-RGB
+#ifdef WLEDMM_WIFI_POWERON_HACK
+ // WLEDMM - if your board has issues connecting to WiFi, try this
+ WiFi.setTxPower(WIFI_POWER_5dBm); // required for ESP32-C3FH4-RGB
+#endif
WiFi.setSleep(!noWifiSleep);
WiFi.setHostname(hostname);
#else
diff --git a/wled00/wled.h b/wled00/wled.h
index 405af084..34e41c65 100644
--- a/wled00/wled.h
+++ b/wled00/wled.h
@@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
-#define VERSION 2301170
+#define VERSION 2301202
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
diff --git a/wled00/xml.cpp b/wled00/xml.cpp
index b0674cf6..84f70bbc 100644
--- a/wled00/xml.cpp
+++ b/wled00/xml.cpp
@@ -273,6 +273,14 @@ void appendGPIOinfo() {
oappendi(16);
#endif
oappend(SET_F(";"));
+
+ char dt_pins[30];
+ #if defined(ESP8266) && !defined(ARDUINO_ESP8266_ESP01)
+ sprintf(dt_pins, "d.dt_pins=[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d];", D0, D1, D2, D3, D4, D5, D6, D7, D8, hardwareRX, hardwareTX);
+ #else
+ sprintf(dt_pins, "d.dt_pins=[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d];", 99, 99, 99, 99, 99, 99, 99, 99, 99, hardwareRX, hardwareTX);
+ #endif
+ oappend(dt_pins);
}
//get values for settings form in javascript
@@ -748,7 +756,7 @@ void getSettingsJS(AsyncWebServerRequest* request, byte subPage, char* dest) //W
if (usermod) usermod->appendConfigData();
}
- // oappend(SET_F("console.log('getSettingsJS fix ro pins', d.max_gpio, d.ro_pins, d.ro_gpio);"));
+ // oappend(SET_F("console.log('getSettingsJS fix ro pins', d.max_gpio, d.ro_gpio);"));
oappend(SET_F("pinDropdownsPost();"));
}