mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
Update xdrv_68_zerocrossDimmer.ino (#18556)
* Update xdrv_68_zerocrossDimmer.ino * Address IRAM issue report removed some IRAM from ESP8266. Further improvement to ESP32 as soon as measurement is available.
This commit is contained in:
parent
cda2bf157d
commit
c498995f79
@ -29,6 +29,9 @@ static const uint8_t MIN_PERCENT = 5;
|
|||||||
static const uint8_t MAX_PERCENT = 99;
|
static const uint8_t MAX_PERCENT = 99;
|
||||||
static const uint8_t TRIGGER_PERIOD = 75;
|
static const uint8_t TRIGGER_PERIOD = 75;
|
||||||
|
|
||||||
|
#define ZCDIMMERSET_SHOW 1
|
||||||
|
//#define ZC_DEBUG 1
|
||||||
|
|
||||||
struct AC_ZERO_CROSS_DIMMER {
|
struct AC_ZERO_CROSS_DIMMER {
|
||||||
uint32_t cycle_time_us; // Time (in micros()) of last ZC signal
|
uint32_t cycle_time_us; // Time (in micros()) of last ZC signal
|
||||||
uint32_t crossed_zero_at; // Time (in micros()) of last ZC signal
|
uint32_t crossed_zero_at; // Time (in micros()) of last ZC signal
|
||||||
@ -43,6 +46,7 @@ struct AC_ZERO_CROSS_DIMMER {
|
|||||||
uint8_t triggertime = GATE_ENABLE_TIME; // copy of the Time for the gate keep open to start TRIAC
|
uint8_t triggertime = GATE_ENABLE_TIME; // copy of the Time for the gate keep open to start TRIAC
|
||||||
uint32_t intr_counter = 0; // counter internally on interrerupt calls
|
uint32_t intr_counter = 0; // counter internally on interrerupt calls
|
||||||
uint32_t missed_zero_cross; // count up all missed Zero-cross events.
|
uint32_t missed_zero_cross; // count up all missed Zero-cross events.
|
||||||
|
uint8_t actual_tigger_Period = TRIGGER_PERIOD; // copy of tigger period to change during runtime
|
||||||
} ac_zero_cross_dimmer;
|
} ac_zero_cross_dimmer;
|
||||||
|
|
||||||
|
|
||||||
@ -83,7 +87,7 @@ void IRAM_ATTR ACDimmerZeroCross(uint32_t time) {
|
|||||||
uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() {
|
uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() {
|
||||||
//ACDimmerTimer_intr();
|
//ACDimmerTimer_intr();
|
||||||
ACDimmerTimer_intr();
|
ACDimmerTimer_intr();
|
||||||
return 6000;
|
return ac_zero_cross_dimmer.actual_tigger_Period * 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACDimmerInterruptDisable(bool disable)
|
void ACDimmerInterruptDisable(bool disable)
|
||||||
@ -96,9 +100,6 @@ void ACDimmerInterruptDisable(bool disable)
|
|||||||
if (dimmer_timer != nullptr) {
|
if (dimmer_timer != nullptr) {
|
||||||
timerAlarmDisable(dimmer_timer);
|
timerAlarmDisable(dimmer_timer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef ESP8266
|
|
||||||
//setTimer1Callback(NULL);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
for (uint8_t i = 0 ; i < MAX_PWMS; i++) {
|
for (uint8_t i = 0 ; i < MAX_PWMS; i++) {
|
||||||
@ -119,32 +120,26 @@ void ACDimmerInterruptDisable(bool disable)
|
|||||||
}
|
}
|
||||||
timerAlarmEnable(dimmer_timer);
|
timerAlarmEnable(dimmer_timer);
|
||||||
#endif
|
#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() {
|
void IRAM_ATTR ACDimmerTimer_intr() {
|
||||||
|
|
||||||
|
uint32_t time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at;
|
||||||
// If no ZC signal received yet.
|
// If no ZC signal received yet.
|
||||||
uint32_t now = micros();
|
if (ac_zero_cross_dimmer.crossed_zero_at == 0) return;
|
||||||
|
|
||||||
|
#ifdef ZC_DEBUG
|
||||||
ac_zero_cross_dimmer.intr_counter++;
|
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;
|
|
||||||
|
|
||||||
// Check for missed Zero-Cross event. Single failure will correct
|
// Check for missed Zero-Cross event. Single failure will correct
|
||||||
if (time_since_zc > 10100) {
|
if (time_since_zc > 10100) {
|
||||||
memset(&ac_zero_cross_dimmer.current_state_in_phase, 0x00, sizeof(ac_zero_cross_dimmer.current_state_in_phase));
|
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;
|
ac_zero_cross_dimmer.crossed_zero_at += ac_zero_cross_dimmer.cycle_time_us;
|
||||||
ac_zero_cross_dimmer.missed_zero_cross++;
|
ac_zero_cross_dimmer.missed_zero_cross++;
|
||||||
time_since_zc = now - ac_zero_cross_dimmer.crossed_zero_at;
|
time_since_zc += ac_zero_cross_dimmer.cycle_time_us;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
ac_zero_cross_dimmer.actual_tigger_Period = TRIGGER_PERIOD;
|
||||||
for (uint8_t i = 0 ; i < MAX_PWMS; i++ ) {
|
for (uint8_t i = 0 ; i < MAX_PWMS; i++ ) {
|
||||||
if (Pin(GPIO_PWM1, i) == -1) continue;
|
if (Pin(GPIO_PWM1, i) == -1) continue;
|
||||||
switch (ac_zero_cross_dimmer.current_state_in_phase[i]) {
|
switch (ac_zero_cross_dimmer.current_state_in_phase[i]) {
|
||||||
@ -159,15 +154,22 @@ void IRAM_ATTR ACDimmerTimer_intr() {
|
|||||||
case 3:
|
case 3:
|
||||||
if (time_since_zc + TRIGGER_PERIOD >= ac_zero_cross_dimmer.enable_time_us[i]){
|
if (time_since_zc + TRIGGER_PERIOD >= ac_zero_cross_dimmer.enable_time_us[i]){
|
||||||
// Very close to the fire event. Loop the last µseconds to wait.
|
// Very close to the fire event. Loop the last µseconds to wait.
|
||||||
|
#ifdef ESP8266
|
||||||
|
// on ESP8266 we can change dynamically the trigger interval
|
||||||
|
ac_zero_cross_dimmer.actual_tigger_Period = tmin(ac_zero_cross_dimmer.actual_tigger_Period,tmax(5,ac_zero_cross_dimmer.enable_time_us[i] - time_since_zc));
|
||||||
|
#endif
|
||||||
|
#ifdef ESP32
|
||||||
while (time_since_zc < ac_zero_cross_dimmer.enable_time_us[i]) {
|
while (time_since_zc < ac_zero_cross_dimmer.enable_time_us[i]) {
|
||||||
now = micros();
|
time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at;
|
||||||
time_since_zc = now - ac_zero_cross_dimmer.crossed_zero_at;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (time_since_zc >= ac_zero_cross_dimmer.enable_time_us[i]) {
|
if (time_since_zc >= ac_zero_cross_dimmer.enable_time_us[i]) {
|
||||||
digitalWrite(Pin(GPIO_PWM1, i), HIGH);
|
digitalWrite(Pin(GPIO_PWM1, i), HIGH);
|
||||||
ac_zero_cross_dimmer.current_state_in_phase[i]++;
|
ac_zero_cross_dimmer.current_state_in_phase[i]++;
|
||||||
|
#ifdef ZC_DEBUG
|
||||||
ac_zero_cross_dimmer.accurracy[i] = time_since_zc-ac_zero_cross_dimmer.enable_time_us[i];
|
ac_zero_cross_dimmer.accurracy[i] = time_since_zc-ac_zero_cross_dimmer.enable_time_us[i];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -175,11 +177,12 @@ void IRAM_ATTR ACDimmerTimer_intr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ACDimmerControllTrigger(void) {
|
void ACDimmerControllTrigger(void) {
|
||||||
|
#ifdef ESP32
|
||||||
if (ac_zero_cross_dimmer.timer_iterrupt_started != ac_zero_cross_dimmer.dimmer_in_use) {
|
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);
|
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);
|
ACDimmerInterruptDisable(!ac_zero_cross_dimmer.dimmer_in_use);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (uint8_t i = 0; i < MAX_PWMS; i++){
|
for (uint8_t i = 0; i < MAX_PWMS; i++){
|
||||||
if (Pin(GPIO_PWM1, i) == -1) continue;
|
if (Pin(GPIO_PWM1, i) == -1) continue;
|
||||||
|
|
||||||
@ -231,6 +234,21 @@ void ACDimmerLogging(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
#ifdef ZCDIMMERSET_SHOW
|
||||||
|
void ACDimmerShow(void)
|
||||||
|
{
|
||||||
|
char c_ZCDimmerSetBuffer[8];
|
||||||
|
for (uint8_t i = 0; i < MAX_PWMS; i++){
|
||||||
|
if (Pin(GPIO_PWM1, i) == -1) continue;
|
||||||
|
if (ac_zero_cross_dimmer.detailpower[i]){
|
||||||
|
dtostrfd(ac_zero_cross_dimmer.detailpower[i]/100.0, 2, c_ZCDimmerSetBuffer);
|
||||||
|
WSContentSend_PD(PSTR("{s}ZCDimmer%d{m}%s %%{e}"), i+1, c_ZCDimmerSetBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ZCDIMMERSET_SHOW
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Commands
|
* Commands
|
||||||
@ -286,6 +304,13 @@ bool Xdrv68(uint32_t function)
|
|||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand);
|
result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand);
|
||||||
break;
|
break;
|
||||||
|
#ifdef USE_WEBSERVER
|
||||||
|
#ifdef ZCDIMMERSET_SHOW
|
||||||
|
case FUNC_WEB_SENSOR:
|
||||||
|
ACDimmerShow();
|
||||||
|
break;
|
||||||
|
#endif // ZCDIMMERSET_SHOW
|
||||||
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user