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:
stefanbode 2023-05-02 15:53:17 +02:00 committed by GitHub
parent cda2bf157d
commit c498995f79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -29,6 +29,9 @@ static const uint8_t MIN_PERCENT = 5;
static const uint8_t MAX_PERCENT = 99;
static const uint8_t TRIGGER_PERIOD = 75;
#define ZCDIMMERSET_SHOW 1
//#define ZC_DEBUG 1
struct AC_ZERO_CROSS_DIMMER {
uint32_t cycle_time_us; // 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
uint32_t intr_counter = 0; // counter internally on interrerupt calls
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;
@ -83,7 +87,7 @@ void IRAM_ATTR ACDimmerZeroCross(uint32_t time) {
uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() {
//ACDimmerTimer_intr();
ACDimmerTimer_intr();
return 6000;
return ac_zero_cross_dimmer.actual_tigger_Period * 80;
}
void ACDimmerInterruptDisable(bool disable)
@ -96,9 +100,6 @@ void ACDimmerInterruptDisable(bool disable)
if (dimmer_timer != nullptr) {
timerAlarmDisable(dimmer_timer);
}
#endif
#ifdef ESP8266
//setTimer1Callback(NULL);
#endif
} else {
for (uint8_t i = 0 ; i < MAX_PWMS; i++) {
@ -119,32 +120,26 @@ void ACDimmerInterruptDisable(bool disable)
}
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() {
uint32_t time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at;
// 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++;
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
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;
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++ ) {
if (Pin(GPIO_PWM1, i) == -1) continue;
switch (ac_zero_cross_dimmer.current_state_in_phase[i]) {
@ -159,15 +154,22 @@ void IRAM_ATTR ACDimmerTimer_intr() {
case 3:
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.
#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]) {
now = micros();
time_since_zc = now - ac_zero_cross_dimmer.crossed_zero_at;
time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at;
}
#endif
}
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]++;
#ifdef ZC_DEBUG
ac_zero_cross_dimmer.accurracy[i] = time_since_zc-ac_zero_cross_dimmer.enable_time_us[i];
#endif
}
break;
}
@ -175,11 +177,12 @@ void IRAM_ATTR ACDimmerTimer_intr() {
}
void ACDimmerControllTrigger(void) {
#ifdef ESP32
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);
}
#endif
for (uint8_t i = 0; i < MAX_PWMS; i++){
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
@ -286,6 +304,13 @@ bool Xdrv68(uint32_t function)
case FUNC_COMMAND:
result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand);
break;
#ifdef USE_WEBSERVER
#ifdef ZCDIMMERSET_SHOW
case FUNC_WEB_SENSOR:
ACDimmerShow();
break;
#endif // ZCDIMMERSET_SHOW
#endif // USE_WEBSERVER
}
}
return result;