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
MycilaDimmer.cpp
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2023-2025 Mathieu Carbou
4 */
5#include <MycilaDimmer.h>
6
7#define DIMMER_RESOLUTION 12
8#define FIRING_DELAYS_LEN 200U
9
10static constexpr uint32_t FIRING_DELAY_MAX = (1 << DIMMER_RESOLUTION) - 1;
11static constexpr uint32_t FIRING_DELAYS_SCALE = (FIRING_DELAYS_LEN - 1U) * (1UL << (16 - DIMMER_RESOLUTION));
12
13// clang-format off
14static constexpr uint16_t FIRING_DELAYS[FIRING_DELAYS_LEN] = {
15 0xffff, 0xe877, 0xe240, 0xddd9, 0xda51, 0xd74f, 0xd4aa, 0xd248, 0xd01a, 0xce16,
16 0xcc34, 0xca6e, 0xc8c0, 0xc728, 0xc5a1, 0xc42b, 0xc2c3, 0xc168, 0xc019, 0xbed3,
17 0xbd98, 0xbc65, 0xbb3b, 0xba17, 0xb8fb, 0xb7e5, 0xb6d5, 0xb5ca, 0xb4c5, 0xb3c4,
18 0xb2c8, 0xb1d1, 0xb0dd, 0xafed, 0xaf01, 0xae18, 0xad33, 0xac51, 0xab71, 0xaa95,
19 0xa9bb, 0xa8e3, 0xa80e, 0xa73b, 0xa66b, 0xa59c, 0xa4d0, 0xa406, 0xa33d, 0xa276,
20 0xa1b1, 0xa0ed, 0xa02b, 0x9f6b, 0x9eac, 0x9dee, 0x9d32, 0x9c76, 0x9bbc, 0x9b04,
21 0x9a4c, 0x9996, 0x98e0, 0x982b, 0x9778, 0x96c5, 0x9613, 0x9563, 0x94b2, 0x9403,
22 0x9354, 0x92a6, 0x91f9, 0x914c, 0x90a0, 0x8ff5, 0x8f4a, 0x8ea0, 0x8df6, 0x8d4d,
23 0x8ca4, 0x8bfb, 0x8b53, 0x8aab, 0x8a04, 0x895d, 0x88b6, 0x8810, 0x876a, 0x86c4,
24 0x861e, 0x8579, 0x84d3, 0x842e, 0x8389, 0x82e4, 0x823f, 0x819b, 0x80f6, 0x8051,
25 0x7fad, 0x7f08, 0x7e63, 0x7dbf, 0x7d1a, 0x7c75, 0x7bd0, 0x7b2b, 0x7a85, 0x79e0,
26 0x793a, 0x7894, 0x77ee, 0x7748, 0x76a1, 0x75fa, 0x7553, 0x74ab, 0x7403, 0x735a,
27 0x72b1, 0x7208, 0x715e, 0x70b4, 0x7009, 0x6f5e, 0x6eb2, 0x6e05, 0x6d58, 0x6caa,
28 0x6bfb, 0x6b4c, 0x6a9b, 0x69eb, 0x6939, 0x6886, 0x67d3, 0x671e, 0x6668, 0x65b2,
29 0x64fa, 0x6442, 0x6388, 0x62cc, 0x6210, 0x6152, 0x6093, 0x5fd3, 0x5f11, 0x5e4d,
30 0x5d88, 0x5cc1, 0x5bf8, 0x5b2e, 0x5a62, 0x5993, 0x58c3, 0x57f0, 0x571b, 0x5643,
31 0x5569, 0x548d, 0x53ad, 0x52cb, 0x51e6, 0x50fd, 0x5011, 0x4f21, 0x4e2d, 0x4d36,
32 0x4c3a, 0x4b39, 0x4a34, 0x4929, 0x4819, 0x4703, 0x45e7, 0x44c3, 0x4399, 0x4266,
33 0x412b, 0x3fe5, 0x3e96, 0x3d3b, 0x3bd3, 0x3a5d, 0x38d6, 0x373e, 0x3590, 0x33ca,
34 0x31e8, 0x2fe4, 0x2db6, 0x2b54, 0x28af, 0x25ad, 0x2225, 0x1dbe, 0x1787, 0x0000
35};
36// clang-format on
37
38// =============================================================================
39// Mycila::Dimmer
40// =============================================================================
41
42uint16_t Mycila::Dimmer::_semiPeriod = 0;
43
44uint16_t Mycila::Dimmer::_lookupFiringDelay(float dutyCycle, uint16_t semiPeriod) {
45 uint32_t duty = dutyCycle * FIRING_DELAY_MAX;
46 uint32_t slot = duty * FIRING_DELAYS_SCALE + (FIRING_DELAYS_SCALE >> 1);
47 uint32_t index = slot >> 16;
48 uint32_t a = FIRING_DELAYS[index];
49 uint32_t b = FIRING_DELAYS[index + 1];
50 uint32_t delay = a - (((a - b) * (slot & 0xffff)) >> 16); // interpolate a b
51 return (delay * semiPeriod) >> 16; // scale to period
52}
53
54#ifdef MYCILA_JSON_SUPPORT
55static const char* H_LEVELS[] = {"H1", "H3", "H5", "H7", "H9", "H11", "H13", "H15", "H17", "H19", "H21"};
56
62void Mycila::Dimmer::toJson(const JsonObject& root) const {
63 root["type"] = type();
64 root["enabled"] = _enabled;
65 root["online"] = _online;
66 root["state"] = isOn() ? "on" : "off";
67 root["duty_cycle"] = _dutyCycle;
68 root["duty_cycle_mapped"] = getDutyCycleMapped();
69 root["duty_cycle_fire"] = _dutyCycleFire;
70 root["duty_cycle_limit"] = _dutyCycleLimit;
71 root["duty_cycle_min"] = _dutyCycleMin;
72 root["duty_cycle_max"] = _dutyCycleMax;
73 root["power_lut"] = _powerLUTEnabled;
74 root["semi_period"] = _semiPeriod;
75 JsonObject harmonics = root["harmonics"].to<JsonObject>();
76 float* output = new float[11]; // H1 to H21
77 if (calculateHarmonics(output, 11)) {
78 for (size_t i = 0; i < 11; i++) {
79 if (!std::isnan(output[i])) {
80 harmonics[H_LEVELS[i]] = output[i];
81 }
82 }
83 }
84}
85#endif