From 6a6675d4df9c216ddc48b2be35a52fc82b8743f2 Mon Sep 17 00:00:00 2001 From: sascha Date: Wed, 11 Aug 2021 11:08:01 -0700 Subject: [PATCH] Fixed missing fading completed events --- CHANGELOG.md | 1 + src/dimmer.cpp | 136 +++++++++++------------ src/dimmer.h | 121 ++++++++++---------- src/main.cpp | 292 ++++++++++++++++++++++++------------------------- src/main.h | 33 ++++-- 5 files changed, 300 insertions(+), 283 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f706b2..fd1b3e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.2.1-dev - Stop/freeze fading command + - Fixed missing fading completed events ## 2.2.0 diff --git a/src/dimmer.cpp b/src/dimmer.cpp index b895087..68754a2 100644 --- a/src/dimmer.cpp +++ b/src/dimmer.cpp @@ -72,11 +72,11 @@ MeasureTimer timer2; ISR(TIMER2_OVF_vect) { timer2._overflow++; -#if HAVE_FADE_COMPLETION_EVENT - if (queues.fading_completed_events.timer > 0) { - queues.fading_completed_events.timer--; - } -#endif + #if HAVE_FADE_COMPLETION_EVENT + if (queues.fading_completed_events.timer > 0) { + queues.fading_completed_events.timer--; + } + #endif if (queues.check_temperature.timer > 0) { queues.check_temperature.timer--; } @@ -156,11 +156,11 @@ void DimmerBase::end() void DimmerBase::zc_interrupt_handler(uint24_t ticks) { -#if HAVE_DISABLE_ZC_SYNC - if (zc_sync_disabled) { - return; - } -#endif + #if HAVE_DISABLE_ZC_SYNC + if (zc_sync_disabled) { + return; + } + #endif int24_t diff; if (dimmer_config.zero_crossing_delay_ticks) { // schedule next _start_halfwave() call @@ -175,15 +175,15 @@ void DimmerBase::zc_interrupt_handler(uint24_t ticks) } diff -= dimmer_config.zero_crossing_delay_ticks; -#if DIMMER_OUT_OF_SYNC_LIMIT - if (!sync_event.sync && (sync_event.lost || sync_event.halfwave_counter > 1)) { - // send in-sync event - sync_event.sync = true; - sync_event.sync_difference_cycles = diff; - queues.scheduled_calls.sync_event = true; - } - out_of_sync_counter = 0; -#endif + #if DIMMER_OUT_OF_SYNC_LIMIT + if (!sync_event.sync && (sync_event.lost || sync_event.halfwave_counter > 1)) { + // send in-sync event + sync_event.sync = true; + sync_event.sync_difference_cycles = diff; + queues.scheduled_calls.sync_event = true; + } + out_of_sync_counter = 0; + #endif memcpy(ordered_channels, ordered_channels_buffer, sizeof(ordered_channels)); sei(); @@ -235,32 +235,32 @@ void DimmerBase::_start_halfwave() Channel::type i; toggle_state = _config.bits.leading_edge ? DIMMER_MOSFET_OFF_STATE : DIMMER_MOSFET_ON_STATE; -#if DIMMER_MAX_CHANNELS > 1 - channel_ptr = 0; -#endif - -#if DIMMER_OUT_OF_SYNC_LIMIT - if (++out_of_sync_counter >= DIMMER_OUT_OF_SYNC_LIMIT) { - Timer<1>::int_mask_disable::kIntMaskCompareAB>(); - _set_all_mosfet_gates(DIMMER_MOSFET_OFF_STATE); - // store counter and send event - sync_event.lost = true; - sync_event.halfwave_counter = out_of_sync_counter; - queues.scheduled_calls.sync_event = true; - return; - } -#else - Timer<1>::disable_compareB(); -#endif + #if DIMMER_MAX_CHANNELS > 1 + channel_ptr = 0; + #endif + + #if DIMMER_OUT_OF_SYNC_LIMIT + if (++out_of_sync_counter >= DIMMER_OUT_OF_SYNC_LIMIT) { + Timer<1>::int_mask_disable::kIntMaskCompareAB>(); + _set_all_mosfet_gates(DIMMER_MOSFET_OFF_STATE); + // store counter and send event + sync_event.lost = true; + sync_event.halfwave_counter = out_of_sync_counter; + queues.scheduled_calls.sync_event = true; + return; + } + #else + Timer<1>::disable_compareB(); + #endif if (ordered_channels[0].ticks) { // any channel dimmed? -#if DIMMER_OUT_OF_SYNC_LIMIT - //Timer<1>::enable_compareA_disable_compareB(); - Timer<1>::int_mask_toggle::kIntMaskCompareA, Timer<1>::kIntMaskCompareB>(); -#else - //Timer<1>::enable_compareA(); - Timer<1>::int_mask_enable::kIntMaskCompareA>(); -#endif + #if DIMMER_OUT_OF_SYNC_LIMIT + //Timer<1>::enable_compareA_disable_compareB(); + Timer<1>::int_mask_toggle::kIntMaskCompareA, Timer<1>::kIntMaskCompareB>(); + #else + //Timer<1>::enable_compareA(); + Timer<1>::int_mask_enable::kIntMaskCompareA>(); + #endif OCR1A = ordered_channels[0].ticks; for(i = 0; ordered_channels[i].ticks; i++) { _set_mosfet_gate(ordered_channels[i].channel, toggle_state); @@ -280,25 +280,25 @@ void DimmerBase::_start_halfwave() } } else { -#if DIMMER_OUT_OF_SYNC_LIMIT - Timer<1>::int_mask_toggle::kFlagsCompareB, Timer<1>::kFlagsCompareA>(); - //Timer<1>::enable_compareB_disable_compareA(); -#else - Timer<1>::int_mask_disable::kFlagsCompareA>(); - // Timer<1>::disable_compareA(); -#endif + #if DIMMER_OUT_OF_SYNC_LIMIT + Timer<1>::int_mask_toggle::kFlagsCompareB, Timer<1>::kFlagsCompareA>(); + //Timer<1>::enable_compareB_disable_compareA(); + #else + Timer<1>::int_mask_disable::kFlagsCompareA>(); + // Timer<1>::disable_compareA(); + #endif // enable or disable channels DIMMER_CHANNEL_LOOP(i) { _set_mosfet_gate(i, _get_level(i) == Level::max ? DIMMER_MOSFET_ON_STATE : DIMMER_MOSFET_OFF_STATE); } } -#if DIMMER_OUT_OF_SYNC_LIMIT - // keep counter up to date - if (!sync_event.lost && !sync_event.sync) { - sync_event.halfwave_counter = out_of_sync_counter; - } -#endif + #if DIMMER_OUT_OF_SYNC_LIMIT + // keep counter up to date + if (!sync_event.lost && !sync_event.sync) { + sync_event.halfwave_counter = out_of_sync_counter; + } + #endif PIN_D11_CLEAR(); } @@ -399,15 +399,16 @@ void DimmerBase::set_channel_level(ChannelType channel, Level::type level) _set_level(channel, _normalize_level(level)); fading[channel].count = 0; // disable fading for this channel -#if HAVE_FADE_COMPLETION_EVENT - if (fading_completed[channel] != Level::invalid) { - // send event with the new level - fading_completed[channel] = _get_level(channel); - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - queues.scheduled_calls.send_fading_events = true; + #if HAVE_FADE_COMPLETION_EVENT + if (fading_completed[channel] != Level::invalid) { + // send event with the new level + fading_completed[channel] = _get_level(channel); + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + queues.scheduled_calls.send_fading_events = true; + queues.fading_completed_events.resetTimer(); + } } - } -#endif + #endif _calculate_channels(); @@ -430,9 +431,9 @@ void DimmerBase::fade_channel_from_to(ChannelType channel, Level::type from, Lev { float diff; dimmer_fade_t &fade = fading[channel]; -#if HAVE_FADE_COMPLETION_EVENT - fading_completed[channel] = Level::invalid; -#endif + #if HAVE_FADE_COMPLETION_EVENT + fading_completed[channel] = Level::invalid; + #endif if (_get_level(channel) == 0) { on_counter[channel] = 0; @@ -506,6 +507,7 @@ void DimmerBase::_apply_fading() fading_completed[i] = _get_level(i); ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { queues.scheduled_calls.send_fading_events = true; + queues.fading_completed_events.resetTimer(); } #endif } else { diff --git a/src/dimmer.h b/src/dimmer.h index fdc3ed4..437bf31 100644 --- a/src/dimmer.h +++ b/src/dimmer.h @@ -33,10 +33,10 @@ struct dimmer_channel_t { uint16_t ticks; }; -typedef struct __attribute__((packed)) { +struct __attribute__((packed)) FadingCompletionEvent_t { dimmer_channel_id_t channel; dimmer_level_t level; -} FadingCompletionEvent_t; +}; #if not HAVE_CHANNELS_INLINE_ASM extern volatile uint8_t *dimmer_pins_addr[::size_of(DIMMER_MOSFET_PINS)]; @@ -62,7 +62,6 @@ namespace Dimmer { static constexpr TickType TickTypeMax = ~0; static constexpr float kVRef = INTERNAL_VREF_1_1V; - template struct Timer {}; @@ -72,11 +71,11 @@ namespace Dimmer { static constexpr uint8_t extraTicks = __extraTicks == 0 ? 1 : __extraTicks; // add 48 clock cycles but at least one tick }; -#ifdef DIMMER_TIMER2_PRESCALER - template<> - struct Timer<2> : Timers::TimerBase<2, DIMMER_TIMER2_PRESCALER> { - }; -#endif + #ifdef DIMMER_TIMER2_PRESCALER + template<> + struct Timer<2> : Timers::TimerBase<2, DIMMER_TIMER2_PRESCALER> { + }; + #endif struct FrequencyTimer : Timers::TimerBase<1, 1> { static inline void begin() { @@ -216,9 +215,9 @@ namespace Dimmer { struct dimmer_t { Level::type level[Channel::size()]; // current level dimmer_fade_t fading[Channel::size()]; // calculated fading data -#if DIMMER_MAX_CHANNELS > 1 - Channel::type channel_ptr; -#endif + #if DIMMER_MAX_CHANNELS > 1 + Channel::type channel_ptr; + #endif dimmer_channel_t ordered_channels[Channel::size() + 1]; // current dimming levels in ticks dimmer_channel_t ordered_channels_buffer[Channel::size() + 1]; // next dimming levels uint8_t on_counter[Channel::size()]; // counts halfwaves from 0 to 254 after switching on @@ -226,19 +225,19 @@ namespace Dimmer { float zc_diff_ticks; uint8_t zc_diff_count; uint8_t channel_state; // bitset of the channel state - bool toggle_state: 1; -#if HAVE_DISABLE_ZC_SYNC - bool zc_sync_disabled: 1; -#endif - -#if DIMMER_OUT_OF_SYNC_LIMIT - uint16_t out_of_sync_counter; - dimmer_sync_event_t sync_event; -#endif - -#if HAVE_FADE_COMPLETION_EVENT - Level::type fading_completed[Channel::size()]; -#endif + bool toggle_state; + #if HAVE_DISABLE_ZC_SYNC + bool zc_sync_disabled; + #endif + + #if DIMMER_OUT_OF_SYNC_LIMIT + uint16_t out_of_sync_counter; + dimmer_sync_event_t sync_event; + #endif + + #if HAVE_FADE_COMPLETION_EVENT + Level::type fading_completed[Channel::size()]; + #endif float halfwave_ticks_avg; float halfwave_ticks_avg2; }; @@ -356,39 +355,41 @@ namespace Dimmer { inline float _get_frequency() const { return register_mem.data.metrics.frequency; } -#if HAVE_CHANNELS_INLINE_ASM - inline void _set_all_mosfet_gates(bool state) { - if (state) { - // if it fails to build here, run the build process again. the required include file is created automatically - DIMMER_SFR_ENABLE_ALL_CHANNELS(); - } - else { - DIMMER_SFR_DISABLE_ALL_CHANNELS(); - } - } - inline void _set_mosfet_gate(Channel::type channel, bool state) { - if (state) { - DIMMER_SFR_CHANNELS_ENABLE(channel); + + #if HAVE_CHANNELS_INLINE_ASM + inline void _set_all_mosfet_gates(bool state) { + if (state) { + // if it fails to build here, run the build process again. the required include file is created automatically + DIMMER_SFR_ENABLE_ALL_CHANNELS(); + } + else { + DIMMER_SFR_DISABLE_ALL_CHANNELS(); + } } - else { - DIMMER_SFR_CHANNELS_DISABLE(channel); + inline void _set_mosfet_gate(Channel::type channel, bool state) { + if (state) { + DIMMER_SFR_CHANNELS_ENABLE(channel); + } + else { + DIMMER_SFR_CHANNELS_DISABLE(channel); + } } - } -#else - inline void _set_all_mosfet_gates(bool state) { - DIMMER_CHANNEL_LOOP(i) { - _set_mosfet_gate(i, state); + #else + inline void _set_all_mosfet_gates(bool state) { + DIMMER_CHANNEL_LOOP(i) { + _set_mosfet_gate(i, state); + } } - } - inline void _set_mosfet_gate(Channel::type channel, bool state) { - if (state) { - *dimmer_pins_addr[channel] |= dimmer_pins_mask[channel]; + inline void _set_mosfet_gate(Channel::type channel, bool state) { + if (state) { + *dimmer_pins_addr[channel] |= dimmer_pins_mask[channel]; + } + else { + *dimmer_pins_addr[channel] &= ~dimmer_pins_mask[channel]; + } } - else { - *dimmer_pins_addr[channel] &= ~dimmer_pins_mask[channel]; - } - } -#endif + #endif + void _calculate_channels(); register_mem_cfg_t &_config; @@ -398,18 +399,26 @@ namespace Dimmer { template struct DimmerEvent { - inline static void send(const uint8_t *buffer, uint8_t length) + inline static void _send(const uint8_t *buffer, uint8_t length) { Wire.write(buffer, length); Wire.endTransmission(); } + template + static void send(const _Type &data, uint8_t length) + { + Wire.beginTransmission(DIMMER_I2C_MASTER_ADDRESS); + Wire.write(_Event); + _send(reinterpret_cast(&data), length); + } + template static void send(const _Type &data) { Wire.beginTransmission(DIMMER_I2C_MASTER_ADDRESS); Wire.write(_Event); - send(reinterpret_cast(&data), (uint8_t)sizeof(data)); + _send(reinterpret_cast(&data), static_cast(sizeof(data))); } template @@ -418,7 +427,7 @@ namespace Dimmer { Wire.beginTransmission(DIMMER_I2C_MASTER_ADDRESS); Wire.write(_Event); Wire.write(extraByte); - send(reinterpret_cast(&data), (uint8_t)sizeof(data)); + _send(reinterpret_cast(&data), static_cast(sizeof(data))); } }; diff --git a/src/main.cpp b/src/main.cpp index 370d052..27971c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,6 @@ #include "measure_frequency.h" #include "adc.h" - Queues queues; void rem() @@ -46,27 +45,24 @@ void display_dimmer_info() rem(); Serial.printf_P(PSTR("options=EEPROM=%lu,"), conf.getEEPROMWriteCount()); -#if HAVE_NTC - Serial.printf_P(PSTR("NTC=A%u,"), NTC_PIN - A0); -#endif -#if HAVE_READ_INT_TEMP - Serial.print(F("int.temp,")); -#endif -#if HAVE_READ_VCC - Serial.print(F("VCC,")); -#endif -#if HAVE_FADE_COMPLETION_EVENT - Serial.print(F("fading_events=1,")); -#endif -#if SERIAL_I2C_BRDIGE - Serial.print(F("proto=UART,")); -#else - Serial.print(F("proto=I2C,")); -#endif - Serial.printf_P(PSTR("addr=%02x,mode=%c,"), - DIMMER_I2C_ADDRESS, - (dimmer_config.bits.leading_edge ? 'L' : 'T') - ); + #if HAVE_NTC + Serial.printf_P(PSTR("NTC=A%u,"), NTC_PIN - A0); + #endif + #if HAVE_READ_INT_TEMP + Serial.print(F("int.temp,")); + #endif + #if HAVE_READ_VCC + Serial.print(F("VCC,")); + #endif + #if HAVE_FADE_COMPLETION_EVENT + Serial.print(F("fading_events=1,")); + #endif + #if SERIAL_I2C_BRDIGE + Serial.print(F("proto=UART,")); + #else + Serial.print(F("proto=I2C,")); + #endif + Serial.printf_P(PSTR("addr=%02x,mode=%c,"), DIMMER_I2C_ADDRESS, (dimmer_config.bits.leading_edge ? 'L' : 'T')); Serial.printf_P(PSTR("timer1=%u/%.2f,lvls=" _STRINGIFY(DIMMER_MAX_LEVEL) ",pins="), Dimmer::Timer<1>::prescaler, Dimmer::Timer<1>::ticksPerMicrosecond); for(auto pin: Dimmer::Channel::pins) { Serial.print(pin); @@ -77,20 +73,20 @@ void display_dimmer_info() rem(); Serial.printf_P(PSTR("values=restore=%u,f=%.3fHz,vref11=%.3f,"), dimmer_config.bits.restore_level, dimmer._get_frequency(), static_cast(dimmer_config.internal_vref11)); -#if HAVE_NTC - Serial.printf_P(PSTR("NTC=%.2f/%+.2f,"), get_ntc_temperature(), (float)dimmer_config.ntc_temp_cal_offset); -#endif -#if HAVE_READ_INT_TEMP - Serial.printf_P(PSTR("int.temp=%d/ofs=%u/gain=%u,"), - get_internal_temperature(), - dimmer_config.internal_temp_calibration.ts_offset, - dimmer_config.internal_temp_calibration.ts_gain - ); -#endif + #if HAVE_NTC + Serial.printf_P(PSTR("NTC=%.2f/%+.2f,"), get_ntc_temperature(), (float)dimmer_config.ntc_temp_cal_offset); + #endif + #if HAVE_READ_INT_TEMP + Serial.printf_P(PSTR("int.temp=%d/ofs=%u/gain=%u,"), + get_internal_temperature(), + dimmer_config.internal_temp_calibration.ts_offset, + dimmer_config.internal_temp_calibration.ts_gain + ); + #endif Serial.printf_P(PSTR("max.temp=%u,metrics=%u,"), dimmer_config.max_temp, REPORT_METRICS_INTERVAL(dimmer_config.report_metrics_interval)); -#if HAVE_READ_VCC - Serial.printf_P(PSTR("VCC=%.3f,"), read_vcc() / 1000.0); -#endif + #if HAVE_READ_VCC + Serial.printf_P(PSTR("VCC=%.3f,"), read_vcc() / 1000.0); + #endif Serial.printf_P(PSTR("min.on-time=%u,min.off=%u,ZC-delay=%u,"), dimmer_config.minimum_on_time_ticks, dimmer_config.minimum_off_time_ticks, @@ -109,25 +105,25 @@ void setup() { Serial.begin(DEFAULT_BAUD_RATE); -#if SERIAL_I2C_BRDIGE && DEBUG - _debug_level = 9; -#endif + #if SERIAL_I2C_BRDIGE && DEBUG + _debug_level = 9; + #endif -#if HIDE_DIMMER_INFO == 0 - rem(); - Serial.println(F("BOOT")); - Serial.flush(); -#endif + #if HIDE_DIMMER_INFO == 0 + rem(); + Serial.println(F("BOOT")); + Serial.flush(); + #endif dimmer_i2c_slave_setup(); conf.readConfig(); -#if HAVE_POTI - pinMode(POTI_PIN, INPUT); -#endif -#if HAVE_NTC - pinMode(NTC_PIN, INPUT); -#endif + #if HAVE_POTI + pinMode(POTI_PIN, INPUT); + #endif + #if HAVE_NTC + pinMode(NTC_PIN, INPUT); + #endif pinMode(ZC_SIGNAL_PIN, INPUT); register_mem.data.errors = {}; @@ -138,25 +134,24 @@ void setup() #if HAVE_FADE_COMPLETION_EVENT -void Dimmer::DimmerBase::send_fading_completion_events() -{ - FadingCompletionEvent_t buffer[Dimmer::Channel::size()]; - FadingCompletionEvent_t *ptr = buffer; + void Dimmer::DimmerBase::send_fading_completion_events() + { + FadingCompletionEvent_t buffer[Dimmer::Channel::size()]; + FadingCompletionEvent_t *ptr = buffer; - ATOMIC_BLOCK(ATOMIC_FORCEON) { DIMMER_CHANNEL_LOOP(i) { if (dimmer.fading_completed[i] != Dimmer::Level::invalid) { *ptr++ = { i, dimmer.fading_completed[i] }; dimmer.fading_completed[i] = Dimmer::Level::invalid; } } - } + sei(); - if (ptr != buffer) { - // _D(5, debug_printf("sending fading completion event for %u channel(s)\n", ptr - buffer)); - Dimmer::DimmerEvent::send(reinterpret_cast(buffer), (uint8_t)(reinterpret_cast(ptr) - reinterpret_cast(buffer))); + if (ptr != buffer) { + // _D(5, debug_printf("sending fading completion event for %u channel(s)\n", ptr - buffer)); + Dimmer::DimmerEvent::send(buffer, static_cast(reinterpret_cast(ptr) - reinterpret_cast(buffer))); + } } -} #endif @@ -211,11 +206,11 @@ void loop() Dimmer::DimmerEvent::send(register_mem.data.metrics); // Dimmer::DimmerEvent::send(register_mem_metrics_t{dimmer._get_frequency(), get_ntc_temperature(), get_internal_temperature(), read_vcc() }); -#if HIDE_DIMMER_INFO == 0 - ATOMIC_BLOCK(ATOMIC_FORCEON) { - queues.scheduled_calls.print_info = true; - } -#endif + #if HIDE_DIMMER_INFO == 0 + ATOMIC_BLOCK(ATOMIC_FORCEON) { + queues.scheduled_calls.print_info = true; + } + #endif } return; } @@ -231,32 +226,32 @@ void loop() dimmer_scheduled_calls_nv_t tmp_scheduled_calls(queues.scheduled_calls); sei(); -#if HIDE_DIMMER_INFO == 0 - if (tmp_scheduled_calls.print_info) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - queues.scheduled_calls.print_info = false; + #if HIDE_DIMMER_INFO == 0 + if (tmp_scheduled_calls.print_info) { + ATOMIC_BLOCK(ATOMIC_FORCEON) { + queues.scheduled_calls.print_info = false; + } + display_dimmer_info(); } - display_dimmer_info(); - } -#endif + #endif auto millis24 = __uint24_from_shr8_ui32(millis()); -#if HAVE_POTI - { - auto level = read_poti(); - if (abs(level - poti_level) >= max(1, (Dimmer::Level::max >> 10)) || (level == 0 && poti_level != 0)) { // = ~0.1% steps - if (level > Dimmer::Level::max) { - level = Dimmer::Level::max; - } - if (poti_level != level) { - poti_level = level; - dimmer.set_channel_level(POTI_CHANNEL, level); + #if HAVE_POTI + { + auto level = read_poti(); + if (abs(level - poti_level) >= max(1, (Dimmer::Level::max >> 10)) || (level == 0 && poti_level != 0)) { // = ~0.1% steps + if (level > Dimmer::Level::max) { + level = Dimmer::Level::max; + } + if (poti_level != level) { + poti_level = level; + dimmer.set_channel_level(POTI_CHANNEL, level); + } } - } - } -#endif + } + #endif if (tmp_scheduled_calls.report_error) { ATOMIC_BLOCK(ATOMIC_FORCEON) { @@ -266,43 +261,43 @@ void loop() _D(5, debug_printf("Report error\n")); } -#if HAVE_PRINT_METRICS - - if (queues.print_metrics.interval && millis24 >= queues.print_metrics.timer) { - queues.print_metrics.timer = millis24 + queues.print_metrics.interval; - rem(); - #if HAVE_NTC - Serial.printf_P(PSTR("NTC=%.2f°C(%.1f),"), get_ntc_temperature(), _adc.getNTC_ADCValueAsFloat()); - #endif - #if HAVE_READ_INT_TEMP - Serial.printf_P(PSTR("int.temp=%d°C(%.1f),"), get_internal_temperature(), _adc.getIntTemp_ADCValueAsFloat()); - #endif - #if HAVE_READ_VCC || HAVE_EXT_VCC - Serial.printf_P(PSTR("VCC=%umV (%.1f),"), read_vcc(), _adc.getVCC_ADCValueAsFloat()); - #endif - #if HAVE_POTI - Serial.printf_P(PSTR("poti=%.1f,"), _adc.getPoti_ADCValueAsFloat()); - #endif - // Serial.printf_P(PSTR("hw=%u,diff=%d,"), dimmer.halfwave_ticks, (int)dimmer.zc_diff_ticks); - // Serial.printf_P(PSTR("frq=%.3f,mode=%c,lvl="), dimmer._get_frequency(), (dimmer_config.bits.leading_edge) ? 'L' : 'T'); - Serial.printf_P(PSTR("hw=%u,diff=%d,frq=%.3f,mode=%c,lvl="), dimmer.halfwave_ticks, (int)dimmer.zc_diff_ticks, dimmer._get_frequency(), (dimmer_config.bits.leading_edge) ? 'L' : 'T'); - DIMMER_CHANNEL_LOOP(i) { - Serial.printf_P(PSTR("%d,"), register_mem.data.channels.level[i]); - } - Serial.printf_P(PSTR("hf=%u,ticks="), (unsigned)dimmer._get_ticks_per_halfwave()); - DIMMER_CHANNEL_LOOP(j) { - Serial.print(dimmer._get_ticks(j, register_mem.data.channels.level[j])); - if (j < Dimmer::Channel::max) { - Serial.print(','); + #if HAVE_PRINT_METRICS + + if (queues.print_metrics.interval && millis24 >= queues.print_metrics.timer) { + queues.print_metrics.timer = millis24 + queues.print_metrics.interval; + rem(); + #if HAVE_NTC + Serial.printf_P(PSTR("NTC=%.2f°C(%.1f),"), get_ntc_temperature(), _adc.getNTC_ADCValueAsFloat()); + #endif + #if HAVE_READ_INT_TEMP + Serial.printf_P(PSTR("int.temp=%d°C(%.1f),"), get_internal_temperature(), _adc.getIntTemp_ADCValueAsFloat()); + #endif + #if HAVE_READ_VCC || HAVE_EXT_VCC + Serial.printf_P(PSTR("VCC=%umV (%.1f),"), read_vcc(), _adc.getVCC_ADCValueAsFloat()); + #endif + #if HAVE_POTI + Serial.printf_P(PSTR("poti=%.1f,"), _adc.getPoti_ADCValueAsFloat()); + #endif + // Serial.printf_P(PSTR("hw=%u,diff=%d,"), dimmer.halfwave_ticks, (int)dimmer.zc_diff_ticks); + // Serial.printf_P(PSTR("frq=%.3f,mode=%c,lvl="), dimmer._get_frequency(), (dimmer_config.bits.leading_edge) ? 'L' : 'T'); + Serial.printf_P(PSTR("hw=%u,diff=%d,frq=%.3f,mode=%c,lvl="), dimmer.halfwave_ticks, (int)dimmer.zc_diff_ticks, dimmer._get_frequency(), (dimmer_config.bits.leading_edge) ? 'L' : 'T'); + DIMMER_CHANNEL_LOOP(i) { + Serial.printf_P(PSTR("%d,"), register_mem.data.channels.level[i]); + } + Serial.printf_P(PSTR("hf=%u,ticks="), (unsigned)dimmer._get_ticks_per_halfwave()); + DIMMER_CHANNEL_LOOP(j) { + Serial.print(dimmer._get_ticks(j, register_mem.data.channels.level[j])); + if (j < Dimmer::Channel::max) { + Serial.print(','); + } } + Serial.println(); + Serial.flush(); + #if DEBUG + _adc.dump(); + #endif } - Serial.println(); - Serial.flush(); -#if DEBUG - _adc.dump(); -#endif - } -#endif + #endif if (tmp_scheduled_calls.send_channel_state) { cli(); @@ -313,19 +308,20 @@ void loop() Dimmer::DimmerEvent::send(event); } -#if HAVE_FADE_COMPLETION_EVENT - if (tmp_scheduled_calls.send_fading_events) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - queues.scheduled_calls.send_fading_events = false; - queues.fading_completed_events.timer = Queues::kFadingCompletedEventTimerOverFlows; + #if HAVE_FADE_COMPLETION_EVENT + if (tmp_scheduled_calls.send_fading_events) { + cli(); + // wait for timer to collect multiple fading events within 100ms + if (queues.fading_completed_events.timer == 0) { + queues.scheduled_calls.send_fading_events = false; + queues.fading_completed_events.disableTimer(); // disable timer until new events are added + dimmer.send_fading_completion_events(); // calls sei() + } + else { + sei(); + } } - } - if (queues.fading_completed_events.timer == 0) { - // we can set the high byte to 0xff (= -256) to disable the timer if the value is 0 without locking interrupts - reinterpret_cast(&queues.fading_completed_events.timer)[1] = 0xff; - dimmer.send_fading_completion_events(); - } -#endif + #endif if (tmp_scheduled_calls.write_eeprom && conf.isEEPROMWriteTimerExpired()) { conf._writeConfig(false); @@ -357,29 +353,29 @@ void loop() read_vcc(); int16_t current_temp; -#if HAVE_NTC + #if HAVE_NTC - register_mem.data.metrics.ntc_temp = get_ntc_temperature(); - if (!isnan(register_mem.data.metrics.ntc_temp)) { - current_temp = register_mem.data.metrics.ntc_temp; - } -#if HAVE_READ_INT_TEMP - register_mem.data.metrics.int_temp = get_internal_temperature(); - if (!isnan(register_mem.data.metrics.int_temp)) { - current_temp = max(current_temp, register_mem.data.metrics.int_temp); - } -#endif + register_mem.data.metrics.ntc_temp = get_ntc_temperature(); + if (!isnan(register_mem.data.metrics.ntc_temp)) { + current_temp = register_mem.data.metrics.ntc_temp; + } + #if HAVE_READ_INT_TEMP + register_mem.data.metrics.int_temp = get_internal_temperature(); + if (!isnan(register_mem.data.metrics.int_temp)) { + current_temp = max(current_temp, register_mem.data.metrics.int_temp); + } + #endif -#elif HAVE_READ_INT_TEMP + #elif HAVE_READ_INT_TEMP - register_mem.data.metrics.int_temp = get_internal_temperature(); - current_temp = isnan(register_mem.data.metrics.int_temp) ? 0 : register_mem.data.metrics.int_temp; + register_mem.data.metrics.int_temp = get_internal_temperature(); + current_temp = isnan(register_mem.data.metrics.int_temp) ? 0 : register_mem.data.metrics.int_temp; -#else + #else -#error No temperature sensor available + #error No temperature sensor available -#endif + #endif if (dimmer_config.max_temp && current_temp > (int16_t)dimmer_config.max_temp) { diff --git a/src/main.h b/src/main.h index 12bf691..e271dba 100644 --- a/src/main.h +++ b/src/main.h @@ -44,22 +44,31 @@ struct Queues { static constexpr int16_t kFadingCompletedEventTimerOverFlows = Dimmer::MeasureTimer::kMillisToOverflows(100); static constexpr uint16_t kTemperatureCheckTimerOverflows = Dimmer::MeasureTimer::kMillisToOverflows(1000); -#if HAVE_PRINT_METRICS - struct { - uint24_t timer{0}; - uint8_t interval{0}; - } print_metrics; -#endif + #if HAVE_PRINT_METRICS + struct { + uint24_t timer{0}; + uint8_t interval{0}; + } print_metrics; + #endif -#if HAVE_FADE_COMPLETION_EVENT - struct { - int16_t timer{-1}; - } fading_completed_events; -#endif + #if HAVE_FADE_COMPLETION_EVENT + struct { + int16_t timer{-1}; + void disableTimer() { + timer = -1; + } + void resetTimer() { + timer = kFadingCompletedEventTimerOverFlows; + } + } fading_completed_events; + #endif struct { uint16_t timer{kTemperatureCheckTimerOverflows}; uint24_t report_next{0}; + void reset() { + timer = kTemperatureCheckTimerOverflows; + } } check_temperature; struct { @@ -72,5 +81,5 @@ struct Queues { extern Queues queues; #if HIDE_DIMMER_INFO == 0 -void display_dimmer_info(); + void display_dimmer_info(); #endif