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
MycilaDimmerDFRobot.cpp
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright (C) 2023-2025 Mathieu Carbou
4 */
5#include <MycilaDimmerDFRobot.h>
6
7// logging
8#include <esp32-hal-log.h>
9
10#define TAG "DFRobot"
11
13 if (_enabled)
14 return true;
15
16 uint8_t resolution = getResolution();
17 if (!resolution) {
18 ESP_LOGE(TAG, "SKU not set!");
19 return false;
20 }
21
22 // sanity checks
23 if (_sku == SKU::DFR1071_GP8211S) {
24 if (_channel > 0) {
25 ESP_LOGW(TAG, "DFRobot DFR1071 (GP8211S) has only one channel: switching to channel 0");
26 _channel = 0;
27 }
28 }
29
30 if (_channel > 2) {
31 ESP_LOGE(TAG, "Invalid channel %d", _channel);
32 return false;
33 }
34
35 // discovery
36 bool found = false;
37 if (_deviceAddress) {
38 ESP_LOGI(TAG, "Searching for DFRobot @ 0x%02x...", _deviceAddress);
39 for (int i = 0; i < 3; i++) {
40 uint8_t err = _test(_deviceAddress);
41 if (err) {
42 ESP_LOGD(TAG, "DFRobot @ 0x%02x: TwoWire communication error: %d", _deviceAddress, err);
43 delay(10);
44 } else {
45 found = true;
46 break;
47 }
48 }
49
50 } else {
51 ESP_LOGI(TAG, "Searching for DFRobot @ 0x58 up to 0x5F...");
52 for (uint8_t addr = 0x58; !found && addr <= 0x5F; addr++) {
53 if (_test(addr) == ESP_OK) {
54 _deviceAddress = addr;
55 found = true;
56 break;
57 }
58 }
59 }
60
61 if (found) {
62 ESP_LOGI(TAG, "Found DFRobot @ 0x%02x and channel %d", _deviceAddress, _channel);
63 } else if (_deviceAddress) {
64 ESP_LOGW(TAG, "DFRobot @ 0x%02x: Unable to communicate with device", _deviceAddress);
65 } else {
66 _deviceAddress = 0x58;
67 ESP_LOGW(TAG, "DFRobot not found! Using default address 0x58");
68 }
69
70 // set output
71 uint8_t err = _sendOutput(_deviceAddress, _output);
72 if (err) {
73 ESP_LOGE(TAG, "Disable DFRobot @ 0x%02x: Unable to set output voltage: TwoWire communication error: %d", _deviceAddress, err);
74 return false;
75 }
76
77 _enabled = true;
78
79 // restart with last saved value
80 setDutyCycle(_dutyCycle);
81
82 return true;
83}
84
86 if (!_enabled)
87 return;
88 _enabled = false;
89 _online = false;
90 ESP_LOGI(TAG, "Disable DFRobot @ 0x%02x", _deviceAddress);
91 _apply();
92}
93
94uint8_t Mycila::DFRobotDimmer::_sendDutyCycle(uint8_t address, uint16_t duty) {
95 duty = duty << (16 - getResolution());
96 switch (_channel) {
97 case 0: {
98 uint8_t buffer[2] = {uint8_t(duty & 0xff), uint8_t(duty >> 8)};
99 return _send(address, 0x02, buffer, 2) == 0;
100 }
101 case 1: {
102 uint8_t buffer[2] = {uint8_t(duty & 0xff), uint8_t(duty >> 8)};
103 return _send(address, 0x04, buffer, 2) == 0;
104 }
105 case 2: {
106 uint8_t buffer[4] = {uint8_t(duty & 0xff), uint8_t(duty >> 8), uint8_t(duty & 0xff), uint8_t(duty >> 8)};
107 return _send(address, 0x02, buffer, 4) == 0;
108 }
109 default:
110 assert(false); // fail
111 return ESP_FAIL;
112 }
113}
114
115uint8_t Mycila::DFRobotDimmer::_sendOutput(uint8_t address, Output output) {
116 switch (output) {
117 case Output::RANGE_0_5V: {
118 ESP_LOGI(TAG, "Set output range to 0-5V");
119 uint8_t data = 0x00;
120 return _send(address, 0x01, &data, 1);
121 }
122 case Output::RANGE_0_10V: {
123 ESP_LOGI(TAG, "Set output range to 0-10V");
124 uint8_t data = 0x11;
125 return _send(address, 0x01, &data, 1);
126 }
127 default:
128 assert(false); // fail
129 return ESP_FAIL;
130 }
131}
132
133uint8_t Mycila::DFRobotDimmer::_send(uint8_t address, uint8_t reg, uint8_t* buffer, size_t size) {
134 _wire->beginTransmission(address);
135 _wire->write(reg);
136 for (uint16_t i = 0; i < size; i++) {
137 _wire->write(buffer[i]);
138 }
139 return _wire->endTransmission();
140}
141
142uint8_t Mycila::DFRobotDimmer::_test(uint8_t address) {
143 // return _sendDutyCycle(address, 0);
144 _wire->beginTransmission(address);
145 delayMicroseconds(100);
146 return _wire->endTransmission();
147}
bool begin() override
Enable a dimmer on a specific GPIO pin.
uint8_t getResolution() const
Get the PWM resolution in bits.
void end() override
Disable the dimmer.
bool setDutyCycle(float dutyCycle)
Set the power duty.