MycilaJSY 13.0.0
Arduino / ESP32 library for the JSY1031, JSY-MK-163, JSY-MK-193, JSY-MK-194, JSY-MK-227, JSY-MK-229, JSY-MK-333 families single-phase and three-phase AC bidirectional meters from Shenzhen Jiansiyan Technologies Co, Ltd.
Loading...
Searching...
No Matches
MycilaDimmerThyristor.h
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2023-2025 Mathieu Carbou
4 */
5#pragma once
6
7#include "MycilaDimmer.h"
8#include <driver/gptimer_types.h>
9
10namespace Mycila {
14 class ThyristorDimmer : public Dimmer {
15 public:
16 virtual ~ThyristorDimmer() { end(); }
17
21 void setPin(gpio_num_t pin) { _pin = pin; }
22
26 gpio_num_t getPin() const { return _pin; }
27
31 void setSemiPeriod(uint16_t semiPeriod) {
32 if (semiPeriod == 0) {
33 ESP_LOGE("Thyristor", "setSemiPeriod: semiPeriod must be > 0");
34 }
35 assert(semiPeriod > 0);
36 _semiPeriod = semiPeriod;
37 }
38
42 uint16_t getSemiPeriod() const { return _semiPeriod; }
43
50 uint16_t getFiringDelay() const { return _delay > _semiPeriod ? _semiPeriod : _delay; }
51
57 float getPhaseAngle() const { return _delay >= _semiPeriod ? 180 : 180 * _delay / _semiPeriod; }
58
65 void begin() override;
66
72 void end() override;
73
74 const char* type() const override { return "thyristor"; }
75
76 bool calculateMetrics(Metrics& metrics, float gridVoltage, float loadResistance) const override {
77 return isEnabled() && _calculatePhaseControlMetrics(metrics, _dutyCycleFire, gridVoltage, loadResistance);
78 }
79
90 static void onZeroCross(int16_t delayUntilZero, void* args);
91
92#ifdef MYCILA_JSON_SUPPORT
98 void toJson(const JsonObject& root) const override {
99 Dimmer::toJson(root);
100 root["dimmer_pin"] = _pin;
101 root["dimmer_semi_period"] = _semiPeriod;
102 root["dimmer_firing_delay"] = getFiringDelay();
103 root["dimmer_firing_angle"] = getPhaseAngle();
104 }
105#endif
106
107 protected:
108 bool _apply() override {
109 if (!_online || !_semiPeriod || _dutyCycleFire == 0) {
110 _delay = UINT16_MAX;
111 return _enabled;
112 }
113 if (_dutyCycleFire == 1) {
114 _delay = 0;
115 return _enabled;
116 }
117 _delay = (1.0f - _dutyCycleFire) * static_cast<float>(_semiPeriod);
118 return _enabled;
119 }
120
121 bool _calculateHarmonics(float* array, size_t n) const override {
122 return _calculatePhaseControlHarmonics(_dutyCycleFire, array, n);
123 }
124
125 private:
126 gpio_num_t _pin = GPIO_NUM_NC;
127 uint16_t _delay = UINT16_MAX; // this is the next firing delay to apply
128
129 static bool _fireTimerISR(gptimer_handle_t timer, const gptimer_alarm_event_data_t* event, void* arg);
130 static void _registerDimmer(Mycila::ThyristorDimmer* dimmer);
131 static void _unregisterDimmer(Mycila::ThyristorDimmer* dimmer);
132 };
133} // namespace Mycila
bool isEnabled() const
Check if the dimmer is enabled (if it was able to initialize correctly).
Thyristor (TRIAC) based dimmer implementation for TRIAC and Random SSR dimmers.
gpio_num_t getPin() const
Get the GPIO pin used for the dimmer.
static void onZeroCross(int16_t delayUntilZero, void *args)
void begin() override
Enable a dimmer on a specific GPIO pin.
void setPin(gpio_num_t pin)
Set the GPIO pin to use for the dimmer.
uint16_t getSemiPeriod() const
Get the semi-period of the grid frequency in us.
void setSemiPeriod(uint16_t semiPeriod)
Set the semi-period of the grid frequency in us. It cannot be zero and it is required for proper dimm...
float getPhaseAngle() const
Get the phase angle in degrees (°) of the dimmer in the range [0, 180] At 0% power,...
uint16_t getFiringDelay() const
Get the firing delay in us of the dimmer in the range [0, semi-period] At 0% power,...
void end() override
Disable the dimmer.