diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6ec59387b..d8bb487bd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,7 +6,8 @@ - [ ] 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 pass CI tests. **Your PR cannot be merged unless tests pass** + - [ ] 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 - [ ] 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**_ 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 + 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 [![Dev Version](https://img.shields.io/badge/development%20version-v8.2.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) ![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg) +![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg) See [tasmota/CHANGELOG.md](tasmota/CHANGELOG.md) for detailed change information. 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/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) 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; } diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h index 22c3081c5..ec4fea1ae 100644 --- a/tasmota/language/bg-BG.h +++ b/tasmota/language/bg-BG.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 8ffc87dc2..e6c0221c4 100644 --- a/tasmota/language/cs-CZ.h +++ b/tasmota/language/cs-CZ.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 0fdf11495..7c4d9459f 100644 --- a/tasmota/language/de-DE.h +++ b/tasmota/language/de-DE.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 cbdeee519..586cc623d 100644 --- a/tasmota/language/el-GR.h +++ b/tasmota/language/el-GR.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 ac3ffd5a6..84134483d 100644 --- a/tasmota/language/en-GB.h +++ b/tasmota/language/en-GB.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 673aaf6a1..1edcf1a9c 100644 --- a/tasmota/language/es-ES.h +++ b/tasmota/language/es-ES.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 5d985eb3e..bb1374ffd 100644 --- a/tasmota/language/fr-FR.h +++ b/tasmota/language/fr-FR.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 c5624b807..f98f18108 100644 --- a/tasmota/language/he-HE.h +++ b/tasmota/language/he-HE.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 303103212..d83e44fb2 100644 --- a/tasmota/language/hu-HU.h +++ b/tasmota/language/hu-HU.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 2a24880d1..3c2aae8c0 100644 --- a/tasmota/language/it-IT.h +++ b/tasmota/language/it-IT.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 b336a27d8..812809f82 100644 --- a/tasmota/language/ko-KO.h +++ b/tasmota/language/ko-KO.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 49859f5b6..04664f8f9 100644 --- a/tasmota/language/nl-NL.h +++ b/tasmota/language/nl-NL.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 4671885e9..5fe5211fd 100644 --- a/tasmota/language/pl-PL.h +++ b/tasmota/language/pl-PL.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 c5c17bb2d..99afd9d10 100644 --- a/tasmota/language/pt-BR.h +++ b/tasmota/language/pt-BR.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 d259939a6..7c7207523 100644 --- a/tasmota/language/pt-PT.h +++ b/tasmota/language/pt-PT.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 1c8559e70..155fbcd71 100644 --- a/tasmota/language/ro-RO.h +++ b/tasmota/language/ro-RO.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 53d493065..8c3a71667 100644 --- a/tasmota/language/ru-RU.h +++ b/tasmota/language/ru-RU.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 85801b8d0..174ceae2c 100644 --- a/tasmota/language/sk-SK.h +++ b/tasmota/language/sk-SK.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 768ed3f74..c655bc524 100644 --- a/tasmota/language/sv-SE.h +++ b/tasmota/language/sv-SE.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 15722b9bf..477342e7b 100644 --- a/tasmota/language/tr-TR.h +++ b/tasmota/language/tr-TR.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 42199bea0..9708db534 100644 --- a/tasmota/language/uk-UA.h +++ b/tasmota/language/uk-UA.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 a84c05922..d821ce292 100644 --- a/tasmota/language/zh-CN.h +++ b/tasmota/language/zh-CN.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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 23918d54e..273b51279 100644 --- a/tasmota/language/zh-TW.h +++ b/tasmota/language/zh-TW.h @@ -667,27 +667,27 @@ #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" #define D_SENSOR_AS3935 "AS3935" #define D_SENSOR_WINDMETER_SPEED "WindMeter Speed" -#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/settings.h b/tasmota/settings.h index 76bf18f12..c36267de2 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 #endif // ESP8266 - ESP32 char serial_delimiter; // 451 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 2548e2b14..911c69c2d 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 } /*********************************************************************************************\ @@ -405,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; @@ -742,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; @@ -777,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; @@ -794,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; @@ -839,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); @@ -1008,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/support_tasmota.ino b/tasmota/support_tasmota.ino index c335bd9cb..47aca2397 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. @@ -1542,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); diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h index 2a356a46a..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,182 +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 - // webcam interface - GPIO_WEBCAM_PWDN_GPIO_NUM, - 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 { @@ -230,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 "|" @@ -280,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 "|" @@ -309,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, @@ -354,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 @@ -632,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_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index d22b07b5c..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, @@ -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 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_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_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; } } 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; } } 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]); } 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 diff --git a/tasmota/xdrv_39_webcam.ino b/tasmota/xdrv_39_webcam.ino index 1a2f3b260..a092bfecd 100644 --- a/tasmota/xdrv_39_webcam.ino +++ b/tasmota/xdrv_39_webcam.ino @@ -1,5 +1,50 @@ +/* + 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) + * + * 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 @@ -38,13 +83,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 +99,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 +108,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 +124,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) && 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); + if (99 == xpin) { xpin = -1; } + config.pin_pwdn = xpin; //PWDN_GPIO_NUM; + xpin = Pin(GPIO_WEBCAM_RESET); + 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 +179,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 +197,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 +270,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 +299,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 +362,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 +375,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 +400,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 +410,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 +418,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 +433,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 +448,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 +486,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(); } @@ -498,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; @@ -508,8 +535,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 +545,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); } } @@ -561,11 +588,19 @@ uint8_t *out_buf=0; } } +void wc_show_stream(void) { +#ifndef USE_SCRIPT + if (CamServer) { + WSContentSend_P(PSTR("

Webcam stream

"), + 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) { @@ -574,25 +609,29 @@ 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 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(); - 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) { @@ -627,6 +666,36 @@ 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_WEBCAM "Webcam" + +const char kWCCommands[] PROGMEM = "|" // no prefix + D_CMND_WEBCAM + ; + +void (* const WCCommand[])(void) PROGMEM = { + &CmndWebcam, + }; + +void CmndWebcam(void) { + uint32_t flag = 0; + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) { + Settings.esp32_webcam_resolution = XdrvMailbox.payload; + WcStreamControl(Settings.esp32_webcam_resolution); + } + if (CamServer) { flag = 1; } + Response_P(PSTR("{\"" D_CMND_WEBCAM "\":{\"Streaming\":\"%s\"}"),GetStateText(flag)); +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -641,8 +710,19 @@ bool Xdrv39(uint8_t function) { case FUNC_WEB_ADD_HANDLER: 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; } -#endif +#endif // USE_WEBCAM +#endif // ESP32