From 85d980db637b6c293ce77294a1404ee3d908e77e Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 2 May 2020 15:39:03 +0200
Subject: [PATCH 01/22] Update to core 2.7.0
---
.github/PULL_REQUEST_TEMPLATE.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 6ec59387b..dade0687c 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,7 +6,7 @@
- [ ] The pull request is done against the latest dev branch
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR.
- - [ ] The code change is tested and works on core Tasmota_core
- - [ ] The code change is tested and works on core ESP32
+ - [ ] The code change is tested and works on core ESP8266 V.2.7.0
+ - [ ] The code change is tested and works on core ESP32 V.1.12.0
- [ ] The code change pass CI tests. **Your PR cannot be merged unless tests pass**
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
From 72ee040948084a678329bee1acb95bc5d41938a6 Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Sat, 2 May 2020 16:44:44 +0200
Subject: [PATCH 02/22] webcam test whitout script
scripter local ip text var
---
tasmota/xdrv_10_scripter.ino | 4 ++++
tasmota/xdrv_39_webcam.ino | 34 +++++++++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index 8f01bae2f..040442084 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -1562,6 +1562,10 @@ chknext:
}
break;
case 'l':
+ if (!strncmp(vname,"lip",3)) {
+ if (sp) strlcpy(sp,(const char*)WiFi.localIP().toString().c_str(),glob_script_mem.max_ssize);
+ goto strexit;
+ }
if (!strncmp(vname,"loglvl",6)) {
fvar=glob_script_mem.script_loglevel;
tind->index=SCRIPT_LOGLEVEL;
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index 1a2f3b260..a223ddfa6 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -561,6 +561,13 @@ uint8_t *out_buf=0;
}
}
+void wc_show_stream(void) {
+#ifndef USE_SCRIPT
+ if (CamServer) WSContentSend_P("

webcam stream",WiFi.localIP().toString().c_str());
+#endif
+}
+
+
uint32_t wc_set_streamserver(uint32_t flag) {
if (global_state.wifi_down) return 0;
@@ -583,7 +590,6 @@ uint32_t wc_set_streamserver(uint32_t flag) {
delete CamServer;
CamServer=NULL;
AddLog_P(WC_LOGLEVEL, "cam stream exit");
-
}
}
return 0;
@@ -630,6 +636,26 @@ red led = gpio 33
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
+#define D_CMND_WC "webcam"
+
+const char kWCCommands[] PROGMEM = "|" // no prefix
+ D_CMND_WC
+ ;
+
+void (* const WCCommand[])(void) PROGMEM = {
+ &CmndWC,
+ };
+
+void CmndWC(void) {
+ uint8_t flag=0;
+ if (XdrvMailbox.data_len > 0) {
+ wc_set_streamserver(XdrvMailbox.payload);
+ wc_setup(flag);
+ }
+ if (CamServer) flag=1;
+ Response_P(PSTR("{\"" D_CMND_WC "\":{\"streaming\":%d}"),flag);
+}
+
bool Xdrv39(uint8_t function) {
bool result = false;
@@ -641,6 +667,12 @@ bool Xdrv39(uint8_t function) {
case FUNC_WEB_ADD_HANDLER:
wc_pic_setup();
break;
+ case FUNC_WEB_ADD_MAIN_BUTTON:
+ wc_show_stream();
+ break;
+ case FUNC_COMMAND:
+ result = DecodeCommand(kWCCommands, WCCommand);
+ break;
}
return result;
}
From e5f27732131e0feb74000136f7c71b4176ac9088 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 2 May 2020 17:13:50 +0200
Subject: [PATCH 03/22] Fix compile error when USE_LIGHT is disabled
---
tasmota/xdrv_37_sonoff_d1.ino | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/xdrv_37_sonoff_d1.ino b/tasmota/xdrv_37_sonoff_d1.ino
index 9ebc4b4f3..cd1bdd4b2 100644
--- a/tasmota/xdrv_37_sonoff_d1.ino
+++ b/tasmota/xdrv_37_sonoff_d1.ino
@@ -17,6 +17,7 @@
along with this program. If not, see .
*/
+#ifdef USE_LIGHT
#ifdef USE_SONOFF_D1
/*********************************************************************************************\
* Sonoff D1 dimmer 433
@@ -196,3 +197,4 @@ bool Xdrv37(uint8_t function)
}
#endif // USE_SONOFF_D1
+#endif // USE_LIGHT
From 203c799dc59f6c14cd9e7bcd14e0722e009086db Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 2 May 2020 17:25:58 +0200
Subject: [PATCH 04/22] Increase TasmotaSlave Serial Timeout
Increase TasmotaSlave Serial Timeout (#8316)
---
tasmota/xdrv_31_tasmota_slave.ino | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/tasmota/xdrv_31_tasmota_slave.ino b/tasmota/xdrv_31_tasmota_slave.ino
index e0a773728..38306a791 100644
--- a/tasmota/xdrv_31_tasmota_slave.ino
+++ b/tasmota/xdrv_31_tasmota_slave.ino
@@ -444,7 +444,7 @@ void TasmotaSlave_Init(void)
if (TasmotaSlave_Serial->hardwareSerial()) {
ClaimSerial();
}
- TasmotaSlave_Serial->setTimeout(50);
+ TasmotaSlave_Serial->setTimeout(100); // Theo 20200502 - increase from 50
if (PinUsed(GPIO_TASMOTASLAVE_RST_INV)) {
SetPin(Pin(GPIO_TASMOTASLAVE_RST_INV), GPIO_TASMOTASLAVE_RST);
TSlave.inverted = HIGH;
@@ -456,11 +456,14 @@ void TasmotaSlave_Init(void)
}
}
}
- if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any
+ if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any
TasmotaSlave_sendCmnd(CMND_FEATURES, 0);
- char buffer[32];
+ char buffer[32] = { 0 };
TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer));
uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer));
+
+ if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00
+
memcpy(&TSlaveSettings, &buffer, sizeof(TSlaveSettings));
if (20191129 == TSlaveSettings.features_version) {
TSlave.type = true;
@@ -494,6 +497,9 @@ void TasmotaSlave_sendCmnd(uint8_t cmnd, uint8_t param)
buffer[0] = CMND_START;
memcpy(&buffer[1], &TSlaveCommand, sizeof(TSlaveCommand));
buffer[sizeof(TSlaveCommand)+1] = CMND_END;
+
+ TasmotaSlave_Serial->flush(); // Theo 20200502
+
for (uint8_t ca = 0; ca < sizeof(buffer); ca++) {
TasmotaSlave_Serial->write(buffer[ca]);
}
From ec1913346c57f80b4e4d65a905264c7666c8f287 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 2 May 2020 17:53:57 +0200
Subject: [PATCH 05/22] Fix ESP32 GPIO selection if Counters are disabled
---
tasmota/xdrv_01_webserver.ino | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index d22b07b5c..4dddafaec 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -1469,12 +1469,28 @@ void HandleTemplateConfiguration(void)
#ifdef ESP32
WSContentSend_P(PSTR("hs=["));
bool first_done = false;
+/*
for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) {
uint32_t midx = pgm_read_word(kGpioNiceList + i) & 0x001F;
if (first_done) { WSContentSend_P(PSTR(",")); }
WSContentSend_P(PSTR("%d"), midx);
first_done = true;
}
+*/
+ uint32_t j = 0;
+ for (uint32_t i = 0; i < GPIO_SENSOR_END; i++) {
+ uint32_t midx = pgm_read_word(kGpioNiceList + j);
+ if ((midx >> 5) != i) {
+ midx = 0;
+ } else {
+ midx &= 0x001F;
+ j++;
+ }
+ if (first_done) { WSContentSend_P(PSTR(",")); }
+ WSContentSend_P(PSTR("%d"), midx);
+ first_done = true;
+ }
+
WSContentSend_P(PSTR("];"));
#endif // ESP32
@@ -1635,12 +1651,28 @@ void HandleModuleConfiguration(void)
#ifdef ESP32
WSContentSend_P(PSTR("hs=["));
bool first_done = false;
+/*
for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) {
midx = pgm_read_word(kGpioNiceList + i) & 0x001F;
if (first_done) { WSContentSend_P(PSTR(",")); }
WSContentSend_P(PSTR("%d"), midx);
first_done = true;
}
+*/
+ uint32_t j = 0;
+ for (uint32_t i = 0; i < GPIO_SENSOR_END; i++) {
+ midx = pgm_read_word(kGpioNiceList + j);
+ if ((midx >> 5) != i) {
+ midx = 0;
+ } else {
+ midx &= 0x001F;
+ j++;
+ }
+ if (first_done) { WSContentSend_P(PSTR(",")); }
+ WSContentSend_P(PSTR("%d"), midx);
+ first_done = true;
+ }
+
WSContentSend_P(PSTR("];"));
#endif // ESP32
From 4b22f60e516c3b4d647df7a88da4efc2af42cf36 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 3 May 2020 10:39:38 +0200
Subject: [PATCH 06/22] Change PWM updated to latest Arduino Core #7213
---
tasmota/CHANGELOG.md | 1 +
tasmota/core_esp8266_waveform.cpp | 445 ++++++++++++++++------------
tasmota/core_esp8266_wiring_pwm.cpp | 4 +-
3 files changed, 260 insertions(+), 190 deletions(-)
diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md
index 8bdb07297..648dac861 100644
--- a/tasmota/CHANGELOG.md
+++ b/tasmota/CHANGELOG.md
@@ -3,6 +3,7 @@
### 8.2.0.6 20200501
- Add experimental basic support for Tasmota on ESP32 based on work by Jörg Schüler-Maroldt
+- Change PWM updated to latest Arduino Core #7213
### 8.2.0.5 20200425
diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp
index 16bd7b40a..c39670686 100644
--- a/tasmota/core_esp8266_waveform.cpp
+++ b/tasmota/core_esp8266_waveform.cpp
@@ -5,23 +5,23 @@
Copyright (c) 2018 Earle F. Philhower, III. All rights reserved.
The core idea is to have a programmable waveform generator with a unique
- high and low period (defined in microseconds or CPU clock cycles). TIMER1 is
- set to 1-shot mode and is always loaded with the time until the next edge
- of any live waveforms.
+ high and low period (defined in microseconds or CPU clock cycles). TIMER1
+ is set to 1-shot mode and is always loaded with the time until the next
+ edge of any live waveforms.
Up to one waveform generator per pin supported.
- Each waveform generator is synchronized to the ESP clock cycle counter, not the
- timer. This allows for removing interrupt jitter and delay as the counter
- always increments once per 80MHz clock. Changes to a waveform are
+ Each waveform generator is synchronized to the ESP clock cycle counter, not
+ the timer. This allows for removing interrupt jitter and delay as the
+ counter always increments once per 80MHz clock. Changes to a waveform are
contiguous and only take effect on the next waveform transition,
allowing for smooth transitions.
This replaces older tone(), analogWrite(), and the Servo classes.
Everywhere in the code where "cycles" is used, it means ESP.getCycleCount()
- clock cycle count, or an interval measured in CPU clock cycles, but not TIMER1
- cycles (which may be 2 CPU clock cycles @ 160MHz).
+ clock cycle count, or an interval measured in CPU clock cycles, but not
+ TIMER1 cycles (which may be 2 CPU clock cycles @ 160MHz).
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -65,60 +65,62 @@ typedef struct {
uint32_t expiryCycle; // For time-limited waveform, the cycle when this waveform must stop
uint32_t timeHighCycles; // Currently running waveform period
uint32_t timeLowCycles; //
+ uint32_t desiredHighCycles; // Currently running waveform period
+ uint32_t desiredLowCycles; //
uint32_t gotoTimeHighCycles; // Copied over on the next period to preserve phase
uint32_t gotoTimeLowCycles; //
+ uint32_t lastEdge; //
} Waveform;
-static Waveform waveform[17]; // State of all possible pins
-static volatile uint32_t waveformState = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code
-static volatile uint32_t waveformEnabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code
+class WVFState {
+public:
+ Waveform waveform[17]; // State of all possible pins
+ uint32_t waveformState = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code
+ uint32_t waveformEnabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code
-// Enable lock-free by only allowing updates to waveformState and waveformEnabled from IRQ service routine
-static volatile uint32_t waveformToEnable = 0; // Message to the NMI handler to start a waveform on a inactive pin
-static volatile uint32_t waveformToDisable = 0; // Message to the NMI handler to disable a pin from waveform generation
+ // Enable lock-free by only allowing updates to waveformState and waveformEnabled from IRQ service routine
+ uint32_t waveformToEnable = 0; // Message to the NMI handler to start a waveform on a inactive pin
+ uint32_t waveformToDisable = 0; // Message to the NMI handler to disable a pin from waveform generation
-volatile int32_t waveformToChange = -1;
-volatile uint32_t waveformNewHigh = 0;
-volatile uint32_t waveformNewLow = 0;
+ int32_t waveformToChange = -1;
+ uint32_t waveformNewHigh = 0;
+ uint32_t waveformNewLow = 0;
-static uint32_t (*timer1CB)() = NULL;
+ uint32_t (*timer1CB)() = NULL;
+
+ // Optimize the NMI inner loop by keeping track of the min and max GPIO that we
+ // are generating. In the common case (1 PWM) these may be the same pin and
+ // we can avoid looking at the other pins.
+ int startPin = 0;
+ int endPin = 0;
+};
+static WVFState wvfState;
+
+
+// Ensure everything is read/written to RAM
+#define MEMBARRIER() { __asm__ volatile("" ::: "memory"); }
// Non-speed critical bits
#pragma GCC optimize ("Os")
-static inline ICACHE_RAM_ATTR uint32_t GetCycleCount() {
- uint32_t ccount;
- __asm__ __volatile__("esync; rsr %0,ccount":"=a"(ccount));
- return ccount;
-}
-
// Interrupt on/off control
static ICACHE_RAM_ATTR void timer1Interrupt();
static bool timerRunning = false;
static void initTimer() {
- timer1_disable();
- ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL);
- ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt);
- timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE);
- timerRunning = true;
+ if (!timerRunning) {
+ timer1_disable();
+ ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL);
+ ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt);
+ timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE);
+ timerRunning = true;
+ timer1_write(microsecondsToClockCycles(10));
+ }
}
-static void ICACHE_RAM_ATTR deinitTimer() {
- ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
- timer1_disable();
- timer1_isr_init();
- timerRunning = false;
-}
-
-// Set a callback. Pass in NULL to stop it
-void setTimer1Callback(uint32_t (*fn)()) {
- timer1CB = fn;
- if (!timerRunning && fn) {
- initTimer();
- timer1_write(microsecondsToClockCycles(1)); // Cause an interrupt post-haste
- } else if (timerRunning && !fn && !waveformEnabled) {
- deinitTimer();
+static ICACHE_RAM_ATTR void forceTimerInterrupt() {
+ if (T1L > microsecondsToClockCycles(10)) {
+ T1L = microsecondsToClockCycles(10);
}
}
@@ -135,24 +137,31 @@ void setTimer1Callback(uint32_t (*fn)()) {
constexpr int maxPWMs = 8;
-// PWM edge definition
-typedef struct {
- unsigned int pin : 8;
- unsigned int delta : 24;
-} PWMEntry;
-
// PWM machine state
typedef struct {
uint32_t mask; // Bitmask of active pins
- uint8_t cnt; // How many entries
- uint8_t idx; // Where the state machine is along the list
- PWMEntry edge[maxPWMs + 1]; // Include space for terminal element
+ uint32_t cnt; // How many entries
+ uint32_t idx; // Where the state machine is along the list
+ uint8_t pin[maxPWMs + 1];
+ uint32_t delta[maxPWMs + 1];
uint32_t nextServiceCycle; // Clock cycle for next step
} PWMState;
static PWMState pwmState;
-static volatile PWMState *pwmUpdate = nullptr; // Set by main code, cleared by ISR
-static uint32_t pwmPeriod = (1000000L * system_get_cpu_freq()) / 1000;
+static PWMState *pwmUpdate = nullptr; // Set by main code, cleared by ISR
+static uint32_t pwmPeriod = microsecondsToClockCycles(1000000UL) / 1000;
+
+
+
+static ICACHE_RAM_ATTR void disableIdleTimer() {
+ if (timerRunning && !wvfState.waveformEnabled && !pwmState.cnt && !wvfState.timer1CB) {
+ ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
+ timer1_disable();
+ timer1_isr_init();
+ timerRunning = false;
+ }
+}
+
// Called when analogWriteFreq() changed to update the PWM total period
void _setPWMPeriodCC(uint32_t cc) {
@@ -168,111 +177,118 @@ void _setPWMPeriodCC(uint32_t cc) {
PWMState p; // The working copy since we can't edit the one in use
p = pwmState;
uint32_t ttl = 0;
- for (auto i = 0; i < p.cnt; i++) {
- uint64_t val64p16 = ((uint64_t)p.edge[i].delta) << 16;
+ for (uint32_t i = 0; i < p.cnt; i++) {
+ uint64_t val64p16 = ((uint64_t)p.delta[i]) << 16;
uint64_t newVal64p32 = val64p16 * ratio64p16;
- p.edge[i].delta = newVal64p32 >> 32;
- ttl += p.edge[i].delta;
+ p.delta[i] = newVal64p32 >> 32;
+ ttl += p.delta[i];
}
- p.edge[p.cnt].delta = cc - ttl; // Final cleanup exactly cc total cycles
+ p.delta[p.cnt] = cc - ttl; // Final cleanup exactly cc total cycles
// Update and wait for mailbox to be emptied
pwmUpdate = &p;
+ MEMBARRIER();
+ forceTimerInterrupt();
while (pwmUpdate) {
delay(0);
+ // No mem barrier. The external function call guarantees it's re-read
}
}
pwmPeriod = cc;
}
// Helper routine to remove an entry from the state machine
-static void _removePWMEntry(int pin, PWMState *p) {
- if (!((1<mask)) {
- return;
- }
+static ICACHE_RAM_ATTR void _removePWMEntry(int pin, PWMState *p) {
+ uint32_t i;
+
+ // Find the pin to pull out...
+ for (i = 0; p->pin[i] != pin; i++) { /* no-op */ }
+ auto delta = p->delta[i];
- int delta = 0;
- int i;
- for (i=0; i < p->cnt; i++) {
- if (p->edge[i].pin == pin) {
- delta = p->edge[i].delta;
- break;
- }
- }
// Add the removed previous pin delta to preserve absolute position
- p->edge[i+1].delta += delta;
- // Move everything back one and clean up
+ p->delta[i+1] += delta;
+
+ // Move everything back one
for (i++; i <= p->cnt; i++) {
- p->edge[i-1] = p->edge[i];
+ p->pin[i-1] = p->pin[i];
+ p->delta[i-1] = p->delta[i];
}
+ // Remove the pin from the active list
p->mask &= ~(1<cnt--;
}
// Called by analogWrite(0/100%) to disable PWM on a specific pin
-bool _stopPWM(int pin) {
+ICACHE_RAM_ATTR bool _stopPWM(int pin) {
if (!((1<= maxPWMs) {
return false; // No space left
} else if (p.cnt == 0) {
// Starting up from scratch, special case 1st element and PWM period
- p.edge[0].pin = pin;
- p.edge[0].delta = cc;
- p.edge[1].pin = 0xff;
- p.edge[1].delta = pwmPeriod - cc;
+ p.pin[0] = pin;
+ p.delta[0] = cc;
+ p.pin[1] = 0xff;
+ p.delta[1] = pwmPeriod - cc;
p.cnt = 1;
p.mask = 1<high transition. For immediate change, stopWaveform()
// first, then it will immediately begin.
@@ -284,44 +300,59 @@ int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t time
if ((pin > 16) || isFlashInterfacePin(pin)) {
return false;
}
- Waveform *wave = &waveform[pin];
- wave->expiryCycle = runTimeCycles ? GetCycleCount() + runTimeCycles : 0;
+ Waveform *wave = &wvfState.waveform[pin];
+ wave->expiryCycle = runTimeCycles ? ESP.getCycleCount() + runTimeCycles : 0;
if (runTimeCycles && !wave->expiryCycle) {
wave->expiryCycle = 1; // expiryCycle==0 means no timeout, so avoid setting it
}
+ _stopPWM(pin); // Make sure there's no PWM live here
+
uint32_t mask = 1<= 0) {
+ MEMBARRIER();
+ if (wvfState.waveformEnabled & mask) {
+ wvfState.waveformNewHigh = timeHighCycles;
+ wvfState.waveformNewLow = timeLowCycles;
+ MEMBARRIER();
+ wvfState.waveformToChange = pin;
+ while (wvfState.waveformToChange >= 0) {
delay(0); // Wait for waveform to update
+ // No mem barrier here, the call to a global function implies global state updated
}
- } else { // if (!(waveformEnabled & mask)) {
+ } else { // if (!(wvfState.waveformEnabled & mask)) {
wave->timeHighCycles = timeHighCycles;
wave->timeLowCycles = timeLowCycles;
+ wave->desiredHighCycles = wave->timeHighCycles;
+ wave->desiredLowCycles = wave->timeLowCycles;
+ wave->lastEdge = 0;
wave->gotoTimeHighCycles = wave->timeHighCycles;
wave->gotoTimeLowCycles = wave->timeLowCycles; // Actually set the pin high or low in the IRQ service to guarantee times
- wave->nextServiceCycle = GetCycleCount() + microsecondsToClockCycles(1);
- waveformToEnable |= mask;
- if (!timerRunning) {
- initTimer();
- timer1_write(microsecondsToClockCycles(10));
- } else {
- // Ensure timely service....
- if (T1L > microsecondsToClockCycles(10)) {
- timer1_write(microsecondsToClockCycles(10));
- }
- }
- while (waveformToEnable) {
+ wave->nextServiceCycle = ESP.getCycleCount() + microsecondsToClockCycles(1);
+ wvfState.waveformToEnable |= mask;
+ MEMBARRIER();
+ initTimer();
+ forceTimerInterrupt();
+ while (wvfState.waveformToEnable) {
delay(0); // Wait for waveform to update
+ // No mem barrier here, the call to a global function implies global state updated
}
}
return true;
}
+
+// Set a callback. Pass in NULL to stop it
+void setTimer1Callback(uint32_t (*fn)()) {
+ wvfState.timer1CB = fn;
+ if (fn) {
+ initTimer();
+ forceTimerInterrupt();
+ }
+ disableIdleTimer();
+}
+
+
// Speed critical bits
#pragma GCC optimize ("O2")
// Normally would not want two copies like this, but due to different
@@ -349,76 +380,87 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
}
// If user sends in a pin >16 but <32, this will always point to a 0 bit
// If they send >=32, then the shift will result in 0 and it will also return false
- uint32_t mask = 1< microsecondsToClockCycles(10)) {
- timer1_write(microsecondsToClockCycles(10));
- }
- while (waveformToDisable) {
- /* no-op */ // Can't delay() since stopWaveform may be called from an IRQ
- }
- if (!waveformEnabled && !pwmState.cnt && !timer1CB) {
- deinitTimer();
+ if (wvfState.waveformEnabled & (1UL << pin)) {
+ wvfState.waveformToDisable = 1UL << pin;
+ forceTimerInterrupt();
+ while (wvfState.waveformToDisable) {
+ MEMBARRIER(); // If it wasn't written yet, it has to be by now
+ /* no-op */ // Can't delay() since stopWaveform may be called from an IRQ
+ }
}
+ disableIdleTimer();
return true;
}
// The SDK and hardware take some time to actually get to our NMI code, so
// decrement the next IRQ's timer value by a bit so we can actually catch the
// real CPU cycle counter we want for the waveforms.
+
+// The SDK also sometimes is running at a different speed the the Arduino core
+// so the ESP cycle counter is actually running at a variable speed.
+// adjust(x) takes care of adjusting a delta clock cycle amount accordingly.
#if F_CPU == 80000000
#define DELTAIRQ (microsecondsToClockCycles(3))
+ #define adjust(x) ((x) << (turbo ? 1 : 0))
#else
#define DELTAIRQ (microsecondsToClockCycles(2))
+ #define adjust(x) ((x) >> (turbo ? 0 : 1))
+#endif
+
+#define ENABLE_ADJUST // Adjust takes 36 bytes
+#define ENABLE_FEEDBACK // Feedback costs 68 bytes
+#define ENABLE_PWM // PWM takes 160 bytes
+
+#ifndef ENABLE_ADJUST
+ #undef adjust
+ #define adjust(x) (x)
#endif
static ICACHE_RAM_ATTR void timer1Interrupt() {
- // Optimize the NMI inner loop by keeping track of the min and max GPIO that we
- // are generating. In the common case (1 PWM) these may be the same pin and
- // we can avoid looking at the other pins.
- static int startPin = 0;
- static int endPin = 0;
+ // Flag if the core is at 160 MHz, for use by adjust()
+ bool turbo = (*(uint32_t*)0x3FF00014) & 1 ? true : false;
uint32_t nextEventCycles = microsecondsToClockCycles(MAXIRQUS);
uint32_t timeoutCycle = GetCycleCountIRQ() + microsecondsToClockCycles(14);
- if (waveformToEnable || waveformToDisable) {
+ if (wvfState.waveformToEnable || wvfState.waveformToDisable) {
// Handle enable/disable requests from main app
- waveformEnabled = (waveformEnabled & ~waveformToDisable) | waveformToEnable; // Set the requested waveforms on/off
- waveformState &= ~waveformToEnable; // And clear the state of any just started
- waveformToEnable = 0;
- waveformToDisable = 0;
+ wvfState.waveformEnabled = (wvfState.waveformEnabled & ~wvfState.waveformToDisable) | wvfState.waveformToEnable; // Set the requested waveforms on/off
+ wvfState.waveformState &= ~wvfState.waveformToEnable; // And clear the state of any just started
+ wvfState.waveformToEnable = 0;
+ wvfState.waveformToDisable = 0;
+ // No mem barrier. Globals must be written to RAM on ISR exit.
// Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t)
- startPin = __builtin_ffs(waveformEnabled) - 1;
+ wvfState.startPin = __builtin_ffs(wvfState.waveformEnabled) - 1;
// Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one)
- endPin = 32 - __builtin_clz(waveformEnabled);
+ wvfState.endPin = 32 - __builtin_clz(wvfState.waveformEnabled);
+#ifdef ENABLE_PWM
} else if (!pwmState.cnt && pwmUpdate) {
// Start up the PWM generator by copying from the mailbox
- pwmState = *(PWMState*)pwmUpdate;
- pwmUpdate = nullptr;
+ pwmState.cnt = 1;
+ pwmState.idx = 1; // Ensure copy this cycle, cause it to start at t=0
pwmState.nextServiceCycle = GetCycleCountIRQ(); // Do it this loop!
- pwmState.idx = pwmState.cnt; // Cause it to start at t=0
- } else if (waveformToChange >=0) {
- waveform[waveformToChange].gotoTimeHighCycles = waveformNewHigh;
- waveform[waveformToChange].gotoTimeLowCycles = waveformNewLow;
- waveformToChange = -1;
+ // No need for mem barrier here. Global must be written by IRQ exit
+#endif
+ } else if (wvfState.waveformToChange >= 0) {
+ wvfState.waveform[wvfState.waveformToChange].gotoTimeHighCycles = wvfState.waveformNewHigh;
+ wvfState.waveform[wvfState.waveformToChange].gotoTimeLowCycles = wvfState.waveformNewLow;
+ wvfState.waveformToChange = -1;
+ // No need for memory barrier here. The global has to be written before exit the ISR.
}
bool done = false;
- if (waveformEnabled || pwmState.cnt) {
+ if (wvfState.waveformEnabled || pwmState.cnt) {
do {
nextEventCycles = microsecondsToClockCycles(MAXIRQUS);
-
+
+#ifdef ENABLE_PWM
// PWM state machine implementation
if (pwmState.cnt) {
- uint32_t now = GetCycleCountIRQ();
+ uint32_t now = GetCycleCountIRQ();
int32_t cyclesToGo = pwmState.nextServiceCycle - now;
- if (cyclesToGo <= 10) {
+ if (cyclesToGo < 0) {
if (pwmState.idx == pwmState.cnt) { // Start of pulses, possibly copy new
if (pwmUpdate) {
// Do the memory copy from temp to global and clear mailbox
@@ -427,39 +469,39 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
}
GPOS = pwmState.mask; // Set all active pins high
// GPIO16 isn't the same as the others
- if (pwmState.mask & 0x100) {
- GP16O |= 1;
+ if (pwmState.mask & (1<<16)) {
+ GP16O = 1;
}
pwmState.idx = 0;
} else {
do {
// Drop the pin at this edge
- GPOC = 1<expiryCycle - now;
if (expiryToGo < 0) {
// Done, remove!
- waveformEnabled &= ~mask;
+ wvfState.waveformEnabled &= ~mask;
if (i == 16) {
- GP16O &= ~1;
+ GP16O = 0;
} else {
ClearGPIO(mask);
}
@@ -480,27 +522,58 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
// Check for toggles
int32_t cyclesToGo = wave->nextServiceCycle - now;
if (cyclesToGo < 0) {
- waveformState ^= mask;
- if (waveformState & mask) {
+ uint32_t nextEdgeCycles;
+ uint32_t desired = 0;
+ uint32_t *timeToUpdate;
+ wvfState.waveformState ^= mask;
+ if (wvfState.waveformState & mask) {
if (i == 16) {
- GP16O |= 1; // GPIO16 write slow as it's RMW
+ GP16O = 1; // GPIO16 write slow as it's RMW
} else {
SetGPIO(mask);
}
- wave->nextServiceCycle = now + wave->timeHighCycles;
- nextEventCycles = min_u32(nextEventCycles, wave->timeHighCycles);
+ if (wave->gotoTimeHighCycles) {
+ // Copy over next full-cycle timings
+ wave->timeHighCycles = wave->gotoTimeHighCycles;
+ wave->desiredHighCycles = wave->gotoTimeHighCycles;
+ wave->timeLowCycles = wave->gotoTimeLowCycles;
+ wave->desiredLowCycles = wave->gotoTimeLowCycles;
+ wave->gotoTimeHighCycles = 0;
+ } else {
+#ifdef ENABLE_FEEDBACK
+ if (wave->lastEdge) {
+ desired = wave->desiredLowCycles;
+ timeToUpdate = &wave->timeLowCycles;
+ }
+ }
+#endif
+ nextEdgeCycles = wave->timeHighCycles;
} else {
if (i == 16) {
- GP16O &= ~1; // GPIO16 write slow as it's RMW
+ GP16O = 0; // GPIO16 write slow as it's RMW
} else {
ClearGPIO(mask);
}
- wave->nextServiceCycle = now + wave->timeLowCycles;
- nextEventCycles = min_u32(nextEventCycles, wave->timeLowCycles);
- // Copy over next full-cycle timings
- wave->timeHighCycles = wave->gotoTimeHighCycles;
- wave->timeLowCycles = wave->gotoTimeLowCycles;
+#ifdef ENABLE_FEEDBACK
+ desired = wave->desiredHighCycles;
+ timeToUpdate = &wave->timeHighCycles;
+#endif
+ nextEdgeCycles = wave->timeLowCycles;
}
+#ifdef ENABLE_FEEDBACK
+ if (desired) {
+ desired = adjust(desired);
+ int32_t err = desired - (now - wave->lastEdge);
+ if (abs(err) < desired) { // If we've lost > the entire phase, ignore this error signal
+ err /= 2;
+ *timeToUpdate += err;
+ }
+ }
+#endif
+ nextEdgeCycles = adjust(nextEdgeCycles);
+ wave->nextServiceCycle = now + nextEdgeCycles;
+ nextEventCycles = min_u32(nextEventCycles, nextEdgeCycles);
+ wave->lastEdge = now;
} else {
uint32_t deltaCycles = wave->nextServiceCycle - now;
nextEventCycles = min_u32(nextEventCycles, deltaCycles);
@@ -513,10 +586,10 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
int32_t cyclesLeftTimeout = timeoutCycle - now;
done = (cycleDeltaNextEvent < 0) || (cyclesLeftTimeout < 0);
} while (!done);
- } // if (waveformEnabled)
+ } // if (wvfState.waveformEnabled)
- if (timer1CB) {
- nextEventCycles = min_u32(nextEventCycles, timer1CB());
+ if (wvfState.timer1CB) {
+ nextEventCycles = min_u32(nextEventCycles, wvfState.timer1CB());
}
if (nextEventCycles < microsecondsToClockCycles(5)) {
@@ -525,11 +598,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
nextEventCycles -= DELTAIRQ;
// Do it here instead of global function to save time and because we know it's edge-IRQ
-#if F_CPU == 160000000
- T1L = nextEventCycles >> 1; // Already know we're in range by MAXIRQUS
-#else
- T1L = nextEventCycles; // Already know we're in range by MAXIRQUS
-#endif
+ T1L = nextEventCycles >> (turbo ? 1 : 0);
TEIE |= TEIE1; // Edge int enable
}
diff --git a/tasmota/core_esp8266_wiring_pwm.cpp b/tasmota/core_esp8266_wiring_pwm.cpp
index ec76b007b..90d69b313 100644
--- a/tasmota/core_esp8266_wiring_pwm.cpp
+++ b/tasmota/core_esp8266_wiring_pwm.cpp
@@ -47,8 +47,8 @@ extern void __analogWriteRange(uint32_t range) {
extern void __analogWriteFreq(uint32_t freq) {
if (freq < 100) {
analogFreq = 100;
- } else if (freq > 40000) {
- analogFreq = 40000;
+ } else if (freq > 60000) {
+ analogFreq = 60000;
} else {
analogFreq = freq;
}
From 5c744b573e12100228db8382f2250306b7e40e78 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 3 May 2020 11:42:10 +0200
Subject: [PATCH 07/22] Fix OTA corruption on large file uploads usinf -minimal
---
tasmota/settings.ino | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index 2548e2b14..aa3bc1e9b 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -346,6 +346,7 @@ void SettingsSaveAll(void)
void UpdateQuickPowerCycle(bool update)
{
+#ifndef FIRMWARE_MINIMAL
if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset
uint32_t pc_register;
@@ -353,9 +354,9 @@ void UpdateQuickPowerCycle(bool update)
#ifdef ESP8266
ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
-#else
+#else // ESP32
QPCRead(&pc_register, sizeof(pc_register));
-#endif
+#endif // ESP8266 - ESP32
if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) {
uint32_t counter = ((pc_register & 0xF) << 1) & 0xF;
if (0 == counter) { // 4 power cycles in a row
@@ -365,9 +366,9 @@ void UpdateQuickPowerCycle(bool update)
pc_register = 0xFFA55AB0 | counter;
#ifdef ESP8266
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
-#else
+#else // ESP32
QPCWrite(&pc_register, sizeof(pc_register));
-#endif
+#endif // ESP8266 - ESP32
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter);
}
}
@@ -378,11 +379,12 @@ void UpdateQuickPowerCycle(bool update)
if (ESP.flashEraseSector(pc_location)) {
ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register));
}
-#else
+#else // ESP32
QPCWrite(&pc_register, sizeof(pc_register));
-#endif
+#endif // ESP8266 - ESP32
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset"));
}
+#endif // FIRMWARE_MINIMAL
}
/*********************************************************************************************\
From d410420110d0e804d66678c876d94c2ee2caa398 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 3 May 2020 18:37:12 +0200
Subject: [PATCH 08/22] Tasmotify ESP32 webcam
---
tasmota/support_tasmota.ino | 13 +-
tasmota/tasmota_template_ESP32.h | 3 +-
tasmota/xdrv_39_webcam.ino | 447 ++++++++++++++++---------------
3 files changed, 246 insertions(+), 217 deletions(-)
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index c335bd9cb..e789d0cc9 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1441,14 +1441,9 @@ void GpioInit(void)
#ifdef ESP8266
if ((2 == Pin(GPIO_TXD)) || (H801 == my_module_type)) { Serial.set_tx(2); }
-#endif // ESP8266
-#ifdef ESP8266
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
-#else
- analogWriteFreqRange(0,Settings.pwm_frequency,Settings.pwm_range);
-#endif
#ifdef USE_SPI
spi_flg = (((PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_CS) > 14)) || (Pin(GPIO_SPI_CS) < 12)) || ((PinUsed(GPIO_SPI_DC) && (Pin(GPIO_SPI_DC) > 14)) || (Pin(GPIO_SPI_DC) < 12)));
@@ -1462,6 +1457,14 @@ void GpioInit(void)
}
soft_spi_flg = (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO)));
#endif // USE_SPI
+#else // ESP32
+ analogWriteFreqRange(0, Settings.pwm_frequency, Settings.pwm_range);
+
+#ifdef USE_SPI
+ spi_flg = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO)));
+ soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO)));
+#endif // USE_SPI
+#endif // ESP8266 - ESP32
// Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino
// Doing it here solves relay toggles at restart.
diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h
index 2a356a46a..80f4b56dd 100644
--- a/tasmota/tasmota_template_ESP32.h
+++ b/tasmota/tasmota_template_ESP32.h
@@ -197,8 +197,7 @@ enum UserSelectablePins {
ADC0_BUTTON_INV,
ADC0_RANGE, // Range
ADC0_CT_POWER, // Current
- // webcam interface
- GPIO_WEBCAM_PWDN_GPIO_NUM,
+ GPIO_WEBCAM_PWDN_GPIO_NUM, // Webcam interface
GPIO_WEBCAM_RESET_GPIO_NUM,
GPIO_WEBCAM_XCLK_GPIO_NUM,
GPIO_WEBCAM_SIOD_GPIO_NUM,
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index a223ddfa6..ffda441ee 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -1,5 +1,45 @@
+/*
+ xdrv_39_webcam.ino - ESP32 webcam support for Tasmota
-#if defined(ESP32) && defined(USE_WEBCAM)
+ Copyright (C) 2020 Gerhard Mutz and Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef ESP32
+#ifdef USE_WEBCAM
+/*********************************************************************************************\
+ * ESP32 webcam based on example in Arduino-ESP32 library
+ *
+ * Template as used on ESP32-CAM WiFi + bluetooth Camera Module Development Board ESP32 With Camera Module OV2640 Geekcreit for Arduino
+ * {"NAME":"AITHINKER CAM No SPI","GPIO":[4992,65504,65504,65504,5472,5312,65504,65504,5504,5536,65504,65504,5568,5440,5280,5248,0,5216,5408,5376,0,5344,5024,5056,0,0,0,0,4928,65504,5120,5088,5184,0,0,5152],"FLAG":0,"BASE":1}
+ * Template with SPI configured. This needs define USE_SPI
+ * {"NAME":"AITHINKER CAM","GPIO":[4992,65504,672,65504,5472,5312,65504,65504,5504,5536,736,704,5568,5440,5280,5248,0,5216,5408,5376,0,5344,5024,5056,0,0,0,0,4928,65504,5120,5088,5184,0,0,5152],"FLAG":0,"BASE":1}
+ *
+ * Command: Webcam
+ * 0 = Stop streaming
+ * 1 = FRAMESIZE_QQVGA2 (128x160)
+ * 2 = FRAMESIZE_QCIF (176x144)
+ * 3 = FRAMESIZE_HQVGA (240x176)
+ * 4 = FRAMESIZE_QVGA (320x240)
+ * 5 = FRAMESIZE_CIF (400x296)
+ * 6 = FRAMESIZE_VGA (640x480)
+ * 7 = FRAMESIZE_SVGA (800x600)
+ * 8 = FRAMESIZE_XGA (1024x768)
+ * 9 = FRAMESIZE_SXGA (1280x1024)
+ * 10 = FRAMESIZE_UXGA (1600x1200)
+\*********************************************************************************************/
#define XDRV_39 39
@@ -38,13 +78,11 @@ uint16_t wc_height;
uint8_t wc_stream_active;
uint32_t wc_setup(int32_t fsiz) {
-bool psram;
+ if (fsiz > 10) { fsiz = 10; }
- if (fsiz>10) fsiz=10;
+ wc_stream_active = 0;
- wc_stream_active=0;
-
- if (fsiz<0) {
+ if (fsiz < 0) {
esp_camera_deinit();
return 0;
}
@@ -56,7 +94,7 @@ bool psram;
//esp_log_level_set("*", ESP_LOG_VERBOSE);
-camera_config_t config;
+ camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.xclk_freq_hz = 20000000;
@@ -65,55 +103,6 @@ camera_config_t config;
// config.pixel_format = PIXFORMAT_RGB565;
#ifndef USE_TEMPLATE
-
-config.pin_d0 = Y2_GPIO_NUM;
-config.pin_d1 = Y3_GPIO_NUM;
-config.pin_d2 = Y4_GPIO_NUM;
-config.pin_d3 = Y5_GPIO_NUM;
-config.pin_d4 = Y6_GPIO_NUM;
-config.pin_d5 = Y7_GPIO_NUM;
-config.pin_d6 = Y8_GPIO_NUM;
-config.pin_d7 = Y9_GPIO_NUM;
-config.pin_xclk = XCLK_GPIO_NUM;
-config.pin_pclk = PCLK_GPIO_NUM;
-config.pin_vsync = VSYNC_GPIO_NUM;
-config.pin_href = HREF_GPIO_NUM;
-config.pin_sscb_sda = SIOD_GPIO_NUM;
-config.pin_sscb_scl = SIOC_GPIO_NUM;
-config.pin_pwdn = PWDN_GPIO_NUM;
-config.pin_reset = RESET_GPIO_NUM;
-
-#else
-
-if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y4_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y5_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_Y6_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y7_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y8_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y9_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_XCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_PCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_VSYNC_GPIO_NUM) && PinUsed(GPIO_WEBCAM_HREF_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_SIOD_GPIO_NUM) && PinUsed(GPIO_WEBCAM_SIOC_GPIO_NUM)) {
-
- config.pin_d0 = Pin(GPIO_WEBCAM_Y2_GPIO_NUM); //Y2_GPIO_NUM;
- config.pin_d1 = Pin(GPIO_WEBCAM_Y3_GPIO_NUM); //Y3_GPIO_NUM;
- config.pin_d2 = Pin(GPIO_WEBCAM_Y4_GPIO_NUM); //Y4_GPIO_NUM;
- config.pin_d3 = Pin(GPIO_WEBCAM_Y5_GPIO_NUM); //Y5_GPIO_NUM;
- config.pin_d4 = Pin(GPIO_WEBCAM_Y6_GPIO_NUM); //Y6_GPIO_NUM;
- config.pin_d5 = Pin(GPIO_WEBCAM_Y7_GPIO_NUM); //Y7_GPIO_NUM;
- config.pin_d6 = Pin(GPIO_WEBCAM_Y8_GPIO_NUM); //Y8_GPIO_NUM;
- config.pin_d7 = Pin(GPIO_WEBCAM_Y9_GPIO_NUM); //Y9_GPIO_NUM;
- config.pin_xclk = Pin(GPIO_WEBCAM_XCLK_GPIO_NUM); //XCLK_GPIO_NUM;
- config.pin_pclk = Pin(GPIO_WEBCAM_PCLK_GPIO_NUM); //PCLK_GPIO_NUM;
- config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC_GPIO_NUM); //VSYNC_GPIO_NUM;
- config.pin_href = Pin(GPIO_WEBCAM_HREF_GPIO_NUM); //HREF_GPIO_NUM;
- config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD_GPIO_NUM); //SIOD_GPIO_NUM;
- config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC_GPIO_NUM); //SIOC_GPIO_NUM;
-
- int16_t xpin;
- xpin=Pin(GPIO_WEBCAM_PWDN_GPIO_NUM);
- if (xpin==99) xpin=-1;
- config.pin_pwdn = xpin; //PWDN_GPIO_NUM;
- xpin=Pin(GPIO_WEBCAM_RESET_GPIO_NUM);
- if (xpin==99) xpin=-1;
- config.pin_reset = xpin; //RESET_GPIO_NUM;
-} else {
- // defaults to AI THINKER
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
@@ -130,9 +119,51 @@ if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinU
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
-}
-
-
+#else
+ if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y4_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y5_GPIO_NUM)\
+ && PinUsed(GPIO_WEBCAM_Y6_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y7_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y8_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y9_GPIO_NUM)\
+ && PinUsed(GPIO_WEBCAM_XCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_PCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_VSYNC_GPIO_NUM) && PinUsed(GPIO_WEBCAM_HREF_GPIO_NUM)\
+ && PinUsed(GPIO_WEBCAM_SIOD_GPIO_NUM) && PinUsed(GPIO_WEBCAM_SIOC_GPIO_NUM)) {
+ config.pin_d0 = Pin(GPIO_WEBCAM_Y2_GPIO_NUM); //Y2_GPIO_NUM;
+ config.pin_d1 = Pin(GPIO_WEBCAM_Y3_GPIO_NUM); //Y3_GPIO_NUM;
+ config.pin_d2 = Pin(GPIO_WEBCAM_Y4_GPIO_NUM); //Y4_GPIO_NUM;
+ config.pin_d3 = Pin(GPIO_WEBCAM_Y5_GPIO_NUM); //Y5_GPIO_NUM;
+ config.pin_d4 = Pin(GPIO_WEBCAM_Y6_GPIO_NUM); //Y6_GPIO_NUM;
+ config.pin_d5 = Pin(GPIO_WEBCAM_Y7_GPIO_NUM); //Y7_GPIO_NUM;
+ config.pin_d6 = Pin(GPIO_WEBCAM_Y8_GPIO_NUM); //Y8_GPIO_NUM;
+ config.pin_d7 = Pin(GPIO_WEBCAM_Y9_GPIO_NUM); //Y9_GPIO_NUM;
+ config.pin_xclk = Pin(GPIO_WEBCAM_XCLK_GPIO_NUM); //XCLK_GPIO_NUM;
+ config.pin_pclk = Pin(GPIO_WEBCAM_PCLK_GPIO_NUM); //PCLK_GPIO_NUM;
+ config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC_GPIO_NUM); //VSYNC_GPIO_NUM;
+ config.pin_href = Pin(GPIO_WEBCAM_HREF_GPIO_NUM); //HREF_GPIO_NUM;
+ config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD_GPIO_NUM); //SIOD_GPIO_NUM;
+ config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC_GPIO_NUM); //SIOC_GPIO_NUM;
+ int16_t xpin;
+ xpin = Pin(GPIO_WEBCAM_PWDN_GPIO_NUM);
+ if (99 == xpin) { xpin = -1; }
+ config.pin_pwdn = xpin; //PWDN_GPIO_NUM;
+ xpin = Pin(GPIO_WEBCAM_RESET_GPIO_NUM);
+ if (99 == xpin) { xpin=-1; }
+ config.pin_reset = xpin; //RESET_GPIO_NUM;
+ } else {
+ // defaults to AI THINKER
+ config.pin_d0 = Y2_GPIO_NUM;
+ config.pin_d1 = Y3_GPIO_NUM;
+ config.pin_d2 = Y4_GPIO_NUM;
+ config.pin_d3 = Y5_GPIO_NUM;
+ config.pin_d4 = Y6_GPIO_NUM;
+ config.pin_d5 = Y7_GPIO_NUM;
+ config.pin_d6 = Y8_GPIO_NUM;
+ config.pin_d7 = Y9_GPIO_NUM;
+ config.pin_xclk = XCLK_GPIO_NUM;
+ config.pin_pclk = PCLK_GPIO_NUM;
+ config.pin_vsync = VSYNC_GPIO_NUM;
+ config.pin_href = HREF_GPIO_NUM;
+ config.pin_sscb_sda = SIOD_GPIO_NUM;
+ config.pin_sscb_scl = SIOC_GPIO_NUM;
+ config.pin_pwdn = PWDN_GPIO_NUM;
+ config.pin_reset = RESET_GPIO_NUM;
+ }
#endif
//ESP.getPsramSize()
@@ -143,17 +174,17 @@ if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinU
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
- psram=psramFound();
+ bool psram = psramFound();
if (psram) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
- AddLog_P(WC_LOGLEVEL,"PSRAM found!");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: PSRAM found"));
} else {
config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 12;
config.fb_count = 1;
- AddLog_P(WC_LOGLEVEL,"PSRAM not found!");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: PSRAM not found"));
}
// stupid workaround camera diver eats up static ram should prefer PSRAM
@@ -161,75 +192,70 @@ if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinU
//ESP.getMaxAllocHeap()
// void *x=malloc(70000);
-void *x=0;
-
+ void *x = 0;
esp_err_t err = esp_camera_init(&config);
-
- if (x) free(x);
+ if (x) { free(x); }
if (err != ESP_OK) {
- AddLog_P2(WC_LOGLEVEL,"Camera init failed with error 0x%x", err);
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Init failed with error 0x%x"), err);
return 0;
}
sensor_t * wc_s = esp_camera_sensor_get();
// initial sensors are flipped vertically and colors are a bit saturated
- if (wc_s->id.PID == OV3660_PID) {
- wc_s->set_vflip(wc_s, 1); // flip it back
- wc_s->set_brightness(wc_s, 1); // up the brightness just a bit
- wc_s->set_saturation(wc_s, -2); // lower the saturation
+ if (OV3660_PID == wc_s->id.PID) {
+ wc_s->set_vflip(wc_s, 1); // flip it back
+ wc_s->set_brightness(wc_s, 1); // up the brightness just a bit
+ wc_s->set_saturation(wc_s, -2); // lower the saturation
}
// drop down frame size for higher initial frame rate
wc_s->set_framesize(wc_s, (framesize_t)fsiz);
camera_fb_t *wc_fb = esp_camera_fb_get();
- wc_width=wc_fb->width;
- wc_height=wc_fb->height;
+ wc_width = wc_fb->width;
+ wc_height = wc_fb->height;
esp_camera_fb_return(wc_fb);
- AddLog_P(WC_LOGLEVEL,"Camera successfully initialized!");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Initialized"));
- wc_up=1;
+ wc_up = 1;
+ if (psram) { wc_up=2; }
- if (psram) {
- wc_up=2;
- }
return wc_up;
}
-
-int32_t wc_set_options(uint32_t sel,int32_t value) {
- int32_t res=0;
+int32_t wc_set_options(uint32_t sel, int32_t value) {
+ int32_t res = 0;
sensor_t *s = esp_camera_sensor_get();
- if (!s) return -99;
+ if (!s) { return -99; }
switch (sel) {
case 0:
- if (value>=0) s->set_framesize(s,(framesize_t)value);
+ if (value >= 0) { s->set_framesize(s, (framesize_t)value); }
res = s->status.framesize;
break;
case 1:
- if (value>=0) s->set_special_effect(s,value);
+ if (value >= 0) { s->set_special_effect(s, value); }
res = s->status.special_effect;
break;
case 2:
- if (value>=0) s->set_vflip(s,value);
+ if (value >= 0) { s->set_vflip(s, value); }
res = s->status.vflip;
break;
case 3:
- if (value>=0) s->set_hmirror(s,value);
+ if (value >= 0) { s->set_hmirror(s, value); }
res = s->status.hmirror;
break;
case 4:
- if (value>=-4) s->set_contrast(s,value);
+ if (value >= -4) { s->set_contrast(s, value); }
res = s->status.contrast;
break;
case 5:
- if (value>=-4) s->set_brightness(s,value);
+ if (value >= -4) { s->set_brightness(s, value); }
res = s->status.brightness;
break;
case 6:
- if (value>=-4) s->set_saturation(s,value);
+ if (value >= -4) { s->set_saturation(s,value); }
res = s->status.saturation;
break;
}
@@ -239,16 +265,16 @@ int32_t wc_set_options(uint32_t sel,int32_t value) {
uint32_t wc_get_width(void) {
camera_fb_t *wc_fb = esp_camera_fb_get();
- if (!wc_fb) return 0;
- wc_width=wc_fb->width;
+ if (!wc_fb) { return 0; }
+ wc_width = wc_fb->width;
esp_camera_fb_return(wc_fb);
return wc_width;
}
uint32_t wc_get_height(void) {
camera_fb_t *wc_fb = esp_camera_fb_get();
- if (!wc_fb) return 0;
- wc_height=wc_fb->height;
+ if (!wc_fb) { return 0; }
+ wc_height = wc_fb->height;
esp_camera_fb_return(wc_fb);
return wc_height;
}
@@ -268,61 +294,60 @@ struct PICSTORE tmp_picstore;
#endif
uint32_t get_picstore(int32_t num, uint8_t **buff) {
- if (num<0) return MAX_PICSTORE;
- *buff=picstore[num].buff;
+ if (num<0) { return MAX_PICSTORE; }
+ *buff = picstore[num].buff;
return picstore[num].len;
}
uint32_t wc_get_jpeg(uint8_t **buff) {
-size_t _jpg_buf_len = 0;
-uint8_t * _jpg_buf = NULL;
-camera_fb_t *wc_fb;
+ size_t _jpg_buf_len = 0;
+ uint8_t * _jpg_buf = NULL;
+ camera_fb_t *wc_fb;
wc_fb = esp_camera_fb_get();
- if (!wc_fb) return 0;
- if (wc_fb->format!=PIXFORMAT_JPEG) {
+ if (!wc_fb) { return 0; }
+ if (wc_fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
- if (!jpeg_converted){
- _jpg_buf_len = wc_fb->len;
- _jpg_buf = wc_fb->buf;
+ if (!jpeg_converted) {
+ _jpg_buf_len = wc_fb->len;
+ _jpg_buf = wc_fb->buf;
}
} else {
_jpg_buf_len = wc_fb->len;
_jpg_buf = wc_fb->buf;
}
esp_camera_fb_return(wc_fb);
- *buff=_jpg_buf;
+ *buff = _jpg_buf;
return _jpg_buf_len;
}
-
uint32_t wc_get_frame(int32_t bnum) {
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
- camera_fb_t *wc_fb=0;
- bool jpeg_converted=false;
+ camera_fb_t *wc_fb = 0;
+ bool jpeg_converted = false;
- if (bnum<0) {
- if (bnum<-MAX_PICSTORE) bnum=-1;
- bnum=-bnum;
+ if (bnum < 0) {
+ if (bnum < -MAX_PICSTORE) { bnum=-1; }
+ bnum = -bnum;
bnum--;
- if (picstore[bnum].buff) free(picstore[bnum].buff);
- picstore[bnum].len=0;
+ if (picstore[bnum].buff) { free(picstore[bnum].buff); }
+ picstore[bnum].len = 0;
return 0;
}
#ifdef COPYFRAME
- if (bnum&0x10) {
- bnum&=0xf;
- _jpg_buf=tmp_picstore.buff;
- _jpg_buf_len=tmp_picstore.len;
- if (!_jpg_buf_len) return 0;
+ if (bnum & 0x10) {
+ bnum &= 0xf;
+ _jpg_buf = tmp_picstore.buff;
+ _jpg_buf_len = tmp_picstore.len;
+ if (!_jpg_buf_len) { return 0; }
goto pcopy;
}
#endif
wc_fb = esp_camera_fb_get();
if (!wc_fb) {
- AddLog_P(WC_LOGLEVEL, "cant get frame");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Can't get frame"));
return 0;
}
if (!bnum) {
@@ -332,12 +357,12 @@ uint32_t wc_get_frame(int32_t bnum) {
return 0;
}
- if (wc_fb->format!=PIXFORMAT_JPEG) {
+ if (wc_fb->format != PIXFORMAT_JPEG) {
jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
if (!jpeg_converted){
- //Serial.println("JPEG compression failed");
- _jpg_buf_len = wc_fb->len;
- _jpg_buf = wc_fb->buf;
+ //Serial.println("JPEG compression failed");
+ _jpg_buf_len = wc_fb->len;
+ _jpg_buf = wc_fb->buf;
}
} else {
_jpg_buf_len = wc_fb->len;
@@ -345,20 +370,21 @@ uint32_t wc_get_frame(int32_t bnum) {
}
pcopy:
- if (bnum<1 || bnum>MAX_PICSTORE) bnum=1;
+ if ((bnum < 1) || (bnum > MAX_PICSTORE)) { bnum = 1; }
bnum--;
- if (picstore[bnum].buff) free(picstore[bnum].buff);
- picstore[bnum].buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ if (picstore[bnum].buff) { free(picstore[bnum].buff); }
+ picstore[bnum].buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (picstore[bnum].buff) {
- memcpy(picstore[bnum].buff,_jpg_buf,_jpg_buf_len);
- picstore[bnum].len=_jpg_buf_len;
+ memcpy(picstore[bnum].buff, _jpg_buf, _jpg_buf_len);
+ picstore[bnum].len = _jpg_buf_len;
} else {
- AddLog_P(WC_LOGLEVEL, "cant allocate picstore");
- picstore[bnum].len=0;
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Can't allocate picstore"));
+ picstore[bnum].len = 0;
}
- if (wc_fb) esp_camera_fb_return(wc_fb);
- if (jpeg_converted) free(_jpg_buf);
- if (!picstore[bnum].buff) return 0;
+ if (wc_fb) { esp_camera_fb_return(wc_fb); }
+ if (jpeg_converted) { free(_jpg_buf); }
+ if (!picstore[bnum].buff) { return 0; }
+
return _jpg_buf_len;
}
@@ -369,7 +395,7 @@ void HandleImage(void) {
if (!HttpCheckPriviledgedAccess(true)) { return; }
uint32_t bnum = Webserver->arg(F("p")).toInt();
- if (bnum<0 || bnum>MAX_PICSTORE) bnum=1;
+ if ((bnum < 0) || (bnum > MAX_PICSTORE)) { bnum= 1; }
WiFiClient client = Webserver->client();
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-disposition: inline; filename=cap.jpg\r\n";
@@ -379,7 +405,7 @@ void HandleImage(void) {
if (!bnum) {
uint8_t *buff;
uint32_t len;
- len=wc_get_jpeg(&buff);
+ len = wc_get_jpeg(&buff);
if (len) {
client.write(buff,len);
free(buff);
@@ -387,14 +413,13 @@ void HandleImage(void) {
} else {
bnum--;
if (!picstore[bnum].len) {
- AddLog_P2(WC_LOGLEVEL, PSTR("no image #: %d"), bnum);
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: No image #: %d"), bnum);
return;
}
client.write((char *)picstore[bnum].buff, picstore[bnum].len);
}
- AddLog_P2(WC_LOGLEVEL, PSTR("sending image #: %d"), bnum+1);
-
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Sending image #: %d"), bnum+1);
}
ESP8266WebServer *CamServer;
@@ -403,17 +428,14 @@ ESP8266WebServer *CamServer;
WiFiClient client;
void handleMjpeg(void) {
- AddLog_P(WC_LOGLEVEL, "handle camserver");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Handle camserver"));
//if (!wc_stream_active) {
- wc_stream_active=1;
+ wc_stream_active = 1;
client = CamServer->client();
- AddLog_P(WC_LOGLEVEL, "create client");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Create client"));
//}
}
-
-
-
void handleMjpeg_task(void) {
camera_fb_t *wc_fb;
size_t _jpg_buf_len = 0;
@@ -421,35 +443,34 @@ void handleMjpeg_task(void) {
//WiFiClient client = CamServer->client();
uint32_t tlen;
- bool jpeg_converted=false;
+ bool jpeg_converted = false;
if (!client.connected()) {
- wc_stream_active=0;
- AddLog_P(WC_LOGLEVEL,"client fail");
+ wc_stream_active = 0;
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Client fail"));
goto exit;
}
- if (wc_stream_active==1) {
+ if (1 == wc_stream_active) {
client.flush();
client.setTimeout(3);
- AddLog_P(WC_LOGLEVEL, "start stream");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Start stream"));
client.print("HTTP/1.1 200 OK\r\n"
- "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n"
- "\r\n");
- wc_stream_active=2;
+ "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n"
+ "\r\n");
+ wc_stream_active = 2;
} else {
-
wc_fb = esp_camera_fb_get();
if (!wc_fb) {
- wc_stream_active=0;
- AddLog_P(WC_LOGLEVEL, "frame fail");
+ wc_stream_active = 0;
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Frame fail"));
goto exit;
}
- if (wc_fb->format!=PIXFORMAT_JPEG) {
+ if (wc_fb->format != PIXFORMAT_JPEG) {
jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len);
if (!jpeg_converted){
- AddLog_P(WC_LOGLEVEL, "JPEG compression failed");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: JPEG compression failed"));
_jpg_buf_len = wc_fb->len;
_jpg_buf = wc_fb->buf;
}
@@ -460,34 +481,34 @@ void handleMjpeg_task(void) {
client.printf("Content-Type: image/jpeg\r\n"
"Content-Length: %d\r\n"
- "\r\n", static_cast(_jpg_buf_len));
- tlen=client.write(_jpg_buf, _jpg_buf_len);
+ "\r\n", static_cast(_jpg_buf_len));
+ tlen = client.write(_jpg_buf, _jpg_buf_len);
/*
if (tlen!=_jpg_buf_len) {
esp_camera_fb_return(wc_fb);
wc_stream_active=0;
- AddLog_P(WC_LOGLEVEL, "send fail");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Send fail"));
}*/
client.print("\r\n--" BOUNDARY "\r\n");
#ifdef COPYFRAME
- if (tmp_picstore.buff) free(tmp_picstore.buff);
- tmp_picstore.buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ if (tmp_picstore.buff) { free(tmp_picstore.buff); }
+ tmp_picstore.buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (tmp_picstore.buff) {
- memcpy(tmp_picstore.buff,_jpg_buf,_jpg_buf_len);
- tmp_picstore.len=_jpg_buf_len;
+ memcpy(tmp_picstore.buff, _jpg_buf, _jpg_buf_len);
+ tmp_picstore.len = _jpg_buf_len;
} else {
- tmp_picstore.len=0;
+ tmp_picstore.len = 0;
}
#endif
- if (jpeg_converted) free(_jpg_buf);
+ if (jpeg_converted) { free(_jpg_buf); }
esp_camera_fb_return(wc_fb);
- //AddLog_P(WC_LOGLEVEL, "send frame");
+ //AddLog_P2(WC_LOGLEVEL, PSTR("CAM: send frame"));
exit:
if (!wc_stream_active) {
- AddLog_P(WC_LOGLEVEL, "stream exit");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Stream exit"));
client.flush();
client.stop();
}
@@ -508,8 +529,8 @@ uint32_t motion_brightness;
uint8_t *last_motion_buffer;
uint32_t wc_set_motion_detect(int32_t value) {
- if (value>=0) motion_detect=value;
- if (value==-1) {
+ if (value >= 0) { motion_detect=value; }
+ if (-1 == value) {
return motion_trigger;
} else {
return motion_brightness;
@@ -518,41 +539,41 @@ uint32_t wc_set_motion_detect(int32_t value) {
// optional motion detector
void detect_motion(void) {
-camera_fb_t *wc_fb;
-uint8_t *out_buf=0;
+ camera_fb_t *wc_fb;
+ uint8_t *out_buf=0;
- if ((millis()-motion_ltime)>motion_detect) {
- motion_ltime=millis();
+ if ((millis()-motion_ltime) > motion_detect) {
+ motion_ltime = millis();
wc_fb = esp_camera_fb_get();
- if (!wc_fb) return;
+ if (!wc_fb) { return; }
if (!last_motion_buffer) {
- last_motion_buffer=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height)+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ last_motion_buffer=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}
if (last_motion_buffer) {
- if (wc_fb->format==PIXFORMAT_JPEG) {
- out_buf=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height*3)+4,MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ if (PIXFORMAT_JPEG == wc_fb->format) {
+ out_buf = (uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (out_buf) {
fmt2rgb888(wc_fb->buf, wc_fb->len, wc_fb->format, out_buf);
- uint32_t x,y;
- uint8_t *pxi=out_buf;
- uint8_t *pxr=last_motion_buffer;
+ uint32_t x, y;
+ uint8_t *pxi = out_buf;
+ uint8_t *pxr = last_motion_buffer;
// convert to bw
- uint64_t accu=0;
- uint64_t bright=0;
- for (y=0;yheight;y++) {
- for (x=0;xwidth;x++) {
- int32_t gray=(pxi[0]+pxi[1]+pxi[2])/3;
- int32_t lgray=pxr[0];
- pxr[0]=gray;
- pxi+=3;
+ uint64_t accu = 0;
+ uint64_t bright = 0;
+ for (y = 0; y < wc_fb->height; y++) {
+ for (x = 0; x < wc_fb->width; x++) {
+ int32_t gray = (pxi[0] + pxi[1] + pxi[2]) / 3;
+ int32_t lgray = pxr[0];
+ pxr[0] = gray;
+ pxi += 3;
pxr++;
- accu+=abs(gray-lgray);
- bright+=gray;
+ accu += abs(gray - lgray);
+ bright += gray;
}
}
- motion_trigger=accu/((wc_fb->height*wc_fb->width)/100);
- motion_brightness=bright/((wc_fb->height*wc_fb->width)/100);
+ motion_trigger = accu / ((wc_fb->height * wc_fb->width) / 100);
+ motion_brightness = bright / ((wc_fb->height * wc_fb->width) / 100);
free(out_buf);
}
}
@@ -563,16 +584,17 @@ uint8_t *out_buf=0;
void wc_show_stream(void) {
#ifndef USE_SCRIPT
- if (CamServer) WSContentSend_P("

webcam stream",WiFi.localIP().toString().c_str());
+ if (CamServer) {
+ WSContentSend_P(PSTR("
"),
+ WiFi.localIP().toString().c_str());
+ }
#endif
}
-
uint32_t wc_set_streamserver(uint32_t flag) {
+ if (global_state.wifi_down) { return 0; }
- if (global_state.wifi_down) return 0;
-
- wc_stream_active=0;
+ wc_stream_active = 0;
if (flag) {
if (!CamServer) {
@@ -581,24 +603,24 @@ uint32_t wc_set_streamserver(uint32_t flag) {
CamServer->on("/cam.mjpeg", handleMjpeg);
CamServer->on("/cam.jpg", handleMjpeg);
CamServer->on("/stream", handleMjpeg);
- AddLog_P(WC_LOGLEVEL, "cam stream init");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Stream init"));
CamServer->begin();
}
} else {
if (CamServer) {
CamServer->stop();
delete CamServer;
- CamServer=NULL;
- AddLog_P(WC_LOGLEVEL, "cam stream exit");
+ CamServer = NULL;
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: Stream exit"));
}
}
return 0;
}
void wc_loop(void) {
- if (CamServer) CamServer->handleClient();
- if (wc_stream_active) handleMjpeg_task();
- if (motion_detect) detect_motion();
+ if (CamServer) { CamServer->handleClient(); }
+ if (wc_stream_active) { handleMjpeg_task(); }
+ if (motion_detect) { detect_motion(); }
}
void wc_pic_setup(void) {
@@ -634,9 +656,10 @@ red led = gpio 33
*/
/*********************************************************************************************\
- * Interface
+ * Commands
\*********************************************************************************************/
-#define D_CMND_WC "webcam"
+
+#define D_CMND_WC "Webcam"
const char kWCCommands[] PROGMEM = "|" // no prefix
D_CMND_WC
@@ -647,15 +670,18 @@ void (* const WCCommand[])(void) PROGMEM = {
};
void CmndWC(void) {
- uint8_t flag=0;
- if (XdrvMailbox.data_len > 0) {
+ uint32_t flag = 0;
+ if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) {
wc_set_streamserver(XdrvMailbox.payload);
wc_setup(flag);
}
- if (CamServer) flag=1;
- Response_P(PSTR("{\"" D_CMND_WC "\":{\"streaming\":%d}"),flag);
+ if (CamServer) { flag = 1; }
+ Response_P(PSTR("{\"" D_CMND_WC "\":{\"Streaming\":\"%s\"}"),GetStateText(flag));
}
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
bool Xdrv39(uint8_t function) {
bool result = false;
@@ -677,4 +703,5 @@ bool Xdrv39(uint8_t function) {
return result;
}
-#endif
+#endif // USE_WEBCAM
+#endif // ESP32
From c2b295984b409a521d93dbb66253ee706ed7c655 Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Mon, 4 May 2020 06:25:13 +0200
Subject: [PATCH 09/22] fix webcam size parameter
---
libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h | 2 +-
tasmota/xdrv_39_webcam.ino | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
index 4d943a052..90e2460b3 100644
--- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
+++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
@@ -80,7 +80,7 @@ inline void analogWriteFreqRange(uint32_t channel,uint32_t freq, uint32_t irange
ledcSetup(cnt+PWM_CHANNEL_OFFSET,freq,range);
}
}
- Serial.printf("freq - range %d - %d\n",freq,range);
+ //Serial.printf("freq - range %d - %d\n",freq,range);
}
#define INPUT_PULLDOWN_16 INPUT_PULLUP
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index ffda441ee..841684cd0 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -39,6 +39,11 @@
* 8 = FRAMESIZE_XGA (1024x768)
* 9 = FRAMESIZE_SXGA (1280x1024)
* 10 = FRAMESIZE_UXGA (1600x1200)
+
+* only boards with PSRAM should be used, to enable PSRAM board should be se set to esp32cam in common32 of platform_override.ini
+* board = esp32cam
+* to speed up cam processing cpu frequency should be better set to 240Mhz in common32 of platform_override.ini
+* board_build.f_cpu = 240000000L
\*********************************************************************************************/
#define XDRV_39 39
@@ -673,7 +678,7 @@ void CmndWC(void) {
uint32_t flag = 0;
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) {
wc_set_streamserver(XdrvMailbox.payload);
- wc_setup(flag);
+ wc_setup(XdrvMailbox.payload);
}
if (CamServer) { flag = 1; }
Response_P(PSTR("{\"" D_CMND_WC "\":{\"Streaming\":\"%s\"}"),GetStateText(flag));
From 0f5ffe5473ad6f560880fb65e6f507fba0cfdff9 Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Mon, 4 May 2020 06:54:24 +0200
Subject: [PATCH 10/22] replace serial print
---
tasmota/xdrv_39_webcam.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index 841684cd0..eeb2dc301 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -524,7 +524,8 @@ void CamHandleRoot(void) {
//CamServer->redirect("http://" + String(ip) + ":81/cam.mjpeg");
CamServer->sendHeader("Location", WiFi.localIP().toString() + ":81/cam.mjpeg");
CamServer->send(302, "", "");
- Serial.printf("WC root called");
+ //Serial.printf("WC root called");
+ AddLog_P2(WC_LOGLEVEL, PSTR("CAM: root called"));
}
uint16_t motion_detect;
From 9824b64a512fe42ecbce7f06532882e42fd85cdc Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 4 May 2020 08:42:15 +0200
Subject: [PATCH 11/22] CI for ESP32
in a different process to see the failures for ESP8266 and ESP32
---
.github/workflows/CI_github_ESP32.yml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 .github/workflows/CI_github_ESP32.yml
diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml
new file mode 100644
index 000000000..aeeb0e9ce
--- /dev/null
+++ b/.github/workflows/CI_github_ESP32.yml
@@ -0,0 +1,22 @@
+name: Tasmota ESP32 CI
+
+on: [push, pull_request]
+
+jobs:
+ tasmota32:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - name: Set up Python
+ uses: actions/setup-python@v1
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -U platformio
+ platformio upgrade --dev
+ platformio update
+ - name: Run PlatformIO
+ run: |
+ cp platformio_override_sample.ini platformio_override.ini
+ platformio run -e tasmota32
+
From b16c9e93e42447dfefb28e582edd63f9b8451462 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 4 May 2020 10:07:47 +0200
Subject: [PATCH 12/22] Turn issue bot off
since it is not working correctly at the moment.
Bot closes wrongly. See #8334
---
.github/{issue-close-app.yml => issue-close-app.yml.off} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename .github/{issue-close-app.yml => issue-close-app.yml.off} (100%)
diff --git a/.github/issue-close-app.yml b/.github/issue-close-app.yml.off
similarity index 100%
rename from .github/issue-close-app.yml
rename to .github/issue-close-app.yml.off
From 23a9948d294dcbe39bb4f75553458cfe5b9488aa Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 4 May 2020 11:07:52 +0200
Subject: [PATCH 13/22] Fix ESP32 compilation
---
tasmota/support_tasmota.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index e789d0cc9..47aca2397 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -1545,7 +1545,7 @@ void GpioInit(void)
if (PinUsed(GPIO_LED1, i)) {
#ifdef USE_ARILUX_RF
if ((3 == i) && (leds_present < 2) && !PinUsed(GPIO_ARIRFSEL)) {
- SetPin(Pin(GPIO_LED4), GPIO_ARIRFSEL); // Legacy support where LED4 was Arilux RF enable
+ SetPin(Pin(GPIO_LED1, i), GPIO_ARIRFSEL); // Legacy support where LED4 was Arilux RF enable
} else {
#endif
pinMode(Pin(GPIO_LED1, i), OUTPUT);
From 8f9bc1e5f7c20e2a9a719307df0c43175df93030 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 4 May 2020 12:48:42 +0200
Subject: [PATCH 14/22] Cleanup ESP32 webcam
---
tasmota/settings.h | 4 +-
tasmota/tasmota_template_ESP32.h | 365 +++++++++++--------------------
tasmota/xdrv_39_webcam.ino | 50 ++---
3 files changed, 150 insertions(+), 269 deletions(-)
diff --git a/tasmota/settings.h b/tasmota/settings.h
index 7a7c7705c..8eadf12b7 100644
--- a/tasmota/settings.h
+++ b/tasmota/settings.h
@@ -365,7 +365,9 @@ struct {
myio my_gp; // 3AC - 2 x 40 bytes (ESP32)
mytmplt user_template; // 3FC - 2 x 37 bytes (ESP32)
- uint8_t free_esp32_446[11]; // 446
+ uint8_t free_esp32_446[10]; // 446
+
+ uint8_t esp32_webcam_resolution; // 450 - not used yet
#endif // ESP8266 - ESP32
char serial_delimiter; // 451
diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h
index 80f4b56dd..e743e59e6 100644
--- a/tasmota/tasmota_template_ESP32.h
+++ b/tasmota/tasmota_template_ESP32.h
@@ -1,5 +1,5 @@
/*
- tasmota_template_ESP32.h - template settings for Tasmota
+ tasmota_template_ESP32.h - ESP32 template settings for Tasmota
Copyright (C) 2020 Theo Arends
@@ -43,181 +43,86 @@
#undef USE_PS_16_DZ
enum UserSelectablePins {
- GPIO_NONE, // Not used
- GPIO_KEY1, // 4 x Button usually connected to GPIO0
- GPIO_KEY1_NP,
- GPIO_KEY1_INV,
- GPIO_KEY1_INV_NP,
- GPIO_SWT1, // 8 x User connected external switches
- GPIO_SWT1_NP,
- GPIO_REL1, // 8 x Relays
- GPIO_REL1_INV,
- GPIO_LED1, // 4 x Leds
- GPIO_LED1_INV,
- GPIO_CNTR1, // 4 x Counter
- GPIO_CNTR1_NP,
- GPIO_PWM1, // 5 x PWM
- GPIO_PWM1_INV,
- GPIO_BUZZER, // Buzzer
- GPIO_BUZZER_INV, // Inverted buzzer
- GPIO_LEDLNK, // Link led
- GPIO_LEDLNK_INV, // Inverted link led
- GPIO_I2C_SCL, // I2C SCL
- GPIO_I2C_SDA, // I2C SDA
- GPIO_SPI_MISO, // SPI MISO
- GPIO_SPI_MOSI, // SPI MOSI
- GPIO_SPI_CLK, // SPI Clk
- GPIO_SPI_CS, // SPI Chip Select
- GPIO_SPI_DC, // SPI Data Direction
- GPIO_SSPI_MISO, // Software SPI Master Input Slave Output
- GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input
- GPIO_SSPI_SCLK, // Software SPI Serial Clock
- GPIO_SSPI_CS, // Software SPI Chip Select
- GPIO_SSPI_DC, // Software SPI Data or Command
- GPIO_BACKLIGHT, // Display backlight control
- GPIO_OLED_RESET, // OLED Display Reset
- GPIO_IRSEND, // IR remote
- GPIO_IRRECV, // IR receiver
- GPIO_RFSEND, // RF transmitter
- GPIO_RFRECV, // RF receiver
- GPIO_DHT11, // DHT11
- GPIO_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321
- GPIO_SI7021, // iTead SI7021
- GPIO_DHT11_OUT, // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
- GPIO_DSB, // Single wire DS18B20 or DS18S20
- GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20
- GPIO_WS2812, // WS2812 Led string
- GPIO_MHZ_TXD, // MH-Z19 Serial interface
- GPIO_MHZ_RXD, // MH-Z19 Serial interface
- GPIO_PZEM0XX_TX, // PZEM0XX Serial interface
- GPIO_PZEM004_RX, // PZEM004T Serial interface
- GPIO_PZEM016_RX, // PZEM-014,016 Serial Modbus interface
- GPIO_PZEM017_RX, // PZEM-003,017 Serial Modbus interface
- GPIO_SAIR_TX, // SenseAir Serial interface
- GPIO_SAIR_RX, // SenseAir Serial interface
- GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface
- GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface
- GPIO_SDS0X1_TX, // Nova Fitness SDS011 Serial interface
- GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface
- GPIO_SBR_TX, // Serial Bridge Serial interface
- GPIO_SBR_RX, // Serial Bridge Serial interface
- GPIO_SR04_TRIG, // SR04 Trigger/TX pin
- GPIO_SR04_ECHO, // SR04 Echo/RX pin
- GPIO_SDM120_TX, // SDM120 Serial interface
- GPIO_SDM120_RX, // SDM120 Serial interface
- GPIO_SDM630_TX, // SDM630 Serial interface
- GPIO_SDM630_RX, // SDM630 Serial interface
- GPIO_TM16CLK, // TM1638 Clock
- GPIO_TM16DIO, // TM1638 Data I/O
- GPIO_TM16STB, // TM1638 Strobe
- GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player
- GPIO_HX711_SCK, // HX711 Load Cell clock
- GPIO_HX711_DAT, // HX711 Load Cell data
- GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin
- GPIO_TUYA_TX, // Tuya Serial interface
- GPIO_TUYA_RX, // Tuya Serial interface
- GPIO_MGC3130_XFER, // MGC3130 Transfer
- GPIO_MGC3130_RESET, // MGC3130 Reset
- GPIO_RF_SENSOR, // Rf receiver with sensor decoding
- GPIO_AZ_TXD, // AZ-Instrument 7798 Serial interface
- GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface
- GPIO_MAX31855CS, // MAX31855 Serial interface
- GPIO_MAX31855CLK, // MAX31855 Serial interface
- GPIO_MAX31855DO, // MAX31855 Serial interface
- GPIO_NRG_SEL, // HLW8012/HLJ-01 Sel output (1 = Voltage)
- GPIO_NRG_SEL_INV, // HLW8012/HLJ-01 Sel output (0 = Voltage)
- GPIO_NRG_CF1, // HLW8012/HLJ-01 CF1 voltage / current
- GPIO_HLW_CF, // HLW8012 CF power
- GPIO_HJL_CF, // HJL-01/BL0937 CF power
- GPIO_MCP39F5_TX, // MCP39F501 Serial interface (Shelly2)
- GPIO_MCP39F5_RX, // MCP39F501 Serial interface (Shelly2)
- GPIO_MCP39F5_RST, // MCP39F501 Reset (Shelly2)
- GPIO_PN532_TXD, // PN532 NFC Serial Tx
- GPIO_PN532_RXD, // PN532 NFC Serial Rx
- GPIO_SM16716_CLK, // SM16716 CLOCK
- GPIO_SM16716_DAT, // SM16716 DATA
- GPIO_SM16716_SEL, // SM16716 SELECT
- GPIO_DI, // my92x1 PWM input
- GPIO_DCKI, // my92x1 CLK input
- GPIO_CSE7766_TX, // CSE7766 Serial interface (S31 and Pow R2) - Not used anymore 20200121
- GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2)
- GPIO_ARIRFRCV, // AriLux RF Receive input
- GPIO_TXD, // Serial interface
- GPIO_RXD, // Serial interface
- GPIO_ROT1A, // Rotary switch1 A Pin
- GPIO_ROT1B, // Rotary switch1 B Pin
- GPIO_ROT2A, // Rotary switch2 A Pin
- GPIO_ROT2B, // Rotary switch2 B Pin
- GPIO_HRE_CLOCK, // Clock/Power line for HR-E Water Meter
- GPIO_HRE_DATA, // Data line for HR-E Water Meter
- GPIO_ADE7953_IRQ, // ADE7953 IRQ
- GPIO_ARIRFSEL, // Arilux RF Receive input selected
- GPIO_SOLAXX1_TX, // Solax Inverter tx pin
- GPIO_SOLAXX1_RX, // Solax Inverter rx pin
- GPIO_ZIGBEE_TX, // Zigbee Serial interface
- GPIO_ZIGBEE_RX, // Zigbee Serial interface
- GPIO_RDM6300_RX, // RDM6300 RX
- GPIO_IBEACON_TX, // HM17 IBEACON TX
- GPIO_IBEACON_RX, // HM17 IBEACON RX
- GPIO_A4988_DIR, // A4988 direction pin
- GPIO_A4988_STP, // A4988 step pin
- GPIO_A4988_ENA, // A4988 enabled pin
- GPIO_A4988_MS1, // A4988 microstep pin1
- GPIO_A4988_MS2, // A4988 microstep pin2
- GPIO_A4988_MS3, // A4988 microstep pin3
- GPIO_DDS2382_TX, // DDS2382 Serial interface
- GPIO_DDS2382_RX, // DDS2382 Serial interface
- GPIO_DDSU666_TX, // DDSU666 Serial interface
- GPIO_DDSU666_RX, // DDSU666 Serial interface
- GPIO_SM2135_CLK, // SM2135 Clk
- GPIO_SM2135_DAT, // SM2135 Dat
- GPIO_DEEPSLEEP, // Kill switch for deepsleep
- GPIO_EXS_ENABLE, // EXS MCU Enable
- GPIO_TASMOTASLAVE_TXD, // Slave TX
- GPIO_TASMOTASLAVE_RXD, // Slave RX
- GPIO_TASMOTASLAVE_RST, // Slave Reset Pin
- GPIO_TASMOTASLAVE_RST_INV, // Slave Reset Inverted
- GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface
- GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface
- GPIO_GPS_RX, // GPS serial interface
- GPIO_GPS_TX, // GPS serial interface
- GPIO_HM10_RX, // HM10-BLE-Mijia-bridge serial interface
- GPIO_HM10_TX, // HM10-BLE-Mijia-bridge serial interface
- GPIO_LE01MR_RX, // F&F LE-01MR energy meter
- GPIO_LE01MR_TX, // F&F LE-01MR energy meter
- GPIO_CC1101_GDO0, // CC1101 pin for RX
- GPIO_CC1101_GDO2, // CC1101 pin for RX
- GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor
- GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX
+ GPIO_NONE, // Not used
+ GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button
+ GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches
+ GPIO_REL1, GPIO_REL1_INV, // 8 x Relays
+ GPIO_LED1, GPIO_LED1_INV, // 4 x Leds
+ GPIO_CNTR1, GPIO_CNTR1_NP, // 4 x Counter
+ GPIO_PWM1, GPIO_PWM1_INV, // 5 x PWM
+ GPIO_BUZZER, GPIO_BUZZER_INV, // Buzzer
+ GPIO_LEDLNK, GPIO_LEDLNK_INV, // Link led
+ GPIO_I2C_SCL, GPIO_I2C_SDA, // Software I2C
+ GPIO_SPI_MISO, GPIO_SPI_MOSI, GPIO_SPI_CLK, GPIO_SPI_CS, GPIO_SPI_DC, // Hardware SPI
+ GPIO_SSPI_MISO, GPIO_SSPI_MOSI, GPIO_SSPI_SCLK, GPIO_SSPI_CS, GPIO_SSPI_DC, // Software SPI
+ GPIO_BACKLIGHT, // Display backlight control
+ GPIO_OLED_RESET, // OLED Display Reset
+ GPIO_IRSEND, GPIO_IRRECV, // IR interface
+ GPIO_RFSEND, GPIO_RFRECV, // RF interface
+ GPIO_DHT11, GPIO_DHT22, GPIO_SI7021, GPIO_DHT11_OUT, // DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
+ GPIO_DSB, GPIO_DSB_OUT, // DS18B20 or DS18S20
+ GPIO_WS2812, // WS2812 Led string
+ GPIO_MHZ_TXD, GPIO_MHZ_RXD, // MH-Z19 Serial interface
+ GPIO_PZEM0XX_TX, GPIO_PZEM004_RX, GPIO_PZEM016_RX, GPIO_PZEM017_RX, // PZEM Serial Modbus interface
+ GPIO_SAIR_TX, GPIO_SAIR_RX, // SenseAir Serial interface
+ GPIO_PMS5003_TX, GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface
+ GPIO_SDS0X1_TX, GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface
+ GPIO_SBR_TX, GPIO_SBR_RX, // Serial Bridge Serial interface
+ GPIO_SR04_TRIG, GPIO_SR04_ECHO, // SR04 interface
+ GPIO_SDM120_TX, GPIO_SDM120_RX, // SDM120 Serial interface
+ GPIO_SDM630_TX, GPIO_SDM630_RX, // SDM630 Serial interface
+ GPIO_TM16CLK, GPIO_TM16DIO, GPIO_TM16STB, // TM1638 interface
+ GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player
+ GPIO_HX711_SCK, GPIO_HX711_DAT, // HX711 Load Cell interface
+ GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin
+ GPIO_TUYA_TX, GPIO_TUYA_RX, // Tuya Serial interface
+ GPIO_MGC3130_XFER, GPIO_MGC3130_RESET, // MGC3130 interface
+ GPIO_RF_SENSOR, // Rf receiver with sensor decoding
+ GPIO_AZ_TXD, GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface
+ GPIO_MAX31855CS, GPIO_MAX31855CLK, GPIO_MAX31855DO, // MAX31855 Serial interface
+ GPIO_NRG_SEL, GPIO_NRG_SEL_INV, GPIO_NRG_CF1, GPIO_HLW_CF, GPIO_HJL_CF, // HLW8012/HJL-01/BL0937 energy monitoring
+ GPIO_MCP39F5_TX, GPIO_MCP39F5_RX, GPIO_MCP39F5_RST, // MCP39F501 Energy monitoring (Shelly2)
+ GPIO_PN532_TXD, GPIO_PN532_RXD, // PN532 NFC Serial interface
+ GPIO_SM16716_CLK, GPIO_SM16716_DAT, GPIO_SM16716_SEL, // SM16716 SELECT
+ GPIO_DI, GPIO_DCKI, // my92x1 PWM controller
+ GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2)
+ GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input
+ GPIO_TXD, GPIO_RXD, // Serial interface
+ GPIO_ROT1A, GPIO_ROT1B, GPIO_ROT2A, GPIO_ROT2B, // Rotary switch
+ GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter
+ GPIO_ADE7953_IRQ, // ADE7953 IRQ
+ GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface
+ GPIO_ZIGBEE_TX, GPIO_ZIGBEE_RX, // Zigbee Serial interface
+ GPIO_RDM6300_RX, // RDM6300 RX
+ GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface
+ GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, // A4988 interface
+ GPIO_A4988_MS1, GPIO_A4988_MS2, GPIO_A4988_MS3, // A4988 microstep
+ GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface
+ GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface
+ GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller
+ GPIO_DEEPSLEEP, // Kill switch for deepsleep
+ GPIO_EXS_ENABLE, // EXS MCU Enable
+ GPIO_TASMOTASLAVE_TXD, GPIO_TASMOTASLAVE_RXD, // Slave Serial interface
+ GPIO_TASMOTASLAVE_RST, GPIO_TASMOTASLAVE_RST_INV, // Slave Reset
+ GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface
+ GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface
+ GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface
+ GPIO_LE01MR_RX, GPIO_LE01MR_TX, // F&F LE-01MR energy meter
+ GPIO_CC1101_GDO0, GPIO_CC1101_GDO2, // CC1101 Serial interface
+ GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor
+ GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX
GPIO_AS3935,
- ADC0_INPUT, // Analog input
- ADC0_TEMP, // Thermistor
- ADC0_LIGHT, // Light sensor
- ADC0_BUTTON, // Button
- ADC0_BUTTON_INV,
- ADC0_RANGE, // Range
- ADC0_CT_POWER, // Current
- GPIO_WEBCAM_PWDN_GPIO_NUM, // Webcam interface
- GPIO_WEBCAM_RESET_GPIO_NUM,
- GPIO_WEBCAM_XCLK_GPIO_NUM,
- GPIO_WEBCAM_SIOD_GPIO_NUM,
- GPIO_WEBCAM_SIOC_GPIO_NUM,
- GPIO_WEBCAM_Y9_GPIO_NUM,
- GPIO_WEBCAM_Y8_GPIO_NUM,
- GPIO_WEBCAM_Y7_GPIO_NUM,
- GPIO_WEBCAM_Y6_GPIO_NUM,
- GPIO_WEBCAM_Y5_GPIO_NUM,
- GPIO_WEBCAM_Y4_GPIO_NUM,
- GPIO_WEBCAM_Y3_GPIO_NUM,
- GPIO_WEBCAM_Y2_GPIO_NUM,
- GPIO_WEBCAM_VSYNC_GPIO_NUM,
- GPIO_WEBCAM_HREF_GPIO_NUM,
- GPIO_WEBCAM_PCLK_GPIO_NUM,
- GPIO_WEBCAM_PSCLK_GPIO_NUM,
- GPIO_WEBCAM_HSD1_GPIO_NUM,
- GPIO_WEBCAM_HSD2_GPIO_NUM,
- GPIO_WEBCAM_HSD3_GPIO_NUM,
- GPIO_WEBCAM_PSRCS_GPIO_NUM,
+ ADC0_INPUT, // Analog input
+ ADC0_TEMP, // Analog Thermistor
+ ADC0_LIGHT, // Analog Light sensor
+ ADC0_BUTTON, ADC0_BUTTON_INV, // Analog Button
+ ADC0_RANGE, // Analog Range
+ ADC0_CT_POWER, // ANalog Current
+ GPIO_WEBCAM_PWDN, GPIO_WEBCAM_RESET, GPIO_WEBCAM_XCLK, GPIO_WEBCAM_SIOD, GPIO_WEBCAM_SIOC, // Webcam
+ GPIO_WEBCAM_Y9, GPIO_WEBCAM_Y8, GPIO_WEBCAM_Y7, GPIO_WEBCAM_Y6,
+ GPIO_WEBCAM_Y5, GPIO_WEBCAM_Y4, GPIO_WEBCAM_Y3, GPIO_WEBCAM_Y2,
+ GPIO_WEBCAM_VSYNC, GPIO_WEBCAM_HREF, GPIO_WEBCAM_PCLK, GPIO_WEBCAM_PSCLK,
+ GPIO_WEBCAM_HSD1, GPIO_WEBCAM_HSD2, GPIO_WEBCAM_HSD3, GPIO_WEBCAM_PSRCS,
GPIO_SENSOR_END };
enum ProgramSelectablePins {
@@ -229,22 +134,13 @@ enum ProgramSelectablePins {
// Text in webpage Module Parameters and commands GPIOS and GPIO
const char kSensorNames[] PROGMEM =
D_SENSOR_NONE "|"
- D_SENSOR_BUTTON "|"
- D_SENSOR_BUTTON "n|"
- D_SENSOR_BUTTON "i|"
- D_SENSOR_BUTTON "in|"
- D_SENSOR_SWITCH "|"
- D_SENSOR_SWITCH "n|"
- D_SENSOR_RELAY "|"
- D_SENSOR_RELAY "i|"
- D_SENSOR_LED "|"
- D_SENSOR_LED "i|"
- D_SENSOR_COUNTER "|"
- D_SENSOR_COUNTER "n|"
- D_SENSOR_PWM "|"
- D_SENSOR_PWM "i|"
- D_SENSOR_BUZZER "|"
- D_SENSOR_BUZZER "i|"
+ D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "n|" D_SENSOR_BUTTON "i|" D_SENSOR_BUTTON "in|"
+ D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "n|"
+ D_SENSOR_RELAY "|" D_SENSOR_RELAY "i|"
+ D_SENSOR_LED "|" D_SENSOR_LED "i|"
+ D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "n|"
+ D_SENSOR_PWM "|" D_SENSOR_PWM "i|"
+ D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "i|"
D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "i|"
D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|"
D_SENSOR_SPI_MISO "|" D_SENSOR_SPI_MOSI "|" D_SENSOR_SPI_CLK "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|"
@@ -279,12 +175,11 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER "|"
D_SENSOR_MY92X1_DI "|" D_SENSOR_MY92X1_DCKI "|"
D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|"
- D_SENSOR_ARIRFRCV "|"
+ D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|"
D_SENSOR_TXD "|" D_SENSOR_RXD "|"
D_SENSOR_ROTARY "1a|" D_SENSOR_ROTARY "1b|" D_SENSOR_ROTARY "2a|" D_SENSOR_ROTARY "2b|"
D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|"
D_SENSOR_ADE7953_IRQ "|"
- D_SENSOR_ARIRFSEL "|"
D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|"
D_SENSOR_ZIGBEE_TXD "|" D_SENSOR_ZIGBEE_RXD "|"
D_SENSOR_RDM6300_RX "|"
@@ -308,34 +203,18 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "i|"
D_RANGE "|"
D_CT_POWER "|"
- D_GPIO_WEBCAM_PWDN_GPIO_NUM "|"
- D_GPIO_WEBCAM_RESET_GPIO_NUM "|"
- D_GPIO_WEBCAM_XCLK_GPIO_NUM "|"
- D_GPIO_WEBCAM_SIOD_GPIO_NUM "|"
- D_GPIO_WEBCAM_SIOC_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y9_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y8_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y7_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y6_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y5_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y4_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y3_GPIO_NUM "|"
- D_GPIO_WEBCAM_Y2_GPIO_NUM "|"
- D_GPIO_WEBCAM_VSYNC_GPIO_NUM "|"
- D_GPIO_WEBCAM_HREF_GPIO_NUM "|"
- D_GPIO_WEBCAM_PCLK_GPIO_NUM "|"
- D_GPIO_WEBCAM_PSCLK_GPIO_NUM "|"
- D_GPIO_WEBCAM_HSD1_GPIO_NUM "|"
- D_GPIO_WEBCAM_HSD2_GPIO_NUM "|"
- D_GPIO_WEBCAM_HSD3_GPIO_NUM "|"
- D_GPIO_WEBCAM_PSRCS_GPIO_NUM
+ D_GPIO_WEBCAM_PWDN "|" D_GPIO_WEBCAM_RESET "|" D_GPIO_WEBCAM_XCLK "|" D_GPIO_WEBCAM_SIOD "|" D_GPIO_WEBCAM_SIOC "|"
+ D_GPIO_WEBCAM_Y9 "|" D_GPIO_WEBCAM_Y8 "|" D_GPIO_WEBCAM_Y7 "|" D_GPIO_WEBCAM_Y6 "|"
+ D_GPIO_WEBCAM_Y5 "|" D_GPIO_WEBCAM_Y4 "|" D_GPIO_WEBCAM_Y3 "|" D_GPIO_WEBCAM_Y2 "|"
+ D_GPIO_WEBCAM_VSYNC "|" D_GPIO_WEBCAM_HREF "|" D_GPIO_WEBCAM_PCLK "|" D_GPIO_WEBCAM_PSCLK "|"
+ D_GPIO_WEBCAM_HSD1 "|" D_GPIO_WEBCAM_HSD2 "|" D_GPIO_WEBCAM_HSD3 "|" D_GPIO_WEBCAM_PSRCS
;
const char kSensorNamesFixed[] PROGMEM =
D_SENSOR_USER;
const uint16_t kGpioNiceList[] PROGMEM = {
- GPIO_NONE, // Not used
+ GPIO_NONE, // Not used
AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons
AGPIO(GPIO_KEY1_NP) + MAX_KEYS,
AGPIO(GPIO_KEY1_INV) + MAX_KEYS,
@@ -353,14 +232,14 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_PWM1) + MAX_PWMS, // RGB Red or C Cold White
AGPIO(GPIO_PWM1_INV) + MAX_PWMS,
#ifdef USE_BUZZER
- AGPIO(GPIO_BUZZER), // Buzzer
- AGPIO(GPIO_BUZZER_INV), // Inverted buzzer
+ AGPIO(GPIO_BUZZER), // Buzzer
+ AGPIO(GPIO_BUZZER_INV), // Inverted buzzer
#endif
- AGPIO(GPIO_LEDLNK), // Link led
- AGPIO(GPIO_LEDLNK_INV), // Inverted link led
+ AGPIO(GPIO_LEDLNK), // Link led
+ AGPIO(GPIO_LEDLNK_INV), // Inverted link led
#ifdef USE_I2C
- AGPIO(GPIO_I2C_SCL), // I2C SCL
- AGPIO(GPIO_I2C_SDA), // I2C SDA
+ AGPIO(GPIO_I2C_SCL), // I2C SCL
+ AGPIO(GPIO_I2C_SDA), // I2C SDA
#endif
#ifdef USE_SPI
AGPIO(GPIO_SPI_MISO), // SPI MISO
@@ -631,28 +510,28 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(ADC0_CT_POWER), // Current
#endif
*/
-#if defined(ESP32) && defined(USE_WEBCAM)
-AGPIO(GPIO_WEBCAM_PWDN_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_RESET_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_XCLK_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_SIOD_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_SIOC_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y9_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y8_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y7_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y6_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y5_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y4_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y3_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_Y2_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_VSYNC_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_HREF_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_PCLK_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_PSCLK_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_HSD1_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_HSD2_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_HSD3_GPIO_NUM),
-AGPIO(GPIO_WEBCAM_PSRCS_GPIO_NUM),
+#ifdef USE_WEBCAM
+ AGPIO(GPIO_WEBCAM_PWDN),
+ AGPIO(GPIO_WEBCAM_RESET),
+ AGPIO(GPIO_WEBCAM_XCLK),
+ AGPIO(GPIO_WEBCAM_SIOD),
+ AGPIO(GPIO_WEBCAM_SIOC),
+ AGPIO(GPIO_WEBCAM_Y9),
+ AGPIO(GPIO_WEBCAM_Y8),
+ AGPIO(GPIO_WEBCAM_Y7),
+ AGPIO(GPIO_WEBCAM_Y6),
+ AGPIO(GPIO_WEBCAM_Y5),
+ AGPIO(GPIO_WEBCAM_Y4),
+ AGPIO(GPIO_WEBCAM_Y3),
+ AGPIO(GPIO_WEBCAM_Y2),
+ AGPIO(GPIO_WEBCAM_VSYNC),
+ AGPIO(GPIO_WEBCAM_HREF),
+ AGPIO(GPIO_WEBCAM_PCLK),
+ AGPIO(GPIO_WEBCAM_PSCLK),
+ AGPIO(GPIO_WEBCAM_HSD1),
+ AGPIO(GPIO_WEBCAM_HSD2),
+ AGPIO(GPIO_WEBCAM_HSD3),
+ AGPIO(GPIO_WEBCAM_PSRCS),
#endif
};
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index eeb2dc301..f161e1ea0 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -39,11 +39,11 @@
* 8 = FRAMESIZE_XGA (1024x768)
* 9 = FRAMESIZE_SXGA (1280x1024)
* 10 = FRAMESIZE_UXGA (1600x1200)
-
-* only boards with PSRAM should be used, to enable PSRAM board should be se set to esp32cam in common32 of platform_override.ini
-* board = esp32cam
-* to speed up cam processing cpu frequency should be better set to 240Mhz in common32 of platform_override.ini
-* board_build.f_cpu = 240000000L
+ *
+ * Only boards with PSRAM should be used. To enable PSRAM board should be se set to esp32cam in common32 of platform_override.ini
+ * board = esp32cam
+ * To speed up cam processing cpu frequency should be better set to 240Mhz in common32 of platform_override.ini
+ * board_build.f_cpu = 240000000L
\*********************************************************************************************/
#define XDRV_39 39
@@ -125,29 +125,29 @@ uint32_t wc_setup(int32_t fsiz) {
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
#else
- if (PinUsed(GPIO_WEBCAM_Y2_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y3_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y4_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y5_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_Y6_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y7_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y8_GPIO_NUM) && PinUsed(GPIO_WEBCAM_Y9_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_XCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_PCLK_GPIO_NUM) && PinUsed(GPIO_WEBCAM_VSYNC_GPIO_NUM) && PinUsed(GPIO_WEBCAM_HREF_GPIO_NUM)\
- && PinUsed(GPIO_WEBCAM_SIOD_GPIO_NUM) && PinUsed(GPIO_WEBCAM_SIOC_GPIO_NUM)) {
- config.pin_d0 = Pin(GPIO_WEBCAM_Y2_GPIO_NUM); //Y2_GPIO_NUM;
- config.pin_d1 = Pin(GPIO_WEBCAM_Y3_GPIO_NUM); //Y3_GPIO_NUM;
- config.pin_d2 = Pin(GPIO_WEBCAM_Y4_GPIO_NUM); //Y4_GPIO_NUM;
- config.pin_d3 = Pin(GPIO_WEBCAM_Y5_GPIO_NUM); //Y5_GPIO_NUM;
- config.pin_d4 = Pin(GPIO_WEBCAM_Y6_GPIO_NUM); //Y6_GPIO_NUM;
- config.pin_d5 = Pin(GPIO_WEBCAM_Y7_GPIO_NUM); //Y7_GPIO_NUM;
- config.pin_d6 = Pin(GPIO_WEBCAM_Y8_GPIO_NUM); //Y8_GPIO_NUM;
- config.pin_d7 = Pin(GPIO_WEBCAM_Y9_GPIO_NUM); //Y9_GPIO_NUM;
- config.pin_xclk = Pin(GPIO_WEBCAM_XCLK_GPIO_NUM); //XCLK_GPIO_NUM;
- config.pin_pclk = Pin(GPIO_WEBCAM_PCLK_GPIO_NUM); //PCLK_GPIO_NUM;
- config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC_GPIO_NUM); //VSYNC_GPIO_NUM;
- config.pin_href = Pin(GPIO_WEBCAM_HREF_GPIO_NUM); //HREF_GPIO_NUM;
- config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD_GPIO_NUM); //SIOD_GPIO_NUM;
- config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC_GPIO_NUM); //SIOC_GPIO_NUM;
+ if (PinUsed(GPIO_WEBCAM_Y2) && PinUsed(GPIO_WEBCAM_Y3) && PinUsed(GPIO_WEBCAM_Y4) && PinUsed(GPIO_WEBCAM_Y5)\
+ && PinUsed(GPIO_WEBCAM_Y6) && PinUsed(GPIO_WEBCAM_Y7) && PinUsed(GPIO_WEBCAM_Y8) && PinUsed(GPIO_WEBCAM_Y9)\
+ && PinUsed(GPIO_WEBCAM_XCLK) && PinUsed(GPIO_WEBCAM_PCLK) && PinUsed(GPIO_WEBCAM_VSYNC) && PinUsed(GPIO_WEBCAM_HREF)\
+ && PinUsed(GPIO_WEBCAM_SIOD) && PinUsed(GPIO_WEBCAM_SIOC)) {
+ config.pin_d0 = Pin(GPIO_WEBCAM_Y2); //Y2_GPIO_NUM;
+ config.pin_d1 = Pin(GPIO_WEBCAM_Y3); //Y3_GPIO_NUM;
+ config.pin_d2 = Pin(GPIO_WEBCAM_Y4); //Y4_GPIO_NUM;
+ config.pin_d3 = Pin(GPIO_WEBCAM_Y5); //Y5_GPIO_NUM;
+ config.pin_d4 = Pin(GPIO_WEBCAM_Y6); //Y6_GPIO_NUM;
+ config.pin_d5 = Pin(GPIO_WEBCAM_Y7); //Y7_GPIO_NUM;
+ config.pin_d6 = Pin(GPIO_WEBCAM_Y8); //Y8_GPIO_NUM;
+ config.pin_d7 = Pin(GPIO_WEBCAM_Y9); //Y9_GPIO_NUM;
+ config.pin_xclk = Pin(GPIO_WEBCAM_XCLK); //XCLK_GPIO_NUM;
+ config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); //PCLK_GPIO_NUM;
+ config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); //VSYNC_GPIO_NUM;
+ config.pin_href = Pin(GPIO_WEBCAM_HREF); //HREF_GPIO_NUM;
+ config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD); //SIOD_GPIO_NUM;
+ config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC); //SIOC_GPIO_NUM;
int16_t xpin;
- xpin = Pin(GPIO_WEBCAM_PWDN_GPIO_NUM);
+ xpin = Pin(GPIO_WEBCAM_PWDN);
if (99 == xpin) { xpin = -1; }
config.pin_pwdn = xpin; //PWDN_GPIO_NUM;
- xpin = Pin(GPIO_WEBCAM_RESET_GPIO_NUM);
+ xpin = Pin(GPIO_WEBCAM_RESET);
if (99 == xpin) { xpin=-1; }
config.pin_reset = xpin; //RESET_GPIO_NUM;
} else {
From 8bb718a741958cc0204c32b51d36ad3d3fa4af45 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 4 May 2020 14:17:19 +0200
Subject: [PATCH 15/22] Revert "Turn issue bot off"
This reverts commit b16c9e93e42447dfefb28e582edd63f9b8451462.
---
.github/{issue-close-app.yml.off => issue-close-app.yml} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename .github/{issue-close-app.yml.off => issue-close-app.yml} (100%)
diff --git a/.github/issue-close-app.yml.off b/.github/issue-close-app.yml
similarity index 100%
rename from .github/issue-close-app.yml.off
rename to .github/issue-close-app.yml
From c66f14baae1caeafc974a7e57368948207dd16f4 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 4 May 2020 14:33:23 +0200
Subject: [PATCH 16/22] Fix ESP32 compilation
---
tasmota/language/bg-BG.h | 42 ++++++++++++++++++++--------------------
tasmota/language/cs-CZ.h | 42 ++++++++++++++++++++--------------------
tasmota/language/de-DE.h | 42 ++++++++++++++++++++--------------------
tasmota/language/el-GR.h | 42 ++++++++++++++++++++--------------------
tasmota/language/en-GB.h | 42 ++++++++++++++++++++--------------------
tasmota/language/es-ES.h | 42 ++++++++++++++++++++--------------------
tasmota/language/fr-FR.h | 42 ++++++++++++++++++++--------------------
tasmota/language/he-HE.h | 42 ++++++++++++++++++++--------------------
tasmota/language/hu-HU.h | 42 ++++++++++++++++++++--------------------
tasmota/language/it-IT.h | 42 ++++++++++++++++++++--------------------
tasmota/language/ko-KO.h | 42 ++++++++++++++++++++--------------------
tasmota/language/nl-NL.h | 42 ++++++++++++++++++++--------------------
tasmota/language/pl-PL.h | 42 ++++++++++++++++++++--------------------
tasmota/language/pt-BR.h | 42 ++++++++++++++++++++--------------------
tasmota/language/pt-PT.h | 42 ++++++++++++++++++++--------------------
tasmota/language/ro-RO.h | 42 ++++++++++++++++++++--------------------
tasmota/language/ru-RU.h | 42 ++++++++++++++++++++--------------------
tasmota/language/sk-SK.h | 42 ++++++++++++++++++++--------------------
tasmota/language/sv-SE.h | 42 ++++++++++++++++++++--------------------
tasmota/language/tr-TR.h | 42 ++++++++++++++++++++--------------------
tasmota/language/uk-UA.h | 42 ++++++++++++++++++++--------------------
tasmota/language/zh-CN.h | 42 ++++++++++++++++++++--------------------
tasmota/language/zh-TW.h | 42 ++++++++++++++++++++--------------------
23 files changed, 483 insertions(+), 483 deletions(-)
diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h
index 396720703..95beeacaa 100644
--- a/tasmota/language/bg-BG.h
+++ b/tasmota/language/bg-BG.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h
index a4dd20a8e..2de9a7d4a 100644
--- a/tasmota/language/cs-CZ.h
+++ b/tasmota/language/cs-CZ.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h
index 84a2606a7..f44b96f19 100644
--- a/tasmota/language/de-DE.h
+++ b/tasmota/language/de-DE.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h
index 12c61fabe..a20119739 100644
--- a/tasmota/language/el-GR.h
+++ b/tasmota/language/el-GR.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h
index eef76a921..8aac430e6 100644
--- a/tasmota/language/en-GB.h
+++ b/tasmota/language/en-GB.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h
index db429dbd6..238ebea5f 100644
--- a/tasmota/language/es-ES.h
+++ b/tasmota/language/es-ES.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h
index 0427b56f3..ab027635d 100644
--- a/tasmota/language/fr-FR.h
+++ b/tasmota/language/fr-FR.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h
index 0d1d29808..87872acbd 100644
--- a/tasmota/language/he-HE.h
+++ b/tasmota/language/he-HE.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h
index 4b7e98794..1ff28fd0a 100644
--- a/tasmota/language/hu-HU.h
+++ b/tasmota/language/hu-HU.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h
index 694c85f3f..41a664c77 100644
--- a/tasmota/language/it-IT.h
+++ b/tasmota/language/it-IT.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL - RX"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h
index a9eeef2c1..7f73d51cb 100644
--- a/tasmota/language/ko-KO.h
+++ b/tasmota/language/ko-KO.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h
index 89346fffa..f7a894a42 100644
--- a/tasmota/language/nl-NL.h
+++ b/tasmota/language/nl-NL.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h
index eea75e882..7f0f42777 100644
--- a/tasmota/language/pl-PL.h
+++ b/tasmota/language/pl-PL.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h
index 218c83ccc..b7087cc53 100644
--- a/tasmota/language/pt-BR.h
+++ b/tasmota/language/pt-BR.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h
index e2eb4cbee..380e9d433 100644
--- a/tasmota/language/pt-PT.h
+++ b/tasmota/language/pt-PT.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ro-RO.h b/tasmota/language/ro-RO.h
index 7ed26efb3..31c647aee 100644
--- a/tasmota/language/ro-RO.h
+++ b/tasmota/language/ro-RO.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h
index 45af96454..91122732c 100644
--- a/tasmota/language/ru-RU.h
+++ b/tasmota/language/ru-RU.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h
index c6589ddfd..cee3f02c3 100644
--- a/tasmota/language/sk-SK.h
+++ b/tasmota/language/sk-SK.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h
index faf8a1000..763d862eb 100644
--- a/tasmota/language/sv-SE.h
+++ b/tasmota/language/sv-SE.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h
index 7a2407dd1..ab1bf6d9a 100644
--- a/tasmota/language/tr-TR.h
+++ b/tasmota/language/tr-TR.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "A"
diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk-UA.h
index 986f3efe3..178710633 100644
--- a/tasmota/language/uk-UA.h
+++ b/tasmota/language/uk-UA.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "А"
diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h
index e54501afe..46bc4fd05 100644
--- a/tasmota/language/zh-CN.h
+++ b/tasmota/language/zh-CN.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "安"
diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h
index e495f858d..25c813815 100644
--- a/tasmota/language/zh-TW.h
+++ b/tasmota/language/zh-TW.h
@@ -666,27 +666,27 @@
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
#define D_SENSOR_AS3935 "AS3935"
-#define D_GPIO_WEBCAM_PWDN_GPIO_NUM "CAM_PWDN"
-#define D_GPIO_WEBCAM_RESET_GPIO_NUM "CAM_RESET"
-#define D_GPIO_WEBCAM_XCLK_GPIO_NUM "CAM_XCLK"
-#define D_GPIO_WEBCAM_SIOD_GPIO_NUM "CAM_SIOD"
-#define D_GPIO_WEBCAM_SIOC_GPIO_NUM "CAM_SIOC"
-#define D_GPIO_WEBCAM_Y9_GPIO_NUM "CAM_Y9"
-#define D_GPIO_WEBCAM_Y8_GPIO_NUM "CAM_Y8"
-#define D_GPIO_WEBCAM_Y7_GPIO_NUM "CAM_Y7"
-#define D_GPIO_WEBCAM_Y6_GPIO_NUM "CAM_Y6"
-#define D_GPIO_WEBCAM_Y5_GPIO_NUM "CAM_Y5"
-#define D_GPIO_WEBCAM_Y4_GPIO_NUM "CAM_Y4"
-#define D_GPIO_WEBCAM_Y3_GPIO_NUM "CAM_Y3"
-#define D_GPIO_WEBCAM_Y2_GPIO_NUM "CAM_Y2"
-#define D_GPIO_WEBCAM_VSYNC_GPIO_NUM "CAM_VSYNC"
-#define D_GPIO_WEBCAM_HREF_GPIO_NUM "CAM_HREF"
-#define D_GPIO_WEBCAM_PCLK_GPIO_NUM "CAM_PCLK"
-#define D_GPIO_WEBCAM_PSCLK_GPIO_NUM "CAM_PSCLK"
-#define D_GPIO_WEBCAM_HSD1_GPIO_NUM "CAM_HSD1"
-#define D_GPIO_WEBCAM_HSD2_GPIO_NUM "CAM_HSD2"
-#define D_GPIO_WEBCAM_HSD3_GPIO_NUM "CAM_HSD3"
-#define D_GPIO_WEBCAM_PSRCS_GPIO_NUM "CAM_PSRCS"
+#define D_GPIO_WEBCAM_PWDN "CAM_PWDN"
+#define D_GPIO_WEBCAM_RESET "CAM_RESET"
+#define D_GPIO_WEBCAM_XCLK "CAM_XCLK"
+#define D_GPIO_WEBCAM_SIOD "CAM_SIOD"
+#define D_GPIO_WEBCAM_SIOC "CAM_SIOC"
+#define D_GPIO_WEBCAM_Y9 "CAM_Y9"
+#define D_GPIO_WEBCAM_Y8 "CAM_Y8"
+#define D_GPIO_WEBCAM_Y7 "CAM_Y7"
+#define D_GPIO_WEBCAM_Y6 "CAM_Y6"
+#define D_GPIO_WEBCAM_Y5 "CAM_Y5"
+#define D_GPIO_WEBCAM_Y4 "CAM_Y4"
+#define D_GPIO_WEBCAM_Y3 "CAM_Y3"
+#define D_GPIO_WEBCAM_Y2 "CAM_Y2"
+#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC"
+#define D_GPIO_WEBCAM_HREF "CAM_HREF"
+#define D_GPIO_WEBCAM_PCLK "CAM_PCLK"
+#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK"
+#define D_GPIO_WEBCAM_HSD1 "CAM_HSD1"
+#define D_GPIO_WEBCAM_HSD2 "CAM_HSD2"
+#define D_GPIO_WEBCAM_HSD3 "CAM_HSD3"
+#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS"
// Units
#define D_UNIT_AMPERE "安"
From ecdaed50d65797dea9803b777560995cd27af108 Mon Sep 17 00:00:00 2001
From: Adrian Scillato <35405447+ascillato@users.noreply.github.com>
Date: Mon, 4 May 2020 11:07:43 -0300
Subject: [PATCH 17/22] KNX: Fix for New Internal Pin Handling on ESP32
---
tasmota/xdrv_11_knx.ino | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino
index d6f2864dc..47b62547d 100644
--- a/tasmota/xdrv_11_knx.ino
+++ b/tasmota/xdrv_11_knx.ino
@@ -473,19 +473,19 @@ void KNX_INIT(void)
{
device_param[i].show = true;
}
- for (uint32_t i = GPIO_SWT1; i < GPIO_SWT4 + 1; ++i)
+ for (uint32_t i = GPIO_SWT1; i < GPIO_SWT1 + 4; ++i)
{
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_SWT1 + 8].show = true; }
}
- for (uint32_t i = GPIO_KEY1; i < GPIO_KEY4 + 1; ++i)
+ for (uint32_t i = GPIO_KEY1; i < GPIO_KEY1 + 4; ++i)
{
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_KEY1 + 8].show = true; }
}
- for (uint32_t i = GPIO_SWT1_NP; i < GPIO_SWT4_NP + 1; ++i)
+ for (uint32_t i = GPIO_SWT1_NP; i < GPIO_SWT1_NP + 4; ++i)
{
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_SWT1_NP + 8].show = true; }
}
- for (uint32_t i = GPIO_KEY1_NP; i < GPIO_KEY4_NP + 1; ++i)
+ for (uint32_t i = GPIO_KEY1_NP; i < GPIO_KEY1_NP + 4; ++i)
{
if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_KEY1_NP + 8].show = true; }
}
From abe6b4e4f427dd200cbae3a4db86d56057bff857 Mon Sep 17 00:00:00 2001
From: Adrian Scillato <35405447+ascillato@users.noreply.github.com>
Date: Mon, 4 May 2020 11:25:46 -0300
Subject: [PATCH 18/22] PR Template. Move the CI Pass request to a Note
As the CI Test is done after the PR is submitted, a checkbox for "The code change must pass CI tests" is always left unchecked. It should be better to just add a note that the proposed PR is going to be tested and that the CI Tests must be passed in order to merge the PR. Any CI Test error should be addressed by the author of the PR, before merging.
---
.github/PULL_REQUEST_TEMPLATE.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index dade0687c..d8bb487bd 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -8,5 +8,6 @@
- [ ] Only one feature/fix was added per PR.
- [ ] The code change is tested and works on core ESP8266 V.2.7.0
- [ ] The code change is tested and works on core ESP32 V.1.12.0
- - [ ] The code change pass CI tests. **Your PR cannot be merged unless tests pass**
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
+
+_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_
From 66378f962b0a9f38c78222b8b850e74127befdf9 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 4 May 2020 16:50:56 +0200
Subject: [PATCH 19/22] Hotfix: Use patched Core 2.7.0...
since the new introduced XMC flash OTA handling in eboot.elf does not work. Device is a Softbrick and needs serial flashing.
Replaced eboot.elf with a older working version
Solves #8334
---
platformio.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index b748ce0b9..5074ee432 100755
--- a/platformio.ini
+++ b/platformio.ini
@@ -114,7 +114,7 @@ build_flags = ${tasmota_core.build_flags}
[tasmota_core]
; *** Esp8266 Arduino core 2.7.0
platform = espressif8266@2.4.0
-platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino/releases/download/2.7.0/esp8266-2.7.0.zip
+platform_packages = framework-arduinoespressif8266 @ https://github.com/tasmota/Arduino/releases/download/2.7.0/esp8266-2.7.0.zip
build_flags = ${esp82xx_defaults.build_flags}
-DBEARSSL_SSL_BASIC
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
From 8bdd46a9650a280bc88786e5c821c1098dd6dd29 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 4 May 2020 17:13:14 +0200
Subject: [PATCH 20/22] Start ESP32 webcam on GUI load
---
tasmota/settings.h | 2 +-
tasmota/xdrv_39_webcam.ino | 31 +++++++++++++++++++++++--------
2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/tasmota/settings.h b/tasmota/settings.h
index 8eadf12b7..81ee3baf8 100644
--- a/tasmota/settings.h
+++ b/tasmota/settings.h
@@ -367,7 +367,7 @@ struct {
uint8_t free_esp32_446[10]; // 446
- uint8_t esp32_webcam_resolution; // 450 - not used yet
+ uint8_t esp32_webcam_resolution; // 450
#endif // ESP8266 - ESP32
char serial_delimiter; // 451
diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino
index f161e1ea0..a092bfecd 100644
--- a/tasmota/xdrv_39_webcam.ino
+++ b/tasmota/xdrv_39_webcam.ino
@@ -591,7 +591,7 @@ void detect_motion(void) {
void wc_show_stream(void) {
#ifndef USE_SCRIPT
if (CamServer) {
- WSContentSend_P(PSTR("
"),
+ WSContentSend_P(PSTR("
"),
WiFi.localIP().toString().c_str());
}
#endif
@@ -623,6 +623,11 @@ uint32_t wc_set_streamserver(uint32_t flag) {
return 0;
}
+void WcStreamControl(uint32_t resolution) {
+ wc_set_streamserver(resolution);
+ wc_setup(resolution);
+}
+
void wc_loop(void) {
if (CamServer) { CamServer->handleClient(); }
if (wc_stream_active) { handleMjpeg_task(); }
@@ -661,28 +666,34 @@ flash led = gpio4
red led = gpio 33
*/
+void WcInit(void) {
+ if (Settings.esp32_webcam_resolution > 10) {
+ Settings.esp32_webcam_resolution = 0;
+ }
+}
+
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
-#define D_CMND_WC "Webcam"
+#define D_CMND_WEBCAM "Webcam"
const char kWCCommands[] PROGMEM = "|" // no prefix
- D_CMND_WC
+ D_CMND_WEBCAM
;
void (* const WCCommand[])(void) PROGMEM = {
- &CmndWC,
+ &CmndWebcam,
};
-void CmndWC(void) {
+void CmndWebcam(void) {
uint32_t flag = 0;
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) {
- wc_set_streamserver(XdrvMailbox.payload);
- wc_setup(XdrvMailbox.payload);
+ Settings.esp32_webcam_resolution = XdrvMailbox.payload;
+ WcStreamControl(Settings.esp32_webcam_resolution);
}
if (CamServer) { flag = 1; }
- Response_P(PSTR("{\"" D_CMND_WC "\":{\"Streaming\":\"%s\"}"),GetStateText(flag));
+ Response_P(PSTR("{\"" D_CMND_WEBCAM "\":{\"Streaming\":\"%s\"}"),GetStateText(flag));
}
/*********************************************************************************************\
@@ -700,11 +711,15 @@ bool Xdrv39(uint8_t function) {
wc_pic_setup();
break;
case FUNC_WEB_ADD_MAIN_BUTTON:
+ WcStreamControl(Settings.esp32_webcam_resolution);
wc_show_stream();
break;
case FUNC_COMMAND:
result = DecodeCommand(kWCCommands, WCCommand);
break;
+ case FUNC_PRE_INIT:
+ WcInit();
+ break;
}
return result;
}
From b07edd1d74e87cdcf71d434fcf7df9abfff4da45 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 4 May 2020 20:00:05 +0200
Subject: [PATCH 21/22] Move constants in PMEM
---
tasmota/settings.ino | 40 +++++++++++++++++------------------
tasmota/support_command.ino | 8 +++----
tasmota/xdrv_01_webserver.ino | 2 +-
tasmota/xdrv_06_snfbridge.ino | 10 ++++-----
tasmota/xdrv_21_wemo.ino | 8 +++----
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index aa3bc1e9b..911c69c2d 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -407,9 +407,9 @@ bool SettingsUpdateText(uint32_t index, const char* replace_me)
}
// Make a copy first in case we use source from Settings.text
- uint32_t replace_len = strlen(replace_me);
+ uint32_t replace_len = strlen_P(replace_me);
char replace[replace_len +1];
- memcpy(replace, replace_me, sizeof(replace));
+ memcpy_P(replace, replace_me, sizeof(replace));
uint32_t start_pos = 0;
uint32_t end_pos = 0;
@@ -744,11 +744,11 @@ void SettingsDefaultSet2(void)
Settings.module = MODULE;
ModuleDefault(WEMOS);
// for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; }
- SettingsUpdateText(SET_FRIENDLYNAME1, FRIENDLY_NAME);
- SettingsUpdateText(SET_FRIENDLYNAME2, FRIENDLY_NAME"2");
- SettingsUpdateText(SET_FRIENDLYNAME3, FRIENDLY_NAME"3");
- SettingsUpdateText(SET_FRIENDLYNAME4, FRIENDLY_NAME"4");
- SettingsUpdateText(SET_OTAURL, OTA_URL);
+ SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME));
+ SettingsUpdateText(SET_FRIENDLYNAME2, PSTR(FRIENDLY_NAME"2"));
+ SettingsUpdateText(SET_FRIENDLYNAME3, PSTR(FRIENDLY_NAME"3"));
+ SettingsUpdateText(SET_FRIENDLYNAME4, PSTR(FRIENDLY_NAME"4"));
+ SettingsUpdateText(SET_OTAURL, PSTR(OTA_URL));
// Power
Settings.flag.save_state = SAVE_STATE;
@@ -779,14 +779,14 @@ void SettingsDefaultSet2(void)
ParseIp(&Settings.ip_address[3], WIFI_DNS);
Settings.sta_config = WIFI_CONFIG_TOOL;
// Settings.sta_active = 0;
- SettingsUpdateText(SET_STASSID1, STA_SSID1);
- SettingsUpdateText(SET_STASSID2, STA_SSID2);
- SettingsUpdateText(SET_STAPWD1, STA_PASS1);
- SettingsUpdateText(SET_STAPWD2, STA_PASS2);
+ SettingsUpdateText(SET_STASSID1, PSTR(STA_SSID1));
+ SettingsUpdateText(SET_STASSID2, PSTR(STA_SSID2));
+ SettingsUpdateText(SET_STAPWD1, PSTR(STA_PASS1));
+ SettingsUpdateText(SET_STAPWD2, PSTR(STA_PASS2));
SettingsUpdateText(SET_HOSTNAME, WIFI_HOSTNAME);
// Syslog
- SettingsUpdateText(SET_SYSLOG_HOST, SYS_LOG_HOST);
+ SettingsUpdateText(SET_SYSLOG_HOST, PSTR(SYS_LOG_HOST));
Settings.syslog_port = SYS_LOG_PORT;
Settings.syslog_level = SYS_LOG_LEVEL;
@@ -796,8 +796,8 @@ void SettingsDefaultSet2(void)
Settings.flag3.mdns_enabled = MDNS_ENABLED;
Settings.webserver = WEB_SERVER;
Settings.weblog_level = WEB_LOG_LEVEL;
- SettingsUpdateText(SET_WEBPWD, WEB_PASSWORD);
- SettingsUpdateText(SET_CORS, CORS_DOMAIN);
+ SettingsUpdateText(SET_WEBPWD, PSTR(WEB_PASSWORD));
+ SettingsUpdateText(SET_CORS, PSTR(CORS_DOMAIN));
// Button
Settings.flag.button_restrict = KEY_DISABLE_MULTIPRESS;
@@ -841,13 +841,13 @@ void SettingsDefaultSet2(void)
SettingsUpdateText(SET_STATE_TXT2, MQTT_STATUS_ON);
SettingsUpdateText(SET_STATE_TXT3, MQTT_CMND_TOGGLE);
SettingsUpdateText(SET_STATE_TXT4, MQTT_CMND_HOLD);
- char fingerprint[60];
- strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint));
+ char fingerprint[64];
+ strncpy_P(fingerprint, PSTR(MQTT_FINGERPRINT1), sizeof(fingerprint));
char *p = fingerprint;
for (uint32_t i = 0; i < 20; i++) {
Settings.mqtt_fingerprint[0][i] = strtol(p, &p, 16);
}
- strlcpy(fingerprint, MQTT_FINGERPRINT2, sizeof(fingerprint));
+ strncpy_P(fingerprint, PSTR(MQTT_FINGERPRINT2), sizeof(fingerprint));
p = fingerprint;
for (uint32_t i = 0; i < 20; i++) {
Settings.mqtt_fingerprint[1][i] = strtol(p, &p, 16);
@@ -1010,9 +1010,9 @@ void SettingsDefaultSet2(void)
Settings.timezone = APP_TIMEZONE / 60;
Settings.timezone_minutes = abs(APP_TIMEZONE % 60);
}
- SettingsUpdateText(SET_NTPSERVER1, NTP_SERVER1);
- SettingsUpdateText(SET_NTPSERVER2, NTP_SERVER2);
- SettingsUpdateText(SET_NTPSERVER3, NTP_SERVER3);
+ SettingsUpdateText(SET_NTPSERVER1, PSTR(NTP_SERVER1));
+ SettingsUpdateText(SET_NTPSERVER2, PSTR(NTP_SERVER2));
+ SettingsUpdateText(SET_NTPSERVER3, PSTR(NTP_SERVER3));
for (uint32_t i = 0; i < MAX_NTP_SERVERS; i++) {
SettingsUpdateText(SET_NTPSERVER1 +i, ReplaceCommaWithDot(SettingsText(SET_NTPSERVER1 +i)));
}
diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino
index 475517d47..269fcfe3c 100644
--- a/tasmota/support_command.ino
+++ b/tasmota/support_command.ino
@@ -659,7 +659,7 @@ void CmndUpgrade(void)
void CmndOtaUrl(void)
{
if (XdrvMailbox.data_len > 0) {
- SettingsUpdateText(SET_OTAURL, (SC_DEFAULT == Shortcut()) ? OTA_URL : XdrvMailbox.data);
+ SettingsUpdateText(SET_OTAURL, (SC_DEFAULT == Shortcut()) ? PSTR(OTA_URL) : XdrvMailbox.data);
}
ResponseCmndChar(SettingsText(SET_OTAURL));
}
@@ -1394,7 +1394,7 @@ void CmndNtpServer(void)
uint32_t ntp_server = SET_NTPSERVER1 + XdrvMailbox.index -1;
if (XdrvMailbox.data_len > 0) {
SettingsUpdateText(ntp_server,
- (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? NTP_SERVER1 : (2 == XdrvMailbox.index) ? NTP_SERVER2 : NTP_SERVER3 : XdrvMailbox.data);
+ (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? PSTR(NTP_SERVER1) : (2 == XdrvMailbox.index) ? PSTR(NTP_SERVER2) : PSTR(NTP_SERVER3) : XdrvMailbox.data);
SettingsUpdateText(ntp_server, ReplaceCommaWithDot(SettingsText(ntp_server)));
// restart_flag = 2; // Issue #3890
ntp_force_sync = true;
@@ -1602,7 +1602,7 @@ void CmndReset(void)
switch (XdrvMailbox.payload) {
case 1:
restart_flag = 211;
- ResponseCmndChar(D_JSON_RESET_AND_RESTARTING);
+ ResponseCmndChar(PSTR(D_JSON_RESET_AND_RESTARTING));
break;
case 2 ... 6:
restart_flag = 210 + XdrvMailbox.payload;
@@ -1614,7 +1614,7 @@ void CmndReset(void)
ResponseCmndDone();
break;
default:
- ResponseCmndChar(D_JSON_ONE_TO_RESET);
+ ResponseCmndChar(PSTR(D_JSON_ONE_TO_RESET));
}
}
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index 4dddafaec..6246377be 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -1087,7 +1087,7 @@ void HandleRoot(void)
WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Hue
"b", // b - Unique HTML id
- "#800", "#f00 5%,#ff0 20%,#0f0 35%,#0ff 50%,#00f 65%,#f0f 80%,#f00 95%,#800", // Hue colors
+ "#800", PSTR("#f00 5%,#ff0 20%,#0f0 35%,#0ff 50%,#00f 65%,#f0f 80%,#f00 95%,#800"), // Hue colors
2, // sl2 - Unique range HTML id - Used as source for Saturation end color
1, 359, // Range valid Hue
hue,
diff --git a/tasmota/xdrv_06_snfbridge.ino b/tasmota/xdrv_06_snfbridge.ino
index 68365fceb..210ff87a3 100644
--- a/tasmota/xdrv_06_snfbridge.ino
+++ b/tasmota/xdrv_06_snfbridge.ino
@@ -481,11 +481,11 @@ void CmndRfKey(void)
SnfBridge.learn_active = 0;
if (2 == XdrvMailbox.payload) { // Learn RF data
SonoffBridgeLearn(XdrvMailbox.index);
- ResponseCmndIdxChar(D_JSON_START_LEARNING);
+ ResponseCmndIdxChar(PSTR(D_JSON_START_LEARNING));
}
else if (3 == XdrvMailbox.payload) { // Unlearn RF data
Settings.rf_code[XdrvMailbox.index][0] = 0; // Reset sync_time MSB
- ResponseCmndIdxChar(D_JSON_SET_TO_DEFAULT);
+ ResponseCmndIdxChar(PSTR(D_JSON_SET_TO_DEFAULT));
}
else if (4 == XdrvMailbox.payload) { // Save RF data provided by RFSync, RfLow, RfHigh and last RfCode
for (uint32_t i = 0; i < 6; i++) {
@@ -494,7 +494,7 @@ void CmndRfKey(void)
Settings.rf_code[XdrvMailbox.index][6] = (SnfBridge.last_send_code >> 16) & 0xff;
Settings.rf_code[XdrvMailbox.index][7] = (SnfBridge.last_send_code >> 8) & 0xff;
Settings.rf_code[XdrvMailbox.index][8] = SnfBridge.last_send_code & 0xff;
- ResponseCmndIdxChar(D_JSON_SAVED);
+ ResponseCmndIdxChar(PSTR(D_JSON_SAVED));
} else if (5 == XdrvMailbox.payload) { // Show default or learned RF data
uint8_t key = XdrvMailbox.index;
uint8_t index = (0 == Settings.rf_code[key][0]) ? 0 : key; // Use default if sync_time MSB = 0
@@ -513,10 +513,10 @@ void CmndRfKey(void)
} else {
if ((1 == XdrvMailbox.payload) || (0 == Settings.rf_code[XdrvMailbox.index][0])) { // Test sync_time MSB
SonoffBridgeSend(0, XdrvMailbox.index); // Send default RF data
- ResponseCmndIdxChar(D_JSON_DEFAULT_SENT);
+ ResponseCmndIdxChar(PSTR(D_JSON_DEFAULT_SENT));
} else {
SonoffBridgeSend(XdrvMailbox.index, 0); // Send learned RF data
- ResponseCmndIdxChar(D_JSON_LEARNED_SENT);
+ ResponseCmndIdxChar(PSTR(D_JSON_LEARNED_SENT));
}
}
} else {
diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino
index eef509e2a..fb123d4ab 100644
--- a/tasmota/xdrv_21_wemo.ino
+++ b/tasmota/xdrv_21_wemo.ino
@@ -259,10 +259,10 @@ bool Xdrv21(uint8_t function)
if (devices_present && (EMUL_WEMO == Settings.flag2.emulation)) {
switch (function) {
case FUNC_WEB_ADD_HANDLER:
- Webserver->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent);
- Webserver->on("/eventservice.xml", HandleUpnpService);
- Webserver->on("/metainfoservice.xml", HandleUpnpMetaService);
- Webserver->on("/setup.xml", HandleUpnpSetupWemo);
+ Webserver->on(F("/upnp/control/basicevent1"), HTTP_POST, HandleUpnpEvent);
+ Webserver->on(F("/eventservice.xml"), HandleUpnpService);
+ Webserver->on(F("/metainfoservice.xml"), HandleUpnpMetaService);
+ Webserver->on(F("/setup.xml"), HandleUpnpSetupWemo);
break;
}
}
From ac81547ea449dc60231f528c24914a3c77739435 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 4 May 2020 22:15:54 +0200
Subject: [PATCH 22/22] Esp32 CI badge
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 142a8037a..fc58416f6 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases
[](https://github.com/arendst/Tasmota)
[](http://thehackbox.org/tasmota/)

+
See [tasmota/CHANGELOG.md](tasmota/CHANGELOG.md) for detailed change information.