diff --git a/tasmota/include/tasmota_globals.h b/tasmota/include/tasmota_globals.h index 187209279..3518899b0 100644 --- a/tasmota/include/tasmota_globals.h +++ b/tasmota/include/tasmota_globals.h @@ -45,6 +45,7 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack extern "C" void resetPins(); extern "C" int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys, uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm); +extern "C" void setTimer1Callback(uint32_t (*fn)()); #ifdef USE_SERIAL_BRIDGE void SerialBridgePrintf(PGM_P formatP, ...); #endif diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino index 9567fdd48..0e214b977 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_utils.ino @@ -40,7 +40,7 @@ const gamma_table_t ac_dimmer_table[] = { // don't put in PROGMEM for performa { 900, 704 }, { 950, 748 }, { 990, 850 }, - { 1024, 1024 }, + { 1023, 1023 }, { 0xFFFF, 0xFFFF } // fail-safe if out of range }; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino new file mode 100644 index 000000000..307fabc00 --- /dev/null +++ b/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino @@ -0,0 +1,276 @@ +/* + xdrv_68_zerocrossdimmer.ino - Zero-Cross Dimmer support for Tasmota + + Copyright (C) 2023 Stefan Bode + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_AC_ZERO_CROSS_DIMMER +/*********************************************************************************************\ + * Zero-Cross AC Dimmer PMM 1..xx use +\*********************************************************************************************/ + +#define XDRV_68 68 + +static const uint32_t GATE_ENABLE_TIME = 100; + +struct AC_ZERO_CROSS_DIMMER { + uint32_t cycle_time_us; + /// Time (in micros()) of last ZC signal + uint32_t crossed_zero_at; + /// Time since last ZC pulse to enable gate pin. 0 means not set. + bool timer_iterrupt_started = false; + bool dimmer_in_use = false; + // Check if 50µs timer is running. + uint32_t enable_time_us[MAX_PWMS]; + /// Time since last ZC pulse to disable gate pin. 0 means no disable. + uint32_t disable_time_us[MAX_PWMS]; + uint8_t current_state_in_phase[MAX_PWMS]; // 0=before fire HIGH, 1=HIGH, 2=after setting LOW, 3=before HIGH without setting LOW (POWER ON) + uint32_t lastlight[MAX_PWMS]; + uint16_t detailpower[MAX_PWMS]; // replaces dimmer and light controll 0..10000. required savedata 0. + uint32_t intr_counter = 0; +} ac_zero_cross_dimmer; + + +#ifdef ESP32 + static hw_timer_t *dimmer_timer = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +#endif + +#define D_PRFX_ZCDIMMER "ZCDimmer" +#define D_CMND_DIMMERSET "Set" + +const char kZCDimmerCommands[] PROGMEM = D_PRFX_ZCDIMMER "|" D_CMND_DIMMERSET; + +void (* const ZCDimmerCommand[])(void) PROGMEM = { + &CmndZCDimmerSet + }; + +void IRAM_ATTR ACDimmerZeroCross(uint32_t time) { + ac_zero_cross_dimmer.dimmer_in_use = false; + ac_zero_cross_dimmer.cycle_time_us = time - ac_zero_cross_dimmer.crossed_zero_at; + ac_zero_cross_dimmer.crossed_zero_at = time; + for (uint8_t i=0; i < MAX_PWMS; i++) { + if (Pin(GPIO_PWM1, i) == -1) continue; + ac_zero_cross_dimmer.dimmer_in_use |= ac_zero_cross_dimmer.lastlight[i] > 0; + // Dimmer is physically off. Skip swich on + ac_zero_cross_dimmer.current_state_in_phase[i] = 0; + if (100 * ac_zero_cross_dimmer.enable_time_us[i] > 95 * ac_zero_cross_dimmer.cycle_time_us ) { + ac_zero_cross_dimmer.current_state_in_phase[i] = 1; + ac_zero_cross_dimmer.disable_time_us[i] = ac_zero_cross_dimmer.cycle_time_us / 2; + } + // If full cycle is required keep pin HIGH, skip LOW by skipping phase + if (100 * ac_zero_cross_dimmer.enable_time_us[i] < 15 * ac_zero_cross_dimmer.cycle_time_us) { + ac_zero_cross_dimmer.current_state_in_phase[i] = 3; + } + } +} + +uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() { + //ACDimmerTimer_intr(); + ACDimmerTimer_intr(); + return 4000; +} + +void ACDimmerInterruptDisable(bool disable) +{ + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer enabled: %d"),!disable); + ac_zero_cross_dimmer.timer_iterrupt_started = !disable; + if (disable) { + //stop the interrupt +#ifdef ESP32 + if (dimmer_timer != nullptr) { + timerAlarmDisable(dimmer_timer); + } +#endif +#ifdef ESP8266 + //setTimer1Callback(NULL); +#endif + } else { + for (uint8_t i = 0 ; i < MAX_PWMS; i++) { + if (Pin(GPIO_PWM1, i) != -1) { + pinMode(Pin(GPIO_PWM1, i), OUTPUT); + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer Pin %d set"),Pin(GPIO_PWM1, i)); + } + } +#ifdef ESP32 + if (dimmer_timer == nullptr) { + // 80 Divider -> 1 count=1µs + dimmer_timer = timerBegin(0, 80, true); + timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr, true); + // For ESP32, we can't use dynamic interval calculation because the timerX functions + // are not callable from ISR (placed in flash storage). + // Here we just use an interrupt firing every 75 µs. + if (Settings->save_data == 0) { + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Save disabled. High frequency scan enabled. DO NOT USE SAVEDATA if channel is on")); + timerAlarmWrite(dimmer_timer, 30, true); + } else { + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Save on. 75µs scan enabled")); + timerAlarmWrite(dimmer_timer, 75, true); + } + } + timerAlarmEnable(dimmer_timer); +#endif + +#ifdef ESP8266 + // Uses ESP8266 waveform (soft PWM) class + // PWM and AcDimmer can even run at the same time this way + //setTimer1Callback(&ACDimmerTimer_intr_ESP8266); +#endif + } +} + +void IRAM_ATTR ACDimmerTimer_intr() { + // If no ZC signal received yet. + uint32_t now = micros(); + ac_zero_cross_dimmer.intr_counter++; + if (ac_zero_cross_dimmer.crossed_zero_at == 0) + return; + + uint32_t time_since_zc = now - ac_zero_cross_dimmer.crossed_zero_at; + if (time_since_zc > 10100) { + memset(&ac_zero_cross_dimmer.current_state_in_phase, 0x00, sizeof(ac_zero_cross_dimmer.current_state_in_phase)); + ac_zero_cross_dimmer.crossed_zero_at += ac_zero_cross_dimmer.cycle_time_us; + time_since_zc = now - ac_zero_cross_dimmer.crossed_zero_at; + } + + for (uint8_t i = 0 ; i < MAX_PWMS; i++ ) { + if (Pin(GPIO_PWM1, i) == -1) continue; + switch (ac_zero_cross_dimmer.current_state_in_phase[i]) { + case 1: + if (time_since_zc >= ac_zero_cross_dimmer.disable_time_us[i]) { + digitalWrite(Pin(GPIO_PWM1, i), LOW); + ac_zero_cross_dimmer.current_state_in_phase[i]++; + } + break; + case 0: + case 3: + if (time_since_zc >= ac_zero_cross_dimmer.enable_time_us[i]) { + digitalWrite(Pin(GPIO_PWM1, i), HIGH); + ac_zero_cross_dimmer.current_state_in_phase[i]++; + } + break; + } + } +} + +void ACDimmerControllTrigger(void) { + + if (ac_zero_cross_dimmer.timer_iterrupt_started != ac_zero_cross_dimmer.dimmer_in_use) { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: ZeroEnable %d --> %d ... change..."),ac_zero_cross_dimmer.timer_iterrupt_started, ac_zero_cross_dimmer.dimmer_in_use); + ACDimmerInterruptDisable(!ac_zero_cross_dimmer.dimmer_in_use); + } + for (uint8_t i = 0; i < MAX_PWMS; i++){ + if (Pin(GPIO_PWM1, i) == -1) continue; + ac_zero_cross_dimmer.lastlight[i] = Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]; + ac_zero_cross_dimmer.enable_time_us[i] = (ac_zero_cross_dimmer.cycle_time_us * (1023 - ac_zero_cross_power(ac_zero_cross_dimmer.lastlight[i]))) / 1023; + +#ifdef ESP32 + if (ac_zero_cross_dimmer.detailpower[i]){ + float state = (float)(1 - (ac_zero_cross_dimmer.detailpower[i]/10000.0)); + //state = std::acos(1 - (2 * state)) / 3.14159 * ac_zero_cross_dimmer.cycle_time_us; + state = std::acos(1 - (2 * state)) / 3.14159 * 10000; + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: Float2: %*_f"),0,&state); + ac_zero_cross_dimmer.enable_time_us[i] = (uint32_t)state; + ac_zero_cross_dimmer.lastlight[i] = 1; + } +#endif + + ac_zero_cross_dimmer.disable_time_us[i] = ac_zero_cross_dimmer.enable_time_us[i] + GATE_ENABLE_TIME; + } + +} + +void ACDimmerLogging(void) +{ + bool alarmEnabled = false; + uint32_t timercounter = ac_zero_cross_dimmer.intr_counter; + +#ifdef ESP32 + if (dimmer_timer != nullptr) { + alarmEnabled = timerAlarmEnabled(dimmer_timer); + timercounter = (uint32_t)timerRead(dimmer_timer); + } +#endif + + AddLog(LOG_LEVEL_DEBUG, PSTR("ZCD: ZeroEnable %d -> %d, Alarm %d, intr: %ld, cycle time: %ld µs"), + ac_zero_cross_dimmer.dimmer_in_use, ac_zero_cross_dimmer.timer_iterrupt_started, alarmEnabled, timercounter, ac_zero_cross_dimmer.cycle_time_us + ); + for (uint8_t i = 0; i < MAX_PWMS; i++){ + if (Pin(GPIO_PWM1, i) == -1) continue; + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: PWM[%d] en: %ld µs, dis: %ld µs, state %d, fade: %d, cur: %d, end: %d, lastlight: %d"), + i+1, ac_zero_cross_dimmer.enable_time_us[i], ac_zero_cross_dimmer.disable_time_us[i], + ac_zero_cross_dimmer.current_state_in_phase[i], Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_end_10[i], ac_zero_cross_dimmer.lastlight[i] + ); + } + +} + + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +void CmndZCDimmerSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) { + if (XdrvMailbox.data_len > 0) { + ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1] = (uint16_t)(100 * CharToFloat(XdrvMailbox.data)); + } + ResponseCmndIdxFloat((float)(ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1]) / 100, 2); + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv68(uint32_t function) +{ + bool result = false; + if (Settings->flag4.zerocross_dimmer) { + switch (function) { + case FUNC_INIT: +#ifdef ESP32 + //ACDimmerInterruptDisable(false); +#endif +#ifdef ESP8266 + setTimer1Callback(&ACDimmerTimer_intr_ESP8266); +#endif + break; + case FUNC_EVERY_SECOND: + ACDimmerLogging(); + break; + case FUNC_EVERY_100_MSECOND: + ACDimmerControllTrigger(); + break; + case FUNC_INTERRUPT_STOP: + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: FUNC_INTERRUPT_STOP")); + ACDimmerInterruptDisable(true); + break; + case FUNC_INTERRUPT_START: + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: FUNC_INTERRUPT_START")); + ACDimmerInterruptDisable(false); + break; + case FUNC_COMMAND: + result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand); + //result = DecodeCommand(kShutterCommands, ShutterCommand); + + break; + } + } + return result; +} + +#endif // USE_AC_ZERO_CROSS_DIMMER diff --git a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino index d427cc7db..b23870503 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino @@ -2,7 +2,6 @@ xsns_01_counter.ino - Counter sensors (water meters, electricity meters etc.) sensor support for Tasmota Copyright (C) 2021 Maarten Damen and Theo Arends - Stefan Bode (Zero-Cross Dimmer) 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 @@ -48,22 +47,6 @@ struct COUNTER { } Counter; -#ifdef USE_AC_ZERO_CROSS_DIMMER -struct AC_ZERO_CROSS_DIMMER { - bool startReSync = false; // set to TRUE if zero-cross event occurs - bool startMeasurePhase[MAX_COUNTERS] ; // set to TRUE if channel is ON and zero-cross occurs to initiate phase measure on channel - bool pwm_defined[MAX_COUNTERS]; // check if all GPIO are set and zerocross enabled. Then ADD dimmer. - bool PWM_ON[MAX_COUNTERS] ; // internal ON/OFF of the channel - uint32_t current_cycle_ClockCycles = 0; // amount of clock cycles between two zero-cross events. - uint32_t currentPWMCycleCount[MAX_COUNTERS] ; // clock cycle time of PWM channel, required to measure actual phase. [3] is phase of zero-cross - int16_t currentShiftClockCycle[MAX_COUNTERS]; // dynamic phase correction per channel in clock cycles - uint32_t tobe_cycle_timeClockCycles = 0; // clock cycles between zero-cross events. Depend on main frequency and CPU speed - uint32_t lastCycleCount = 0; // Last value of GetCycleCount during zero-cross sychronisation - uint32_t currentSteps = 100; // dynamic value of zero-crosses between two sychronisation intervalls (default=20 == 200ms at 100Hz) - uint32_t high; // cycle counts for PWM high vaule. needs long enough (4µs) to secure fire TRIAC -} ac_zero_cross_dimmer; -#endif //USE_AC_ZERO_CROSS_DIMMER - void IRAM_ATTR CounterIsrArg(void *arg) { uint32_t index = *static_cast(arg); @@ -93,27 +76,7 @@ void IRAM_ATTR CounterIsrArg(void *arg) { // restart PWM each second (german 50Hz has to up to 0.01% deviation) // restart initiated by setting Counter.startReSync = true; #ifdef USE_AC_ZERO_CROSS_DIMMER - // if zero-cross events occur ond channel is on. phase on PWM must be measured - if ( ac_zero_cross_dimmer.startMeasurePhase[index] == true ) { - ac_zero_cross_dimmer.currentPWMCycleCount[index] = ESP.getCycleCount(); - ac_zero_cross_dimmer.startMeasurePhase[index] = false; - } - // if zero-cross event occurs (200ms window, 5-times a second) and device is online for >10sec - if (index == 3 && RtcSettings.pulse_counter[index]%(Settings->pwm_frequency / 5) == 0 && ac_zero_cross_dimmer.pwm_defined[index] && millis() > 10000) { - ac_zero_cross_dimmer.currentPWMCycleCount[index] = ESP.getCycleCount(); - - if (ac_zero_cross_dimmer.lastCycleCount > 0) { - // start phase measure on PWM channels and initiate phase sync with zero-cross. - ac_zero_cross_dimmer.startReSync = true; - for (uint8_t k=0; k < MAX_COUNTERS-1; k++ ) { - if (ac_zero_cross_dimmer.PWM_ON[k] == true) ac_zero_cross_dimmer.startMeasurePhase[k] = true; - } - ac_zero_cross_dimmer.currentSteps = (ac_zero_cross_dimmer.currentPWMCycleCount[index]-ac_zero_cross_dimmer.lastCycleCount+(ac_zero_cross_dimmer.tobe_cycle_timeClockCycles/2))/(ac_zero_cross_dimmer.tobe_cycle_timeClockCycles); - ac_zero_cross_dimmer.current_cycle_ClockCycles = (ac_zero_cross_dimmer.currentPWMCycleCount[index]-ac_zero_cross_dimmer.lastCycleCount)/ac_zero_cross_dimmer.currentSteps; - } - ac_zero_cross_dimmer.lastCycleCount = ac_zero_cross_dimmer.currentPWMCycleCount[index]; - } - + if (index == 3) ACDimmerZeroCross(time); #endif //USE_AC_ZERO_CROSS_DIMMER return; } @@ -162,26 +125,9 @@ bool CounterPinState(void) void CounterInit(void) { + for (uint32_t i = 0; i < MAX_COUNTERS; i++) { if (PinUsed(GPIO_CNTR1, i)) { -#ifdef USE_AC_ZERO_CROSS_DIMMER - if (Settings->flag4.zerocross_dimmer) { - ac_zero_cross_dimmer.current_cycle_ClockCycles = ac_zero_cross_dimmer.tobe_cycle_timeClockCycles = microsecondsToClockCycles(1000000 / Settings->pwm_frequency); - // short fire on PWM to ensure not to hit next sinus curve but trigger the TRIAC. 0.78% of duty cycle (10ms) ~4µs - ac_zero_cross_dimmer.high = ac_zero_cross_dimmer.current_cycle_ClockCycles / 256; - - // Support for dimmer 1-3. Counter4 reseverd for zero-cross signal - if ((i < MAX_COUNTERS-1 && PinUsed(GPIO_PWM1, i)) || ( i == MAX_COUNTERS-1) ) { - ac_zero_cross_dimmer.pwm_defined[i] = true; - if (i == 3) { - AddLog(LOG_LEVEL_INFO, PSTR("ZeroCross initialized")); - } else { - AddLog(LOG_LEVEL_INFO, PSTR("Dimmer: [%d] initialized. READY. Dimmer %d"), i+1, Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]); - } - - } - } -#endif //USE_AC_ZERO_CROSS_DIMMER Counter.any_counter = true; pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); if ((0 == Settings->pulse_counter_debounce_low) && (0 == Settings->pulse_counter_debounce_high) && !Settings->flag4.zerocross_dimmer) { @@ -260,78 +206,6 @@ void CounterShow(bool json) } } -#ifdef USE_AC_ZERO_CROSS_DIMMER -void SyncACDimmer(void) -{ - if (ac_zero_cross_dimmer.startReSync ) { - // currently only support one AC Dimmer PWM. Plan to support up to 4 Dimmer on same Phase. - for (uint32_t i = 0; i < MAX_COUNTERS-1; i++) { - if (Light.fade_start_10[i] == 0 && Light.fade_cur_10[i] == 0 && ac_zero_cross_dimmer.PWM_ON[i]==false ) continue; - if (ac_zero_cross_dimmer.pwm_defined[i] && (ac_zero_cross_dimmer.startMeasurePhase[i] == 0 || ac_zero_cross_dimmer.PWM_ON[i] == false ) ) - { - uint32_t phaseStart_ActualClockCycles; // As-Is positon of PWM after Zero Cross - uint32_t phaseStart_ToBeClockCycles; // To be position after zero-cross to fire PWM start - int16_t phaseShift_ClockCycles; // - - - // reset trigger for PWM sync - ac_zero_cross_dimmer.startReSync = false; - // calculate timeoffset to fire PWM based on Dimmer - phaseStart_ToBeClockCycles = (ac_zero_cross_dimmer.tobe_cycle_timeClockCycles * (1024 - ac_zero_cross_power(Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]))) / 1024; - - // Limit range to avoid overshoot and undershoot - phaseStart_ToBeClockCycles = tmin(tmax(phaseStart_ToBeClockCycles, 160000), 0.95* ac_zero_cross_dimmer.tobe_cycle_timeClockCycles); - - // Switch OFF dimmer - if (Light.fade_start_10[i] == 0 && !Light.fade_running) { - ac_zero_cross_dimmer.PWM_ON[i]=false; - Light.fade_cur_10[i] = 0; - digitalWrite(Pin(GPIO_PWM1, i), LOW); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT2: [%d], curr: %d, final: %d, fading: %d, phase-shift: %d, ON/OFF: %d"),i, Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_running, phaseStart_ToBeClockCycles,ac_zero_cross_dimmer.PWM_ON[i]); - continue; - } - // Calculyte clockcycles between zero-cross [3] and start of the current PWM signal [i] - phaseStart_ActualClockCycles = ac_zero_cross_dimmer.currentPWMCycleCount[i]-ac_zero_cross_dimmer.currentPWMCycleCount[3]; - - // Calulate additional or less clockcycles to move current phase position to should be position - phaseShift_ClockCycles = (int32_t)((int32_t)phaseStart_ToBeClockCycles-(int32_t)phaseStart_ActualClockCycles)/100; - - if ( ac_zero_cross_dimmer.PWM_ON[i] == 0 ) { - // because in LOOP calculate the timelag to fire PWM correctly with zero-cross - uint32_t timelag_ClockCycles = (ESP.getCycleCount() - ac_zero_cross_dimmer.currentPWMCycleCount[3])%ac_zero_cross_dimmer.tobe_cycle_timeClockCycles; - timelag_ClockCycles = ((phaseStart_ToBeClockCycles + ac_zero_cross_dimmer.tobe_cycle_timeClockCycles) - timelag_ClockCycles)%ac_zero_cross_dimmer.tobe_cycle_timeClockCycles; - - delayMicroseconds(clockCyclesToMicroseconds(timelag_ClockCycles)); - ac_zero_cross_dimmer.PWM_ON[i]=true; - pinMode(Pin(GPIO_PWM1, i), OUTPUT); - } else { - // currentShiftClockCycle is an I-Controller (not PID) to realign the phase. grace time are 5 clock cycles - ac_zero_cross_dimmer.currentShiftClockCycle[i] += phaseShift_ClockCycles > 5 ? 1 : (phaseShift_ClockCycles < -5 ? -1 : 0); - ac_zero_cross_dimmer.current_cycle_ClockCycles += ac_zero_cross_dimmer.currentShiftClockCycle[i]+phaseShift_ClockCycles; - } -#ifdef ESP8266 - // 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 - startWaveformClockCycles(Pin(GPIO_PWM1, i), ac_zero_cross_dimmer.high, ac_zero_cross_dimmer.current_cycle_ClockCycles - ac_zero_cross_dimmer.high, 0, -1, 0, true); -#endif // ESP8266 -#ifdef ESP32 - // Under investigation. Still not working - double esp32freq = 1000000.0 / clockCyclesToMicroseconds(ac_zero_cross_dimmer.current_cycle_ClockCycles); - ledcSetup(i, esp32freq, 10); - ledcAttachPin(Pin(GPIO_PWM1, i), i); - ledcWrite(i, 5); - -#endif // ESP32 - - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT: [%d], shift: %d, dimm_time_CCs %d, phaseShift_CCs %d, currentPWMcylce: %lu, current_cycle_CC: %lu, lastcc %lu, currentSteps %lu, currDIM %lu, last delta:%lu"), - i, ac_zero_cross_dimmer.currentShiftClockCycle[i], phaseStart_ToBeClockCycles,phaseShift_ClockCycles,ac_zero_cross_dimmer.currentPWMCycleCount[i],ac_zero_cross_dimmer.current_cycle_ClockCycles , ac_zero_cross_dimmer.lastCycleCount, ac_zero_cross_dimmer.currentSteps, Light.fade_cur_10[i],phaseStart_ActualClockCycles); // Light fading - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("CNT: [%d], curr: %d, final: %d, fading: %d, phase-shift: %d, ON/OFF: %d"),i, Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_running, phaseStart_ToBeClockCycles,ac_zero_cross_dimmer.PWM_ON[i]); - - } // do sync onchannel - } // loop on counter - } // zero cross detected -} // end SyncACDimmer -#endif //USE_AC_ZERO_CROSS_DIMMER - /*********************************************************************************************\ * Commands \*********************************************************************************************/ @@ -406,11 +280,6 @@ bool Xsns01(uint32_t function) case FUNC_JSON_APPEND: CounterShow(1); break; -#ifdef USE_AC_ZERO_CROSS_DIMMER - case FUNC_EVERY_50_MSECOND: - SyncACDimmer(); - break; -#endif //USE_AC_ZERO_CROSS_DIMMER #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: CounterShow(0);