Merge branch 'development' into new-windmeter-sensor

# Conflicts:
#	tasmota/language/bg-BG.h
#	tasmota/language/cs-CZ.h
#	tasmota/language/de-DE.h
#	tasmota/language/el-GR.h
#	tasmota/language/en-GB.h
#	tasmota/language/es-ES.h
#	tasmota/language/fr-FR.h
#	tasmota/language/he-HE.h
#	tasmota/language/hu-HU.h
#	tasmota/language/it-IT.h
#	tasmota/language/ko-KO.h
#	tasmota/language/nl-NL.h
#	tasmota/language/pl-PL.h
#	tasmota/language/pt-BR.h
#	tasmota/language/pt-PT.h
#	tasmota/language/ro-RO.h
#	tasmota/language/ru-RU.h
#	tasmota/language/sk-SK.h
#	tasmota/language/sv-SE.h
#	tasmota/language/tr-TR.h
#	tasmota/language/uk-UA.h
#	tasmota/language/zh-CN.h
#	tasmota/language/zh-TW.h
This commit is contained in:
Matteo Albinola 2020-05-05 09:07:03 +02:00
commit 097d51ea72
44 changed files with 1283 additions and 1180 deletions

View File

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

22
.github/workflows/CI_github_ESP32.yml vendored Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<<pin) & p->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<<pin);
p->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<<pin) & pwmState.mask)) {
return false; // Pin not actually active
}
PWMState p; // The working copy since we can't edit the one in use
p = pwmState;
_removePWMEntry(pin, &p);
// Update and wait for mailbox to be emptied
pwmUpdate = &p;
MEMBARRIER();
forceTimerInterrupt();
while (pwmUpdate) {
delay(0);
}
// Possibly shut doen the timer completely if we're done
if (!waveformEnabled && !pwmState.cnt && !timer1CB) {
deinitTimer();
MEMBARRIER();
/* Busy wait, could be in ISR */
}
// Possibly shut down the timer completely if we're done
disableIdleTimer();
return true;
}
// Called by analogWrite(1...99%) to set the PWM duty in clock cycles
bool _setPWM(int pin, uint32_t cc) {
stopWaveform(pin);
PWMState p; // Working copy
p = pwmState;
// Get rid of any entries for this pin
_removePWMEntry(pin, &p);
if ((1<<pin) & p.mask) {
_removePWMEntry(pin, &p);
}
// And add it to the list, in order
if (p.cnt >= 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<<pin;
} else {
uint32_t ttl=0;
uint32_t i;
// Skip along until we're at the spot to insert
for (i=0; (i <= p.cnt) && (ttl + p.edge[i].delta < cc); i++) {
ttl += p.edge[i].delta;
for (i=0; (i <= p.cnt) && (ttl + p.delta[i] < cc); i++) {
ttl += p.delta[i];
}
// Shift everything out by one to make space for new edge
memmove(&p.edge[i + 1], &p.edge[i], (1 + p.cnt - i) * sizeof(p.edge[0]));
memmove(&p.pin[i + 1], &p.pin[i], (1 + p.cnt - i) * sizeof(p.pin[0]));
memmove(&p.delta[i + 1], &p.delta[i], (1 + p.cnt - i) * sizeof(p.delta[0]));
int off = cc - ttl; // The delta from the last edge to the one we're inserting
p.edge[i].pin = pin;
p.edge[i].delta = off; // Add the delta to this new pin
p.edge[i + 1].delta -= off; // And subtract it from the follower to keep sum(deltas) constant
p.pin[i] = pin;
p.delta[i] = off; // Add the delta to this new pin
p.delta[i + 1] -= off; // And subtract it from the follower to keep sum(deltas) constant
p.cnt++;
p.mask |= 1<<pin;
}
// Set mailbox and wait for ISR to copy it over
pwmUpdate = &p;
if (!timerRunning) {
initTimer();
timer1_write(microsecondsToClockCycles(10));
MEMBARRIER();
initTimer();
forceTimerInterrupt();
while (pwmUpdate) {
delay(0);
}
while (pwmUpdate) { delay(0); }
return true;
}
// Start up a waveform on a pin, or change the current one. Will change to the new
// waveform smoothly on next low->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<<pin;
if (waveformEnabled & mask) {
waveformNewHigh = timeHighCycles;
waveformNewLow = timeLowCycles;
waveformToChange = pin;
while (waveformToChange >= 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<<pin;
if (!(waveformEnabled & mask)) {
return false; // It's not running, nothing to do here
}
waveformToDisable |= mask;
// Ensure timely service....
if (T1L > 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<<pwmState.edge[pwmState.idx].pin;
GPOC = 1<<pwmState.pin[pwmState.idx];
// GPIO16 still needs manual work
if (pwmState.edge[pwmState.idx].pin == 16) {
GP16O &= ~1;
if (pwmState.pin[pwmState.idx] == 16) {
GP16O = 0;
}
pwmState.idx++;
// Any other pins at this same PWM value will have delta==0, drop them too.
} while (pwmState.edge[pwmState.idx].delta == 0);
} while (pwmState.delta[pwmState.idx] == 0);
}
// Preserve duty cycle over PWM period by using now+xxx instead of += delta
pwmState.nextServiceCycle = now + pwmState.edge[pwmState.idx].delta;
cyclesToGo = pwmState.nextServiceCycle - now;
if (cyclesToGo<0) cyclesToGo=0;
cyclesToGo = adjust(pwmState.delta[pwmState.idx]);
pwmState.nextServiceCycle = GetCycleCountIRQ() + cyclesToGo;
}
nextEventCycles = min_u32(nextEventCycles, cyclesToGo);
}
#endif
for (int i = startPin; i <= endPin; i++) {
for (auto i = wvfState.startPin; i <= wvfState.endPin; i++) {
uint32_t mask = 1<<i;
// If it's not on, ignore!
if (!(waveformEnabled & mask)) {
if (!(wvfState.waveformEnabled & mask)) {
continue;
}
Waveform *wave = &waveform[i];
Waveform *wave = &wvfState.waveform[i];
uint32_t now = GetCycleCountIRQ();
// Disable any waveforms that are done
@ -467,9 +509,9 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
int32_t expiryToGo = wave->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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 <number>
* 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<int>(_jpg_buf_len));
tlen=client.write(_jpg_buf, _jpg_buf_len);
"\r\n", static_cast<int>(_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;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;
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("<p></p><center><img src='http://%s:81/stream' alt='Webcam stream' style='width:99%%;'></center><p></p>"),
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