Skip to content

Commit 0e6e4e8

Browse files
committed
Prep support Sonoff Pow CT
1 parent 344fdf9 commit 0e6e4e8

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

tasmota/include/tasmota_template.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ const char kSensorNamesFixed[] PROGMEM =
509509
#define MAX_DINGTIAN_SHIFT 4
510510
#define MAX_MAGIC_SWITCH_MODES 2
511511
#define MAX_BL0942_RX 8 // Baudrates 1/5 (4800), 2/6 (9600), 3/7 (19200), 4/8 (38400), Support Positive values only 1..4, Support also negative values 5..8
512+
#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT)
512513

513514
const uint16_t kGpioNiceList[] PROGMEM = {
514515
GPIO_NONE, // Not used
@@ -886,7 +887,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
886887
#endif // USE_ADE7953
887888
#ifdef USE_CSE7761
888889
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
889-
AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3)
890+
AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT)
890891
#endif
891892
#ifdef USE_CSE7766
892893
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)

tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#ifdef USE_ENERGY_SENSOR
2121
#ifdef USE_CSE7761
2222
/*********************************************************************************************\
23-
* CSE7761 - Energy (Sonoff Dual R3 Pow)
23+
* CSE7761 - Energy (Sonoff Dual R3 Pow and Pox CT)
2424
*
2525
* Without zero-cross detection
2626
* {"NAME":"Sonoff Dual R3","GPIO":[32,0,0,0,0,0,0,0,0,576,225,0,0,0,0,0,0,0,0,0,0,7296,7328,224,0,0,0,0,160,161,0,0,0,0,0,0],"FLAG":0,"BASE":1}
@@ -88,6 +88,8 @@ enum CSE7761 { RmsIAC, RmsIBC, RmsUC, PowerPAC, PowerPBC, PowerSC, EnergyAC, Ene
8888

8989
TasmotaSerial *Cse7761Serial = nullptr;
9090

91+
enum CSE7761Model { CSE7761_MODEL_DUALR3, CSE7761_MODEL_POWCT }; // Model index number starting from 0
92+
9193
struct {
9294
uint32_t frequency = 0;
9395
uint32_t voltage_rms = 0;
@@ -98,6 +100,7 @@ struct {
98100
uint8_t energy_update[2] = { 0 };
99101
uint8_t init = 4;
100102
uint8_t ready = 0;
103+
uint8_t model;
101104
} CSE7761Data;
102105

103106
/********************************************************************************************/
@@ -442,33 +445,39 @@ void Cse7761GetData(void) {
442445
#endif
443446
CSE7761Data.active_power[0] = (0 == CSE7761Data.current_rms[0]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
444447

445-
value = Cse7761ReadFallback(CSE7761_REG_RMSIB, CSE7761Data.current_rms[1], 3);
448+
if (2 == Energy->phase_count) {
449+
value = Cse7761ReadFallback(CSE7761_REG_RMSIB, CSE7761Data.current_rms[1], 3);
446450
#ifdef CSE7761_SIMULATE
447-
value = 29760; // 0.185A
451+
value = 29760; // 0.185A
448452
#endif
449-
CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA
450-
value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4);
453+
CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA
454+
value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4);
451455
#ifdef CSE7761_SIMULATE
452-
value = 2126641; // 44.05W
456+
value = 2126641; // 44.05W
453457
#endif
454-
CSE7761Data.active_power[1] = (0 == CSE7761Data.current_rms[1]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
458+
CSE7761Data.active_power[1] = (0 == CSE7761Data.current_rms[1]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
459+
}
455460

456461
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("C61: F%d, U%d, I%d/%d, P%d/%d"),
457462
CSE7761Data.frequency, CSE7761Data.voltage_rms,
458463
CSE7761Data.current_rms[0], CSE7761Data.current_rms[1],
459464
CSE7761Data.active_power[0], CSE7761Data.active_power[1]);
460465

461466
if (Energy->power_on) { // Powered on
462-
// Voltage = RmsU * RmsUC * 10 / 0x400000
463-
// Energy->voltage[0] = (float)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
464-
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)); // V
465-
Energy->voltage[1] = Energy->voltage[0];
467+
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
468+
if (0 == channel) {
469+
// Voltage = RmsU * RmsUC * 10 / 0x400000
470+
// Energy->voltage[0] = (float)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
471+
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)); // V
466472
#ifdef CSE7761_FREQUENCY
467-
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
468-
Energy->frequency[1] = Energy->frequency[0];
473+
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
469474
#endif
470-
471-
for (uint32_t channel = 0; channel < 2; channel++) {
475+
} else {
476+
Energy->voltage[1] = Energy->voltage[0];
477+
#ifdef CSE7761_FREQUENCY
478+
Energy->frequency[1] = Energy->frequency[0];
479+
#endif
480+
}
472481
Energy->data_valid[channel] = 0;
473482
uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel);
474483
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
@@ -563,7 +572,7 @@ void Cse7761EverySecond(void) {
563572
}
564573
else {
565574
if (2 == CSE7761Data.ready) {
566-
for (uint32_t channel = 0; channel < 2; channel++) {
575+
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
567576
if (CSE7761Data.energy_update[channel]) {
568577
Energy->kWhtoday_delta[channel] += ((CSE7761Data.energy[channel] * 1000) / CSE7761Data.energy_update[channel]) / 36;
569578
CSE7761Data.energy[channel] = 0;
@@ -577,7 +586,7 @@ void Cse7761EverySecond(void) {
577586

578587
void Cse7761SnsInit(void) {
579588
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
580-
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX), Pin(GPIO_CSE7761_TX), 1);
589+
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX, GPIO_ANY), Pin(GPIO_CSE7761_TX), 1);
581590
if (Cse7761Serial->begin(38400, SERIAL_8E1)) {
582591
if (Cse7761Serial->hardwareSerial()) {
583592
SetSerial(38400, TS_SERIAL_8E1);
@@ -599,10 +608,15 @@ void Cse7761SnsInit(void) {
599608
}
600609

601610
void Cse7761DrvInit(void) {
602-
if (PinUsed(GPIO_CSE7761_RX) && PinUsed(GPIO_CSE7761_TX)) {
611+
if (PinUsed(GPIO_CSE7761_RX, GPIO_ANY) && PinUsed(GPIO_CSE7761_TX)) {
612+
CSE7761Data.model = GetPin(Pin(GPIO_CSE7761_RX, GPIO_ANY)) - AGPIO(GPIO_CSE7761_RX);
603613
CSE7761Data.ready = 0;
604-
CSE7761Data.init = 4; // Init setup steps
605-
Energy->phase_count = 2; // Handle two channels as two phases
614+
CSE7761Data.init = 4; // Init setup steps
615+
616+
// Energy->phase_count = 1; // Handle one channel (default set by xdrv_03_energy.ino)
617+
if (CSE7761_MODEL_DUALR3 == CSE7761Data.model) {
618+
Energy->phase_count = 2; // Handle two channels as two phases
619+
}
606620
Energy->voltage_common = true; // Use common voltage
607621
#ifdef CSE7761_FREQUENCY
608622
Energy->frequency_common = true; // Use common frequency
@@ -615,7 +629,10 @@ void Cse7761DrvInit(void) {
615629
bool Cse7761Command(void) {
616630
bool serviced = true;
617631

618-
uint32_t channel = (2 == XdrvMailbox.index) ? 1 : 0;
632+
uint32_t channel = 0;
633+
if (Energy->phase_count > 1) {
634+
channel = (2 == XdrvMailbox.index) ? 1 : 0;
635+
}
619636
uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123
620637

621638
if (CMND_POWERCAL == Energy->command_code) {

0 commit comments

Comments
 (0)