Skip to content

Commit 2dee0dd

Browse files
authored
Merge branch 'MoonModules:mdev' into downsample4x
2 parents 370e43c + 7425b43 commit 2dee0dd

File tree

6 files changed

+141
-111
lines changed

6 files changed

+141
-111
lines changed

usermods/Battery/usermod_v2_Battery.h

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ class UsermodBattery : public Usermod
6060
bool initializing = true;
6161

6262
// strings to reduce flash memory usage (used more than twice)
63-
static const char _name[];
63+
// static const char _name[];
6464
static const char _readInterval[];
65-
static const char _enabled[];
65+
// static const char _enabled[];
6666
static const char _threshold[];
6767
static const char _preset[];
6868
static const char _duration[];
@@ -117,6 +117,7 @@ class UsermodBattery : public Usermod
117117
float readVoltage()
118118
{
119119
#ifdef ARDUINO_ARCH_ESP32
120+
if ((batteryPin <0) || !pinManager.isPinAnalog(batteryPin)) return(-1.0f); // WLEDMM avoid reading from invalid pin
120121
// use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV default attentuation) and divide by 1000 to get from milivolts to volts and multiply by voltage multiplier and apply calibration value
121122
return (analogReadMilliVolts(batteryPin) / 1000.0f) * voltageMultiplier + calibration;
122123
#else
@@ -127,26 +128,29 @@ class UsermodBattery : public Usermod
127128

128129
public:
129130
//Functions called by WLED
131+
UsermodBattery(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM: this shouldn't be necessary (passthrough of constructor), maybe because Usermod is an abstract class
130132

131133
/*
132134
* setup() is called once at boot. WiFi is not yet connected at this point.
133135
* You can use it to initialize variables, sensors or similar.
134136
*/
135137
void setup()
136138
{
139+
if (!enabled) return; // WLEDMM
137140
#ifdef ARDUINO_ARCH_ESP32
138141
bool success = false;
139142
DEBUG_PRINTLN(F("Allocating battery pin..."));
140-
if (batteryPin >= 0 && digitalPinToAnalogChannel(batteryPin) >= 0)
143+
if ((batteryPin >= 0) && (digitalPinToAnalogChannel(batteryPin) >= 0))
141144
if (pinManager.allocatePin(batteryPin, false, PinOwner::UM_Battery)) {
142145
DEBUG_PRINTLN(F("Battery pin allocation succeeded."));
143146
success = true;
144147
voltage = readVoltage();
145148
}
146149

147150
if (!success) {
148-
DEBUG_PRINTLN(F("Battery pin allocation failed."));
151+
USER_PRINTLN(F("Battery pin allocation failed."));
149152
batteryPin = -1; // allocation failed
153+
enabled = false;
150154
} else {
151155
pinMode(batteryPin, INPUT);
152156
}
@@ -178,7 +182,13 @@ class UsermodBattery : public Usermod
178182
*/
179183
void loop()
180184
{
181-
if(strip.isUpdating()) return;
185+
// WLEDMM begin
186+
if (!enabled) return;
187+
if (batteryPin < 0) return;
188+
unsigned long currentTime = millis(); // get the current elapsed time
189+
if (strip.isUpdating() && (currentTime - lastTime < 30000)) return; // WLEDMM: be nice
190+
lastTime = currentTime;
191+
// WLEDMM end
182192

183193
lowPowerIndicator();
184194

@@ -252,6 +262,7 @@ class UsermodBattery : public Usermod
252262
JsonObject user = root["u"];
253263
if (user.isNull()) user = root.createNestedObject("u");
254264

265+
if (!enabled) return; // WLEDMM
255266
if (batteryPin < 0) {
256267
JsonArray infoVoltage = user.createNestedArray(F("Battery voltage"));
257268
infoVoltage.add(F("n/a"));
@@ -360,6 +371,8 @@ class UsermodBattery : public Usermod
360371
void addToConfig(JsonObject& root)
361372
{
362373
JsonObject battery = root.createNestedObject(FPSTR(_name)); // usermodname
374+
battery[F("enabled")] = enabled; // WLEDMM
375+
363376
#ifdef ARDUINO_ARCH_ESP32
364377
battery[F("pin")] = batteryPin;
365378
#endif
@@ -373,11 +386,11 @@ class UsermodBattery : public Usermod
373386
battery[FPSTR(_readInterval)] = readingInterval;
374387

375388
JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section
376-
ao[FPSTR(_enabled)] = autoOffEnabled;
389+
ao[F("auto-off-enabled")] = autoOffEnabled;
377390
ao[FPSTR(_threshold)] = autoOffThreshold;
378391

379392
JsonObject lp = battery.createNestedObject(F("indicator")); // low power section
380-
lp[FPSTR(_enabled)] = lowPowerIndicatorEnabled;
393+
lp[F("indicator-enabled")] = lowPowerIndicatorEnabled;
381394
lp[FPSTR(_preset)] = lowPowerIndicatorPreset; // dropdown trickery (String)lowPowerIndicatorPreset;
382395
lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold;
383396
lp[FPSTR(_duration)] = lowPowerIndicatorDuration;
@@ -436,6 +449,10 @@ class UsermodBattery : public Usermod
436449
#endif
437450

438451
JsonObject battery = root[FPSTR(_name)];
452+
453+
bool configComplete = !battery.isNull(); // WLEDMM
454+
configComplete &= getJsonValue(battery[F("enabled")], enabled, true); // WLEDMM
455+
439456
if (battery.isNull())
440457
{
441458
DEBUG_PRINT(FPSTR(_name));
@@ -455,11 +472,11 @@ class UsermodBattery : public Usermod
455472
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
456473

457474
JsonObject ao = battery[F("auto-off")];
458-
setAutoOffEnabled(ao[FPSTR(_enabled)] | autoOffEnabled);
475+
setAutoOffEnabled(ao[F("auto-off-enabled")] | autoOffEnabled); // WLEDMM
459476
setAutoOffThreshold(ao[FPSTR(_threshold)] | autoOffThreshold);
460477

461478
JsonObject lp = battery[F("indicator")];
462-
setLowPowerIndicatorEnabled(lp[FPSTR(_enabled)] | lowPowerIndicatorEnabled);
479+
setLowPowerIndicatorEnabled(lp[F("indicator-enabled")] | lowPowerIndicatorEnabled); // WLEDMM
463480
setLowPowerIndicatorPreset(lp[FPSTR(_preset)] | lowPowerIndicatorPreset); // dropdown trickery (int)lp["preset"]
464481
setLowPowerIndicatorThreshold(lp[FPSTR(_threshold)] | lowPowerIndicatorThreshold);
465482
lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
@@ -490,7 +507,7 @@ class UsermodBattery : public Usermod
490507
}
491508
#endif
492509

493-
return !battery[FPSTR(_readInterval)].isNull();
510+
return configComplete && (!battery[FPSTR(_readInterval)].isNull()); // WLEDMM
494511
}
495512

496513
/*
@@ -780,9 +797,9 @@ class UsermodBattery : public Usermod
780797
};
781798

782799
// strings to reduce flash memory usage (used more than twice)
783-
const char UsermodBattery::_name[] PROGMEM = "Battery";
800+
// const char UsermodBattery::_name[] PROGMEM = "Battery";
784801
const char UsermodBattery::_readInterval[] PROGMEM = "interval";
785-
const char UsermodBattery::_enabled[] PROGMEM = "enabled";
802+
//const char UsermodBattery::_enabled[] PROGMEM = "enabled";
786803
const char UsermodBattery::_threshold[] PROGMEM = "threshold";
787804
const char UsermodBattery::_preset[] PROGMEM = "preset";
788805
const char UsermodBattery::_duration[] PROGMEM = "duration";

usermods/RTC/usermod_rtc.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,25 @@
88

99
#define RTC_DELTA 2 // only modify RTC time if delta exceeds this number of seconds
1010

11-
//Connect DS1307 to standard I2C pins (ESP32: GPIO 21 (SDA)/GPIO 22 (SCL))
11+
//Connect DS1307 or DS3231 to standard I2C pins (ESP32: GPIO 21 (SDA)/GPIO 22 (SCL))
1212

1313
class RTCUsermod : public Usermod {
1414
private:
1515
unsigned long lastTime = 0;
16-
bool disabled = false;
16+
bool RTCfound = false; // WLEDMM to prevent errors after anabling the usermod (Wire.cpp:526] write(): NULL TX buffer pointer)
1717
public:
1818

19+
RTCUsermod(const char *name, bool enabled):Usermod(name, enabled) {} //WLEDMM: this shouldn't be necessary (passthrough of constructor), maybe because Usermod is an abstract class
20+
1921
void setup() {
22+
RTCfound = false; // WLEDMM
2023
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
21-
if (pins[1].pin < 0 || pins[0].pin < 0) { disabled=true; return; } //WLEDMM bugfix - ensure that "final" GPIO are valid and no "-1" sneaks trough
24+
if (pins[1].pin < 0 || pins[0].pin < 0) { enabled=false; return; } //WLEDMM bugfix - ensure that "final" GPIO are valid and no "-1" sneaks trough
25+
if (!enabled) { DEBUG_PRINTLN(F("RTC usermod not enabled.")); return; }
2226

2327
// WLEDMM join hardware I2C
2428
if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously
25-
disabled = true;
29+
enabled = false;
2630
return;
2731
}
2832

@@ -40,20 +44,31 @@ class RTCUsermod : public Usermod {
4044
updateLocalTime();
4145
USER_PRINTLN(F("Localtime updated from RTC."));
4246
} else {
43-
if (!RTC.chipPresent()) disabled = true; //don't waste time if H/W error
47+
if (!RTC.chipPresent()) {
48+
enabled = false; //don't waste time if H/W error
49+
USER_PRINTLN(F("RTC board not present."));
50+
}
4451
}
52+
if (enabled) RTCfound = true; // WLEDMM
4553
}
4654

4755
void loop() {
48-
if (strip.isUpdating()) return;
49-
if (!disabled && toki.isTick()) {
56+
// WLEDMM begin
57+
if (!enabled) return;
58+
if (!RTCfound) return; // WLEDMM
59+
unsigned long currentTime = millis(); // get the current elapsed time
60+
if (strip.isUpdating() && (currentTime - lastTime < 10000)) return; // WLEDMM: be nice
61+
// WLEDMM end
62+
63+
if (enabled && toki.isTick()) { // WLEDMM
5064
time_t t = toki.second();
65+
lastTime = millis(); // WLEDMM
5166

5267
if (abs(t - RTC.get())> RTC_DELTA) { // WLEDMM only consider time diffs > 2 seconds
5368
if ( (toki.getTimeSource() == TOKI_TS_NTP)
5469
||( (toki.getTimeSource() != TOKI_TS_NONE) && (toki.getTimeSource() != TOKI_TS_RTC)
5570
&& (toki.getTimeSource() != TOKI_TS_BAD) && (toki.getTimeSource() != TOKI_TS_UDP_SEC) && (toki.getTimeSource() != TOKI_TS_UDP)))
56-
{ // WLEMM update RTC if we have a reliable time source
71+
{ // WLEDMM update RTC if we have a reliable time source
5772
RTC.set(t); //set RTC to NTP/UI-provided value - WLEDMM allow up to 3 sec deviation
5873
USER_PRINTLN(F("RTC updated using localtime."));
5974
} else {

usermods/audioreactive/audio_reactive.h

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,9 @@ void FFTcode(void * parameter)
449449
}
450450

451451
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
452+
// timing
452453
uint64_t start = esp_timer_get_time();
453454
bool haveDoneFFT = false; // indicates if second measurement (FFT time) is valid
454-
455455
static uint64_t lastCycleStart = 0;
456456
static uint64_t lastLastTime = 0;
457457
if ((lastCycleStart > 0) && (lastCycleStart < start)) { // filter out overflows
@@ -466,6 +466,14 @@ void FFTcode(void * parameter)
466466
if (audioSource) audioSource->getSamples(vReal, samplesFFT);
467467

468468
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
469+
// debug info in case that stack usage changes
470+
static unsigned int minStackFree = UINT32_MAX;
471+
unsigned int stackFree = uxTaskGetStackHighWaterMark(NULL);
472+
if (minStackFree > stackFree) {
473+
minStackFree = stackFree;
474+
DEBUGSR_PRINTF("|| %-9s min free stack %d\n", pcTaskGetTaskName(NULL), minStackFree); //WLEDMM
475+
}
476+
// timing
469477
if (start < esp_timer_get_time()) { // filter out overflows
470478
uint64_t sampleTimeInMillis = (esp_timer_get_time() - start +5ULL) / 10ULL; // "+5" to ensure proper rounding
471479
sampleTime = (sampleTimeInMillis*3 + sampleTime*7)/10.0; // smooth
@@ -715,6 +723,7 @@ void FFTcode(void * parameter)
715723
postProcessFFTResults((fabsf(volumeSmth)>0.25f)? true : false , NUM_GEQ_CHANNELS); // this function modifies fftCalc, fftAvg and fftResult
716724

717725
#if defined(WLED_DEBUG) || defined(SR_DEBUG)|| defined(SR_STATS)
726+
// timing
718727
static uint64_t lastLastFFT = 0;
719728
if (haveDoneFFT && (start < esp_timer_get_time())) { // filter out overflows
720729
uint64_t fftTimeInMillis = ((esp_timer_get_time() - start) +5ULL) / 10ULL; // "+5" to ensure proper rounding
@@ -1678,7 +1687,13 @@ class AudioReactive : public Usermod {
16781687
//useInputFilter = 0; // in case you need to disable low-cut software filtering
16791688
audioSource = new ES7243(SAMPLE_RATE, BLOCK_SIZE);
16801689
delay(100);
1681-
if (audioSource) audioSource->initialize(sdaPin, sclPin, i2swsPin, i2ssdPin, i2sckPin, mclkPin);
1690+
// WLEDMM align global pins
1691+
if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined)
1692+
if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin;
1693+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
1694+
if (i2c_scl >= 0) sclPin = -1;
1695+
1696+
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
16821697
break;
16831698
case 3:
16841699
DEBUGSR_PRINT(F("AR: SPH0645 Microphone - ")); DEBUGSR_PRINTLN(F(I2S_MIC_CHANNEL_TEXT));
@@ -1710,11 +1725,21 @@ class AudioReactive : public Usermod {
17101725
break;
17111726
#endif
17121727
case 6:
1713-
DEBUGSR_PRINTLN(F("AR: ES8388 Source"));
1728+
#ifdef use_es8388_mic
1729+
DEBUGSR_PRINTLN(F("AR: ES8388 Source (Mic)"));
1730+
#else
1731+
DEBUGSR_PRINTLN(F("AR: ES8388 Source (Line-In)"));
1732+
#endif
17141733
audioSource = new ES8388Source(SAMPLE_RATE, BLOCK_SIZE, 1.0f);
17151734
//useInputFilter = 0; // to disable low-cut software filtering and restore previous behaviour
17161735
delay(100);
1717-
if (audioSource) audioSource->initialize(sdaPin, sclPin, i2swsPin, i2ssdPin, i2sckPin, mclkPin);
1736+
// WLEDMM align global pins
1737+
if ((sdaPin >= 0) && (i2c_sda < 0)) i2c_sda = sdaPin; // copy usermod prefs into globals (if globals not defined)
1738+
if ((sclPin >= 0) && (i2c_scl < 0)) i2c_scl = sclPin;
1739+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
1740+
if (i2c_scl >= 0) sclPin = -1;
1741+
1742+
if (audioSource) audioSource->initialize(i2swsPin, i2ssdPin, i2sckPin, mclkPin);
17181743
break;
17191744

17201745
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
@@ -1758,6 +1783,10 @@ class AudioReactive : public Usermod {
17581783
DEBUGSR_PRINT(F("AR: init done, enabled = "));
17591784
DEBUGSR_PRINTLN(enabled ? F("true.") : F("false."));
17601785
USER_FLUSH();
1786+
1787+
#if defined(ARDUINO_ARCH_ESP32) && defined(SR_DEBUG)
1788+
DEBUGSR_PRINTF("|| %-9s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM
1789+
#endif
17611790
}
17621791

17631792

@@ -1788,6 +1817,10 @@ class AudioReactive : public Usermod {
17881817
DEBUGSR_PRINTLN(udpSyncConnected ? F("AR connected(): UDP: connected to WIFI.") : F("AR connected(): UDP is disconnected (Wifi)."));
17891818
}
17901819
}
1820+
1821+
#if defined(ARDUINO_ARCH_ESP32) && defined(SR_DEBUG)
1822+
DEBUGSR_PRINTF("|| %-9s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM
1823+
#endif
17911824
}
17921825

17931826

@@ -1844,6 +1877,15 @@ class AudioReactive : public Usermod {
18441877
#ifdef ARDUINO_ARCH_ESP32
18451878
if (!audioSource->isInitialized()) disableSoundProcessing = true; // no audio source
18461879

1880+
#ifdef SR_DEBUG
1881+
// debug info in case that task stack usage changes
1882+
static unsigned int minLoopStackFree = UINT32_MAX;
1883+
unsigned int stackFree = uxTaskGetStackHighWaterMark(NULL);
1884+
if (minLoopStackFree > stackFree) {
1885+
minLoopStackFree = stackFree;
1886+
DEBUGSR_PRINTF("|| %-9s min free stack %d\n", pcTaskGetTaskName(NULL), minLoopStackFree); //WLEDMM
1887+
}
1888+
#endif
18471889

18481890
// Only run the sampling code IF we're not in Receive mode or realtime mode
18491891
if (!(audioSyncEnabled & 0x02) && !disableSoundProcessing) {
@@ -2040,6 +2082,10 @@ class AudioReactive : public Usermod {
20402082
micDataReal = 0.0f; // just to be sure
20412083
if (enabled) disableSoundProcessing = false;
20422084
updateIsRunning = init;
2085+
2086+
#if defined(ARDUINO_ARCH_ESP32) && defined(SR_DEBUG)
2087+
DEBUGSR_PRINTF("|| %-9s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM
2088+
#endif
20432089
}
20442090

20452091
#else // reduced function for 8266
@@ -2336,6 +2382,11 @@ class AudioReactive : public Usermod {
23362382

23372383
JsonObject dmic = top.createNestedObject(FPSTR(_digitalmic));
23382384
dmic[F("type")] = dmType;
2385+
// WLEDMM: align with globals I2C pins
2386+
if ((dmType == 2) || (dmType == 6)) { // only for ES7243 and ES8388
2387+
if (i2c_sda >= 0) sdaPin = -1; // -1 = use global
2388+
if (i2c_scl >= 0) sclPin = -1; // -1 = use global
2389+
}
23392390
JsonArray pinArray = dmic.createNestedArray("pin");
23402391
pinArray.add(i2ssdPin);
23412392
pinArray.add(i2swsPin);

0 commit comments

Comments
 (0)