Prep support Sonoff Pow CT

This commit is contained in:
Theo Arends 2024-07-02 11:38:55 +02:00
parent 344fdf94f7
commit 0e6e4e8949
2 changed files with 40 additions and 22 deletions

View File

@ -509,6 +509,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_DINGTIAN_SHIFT 4
#define MAX_MAGIC_SWITCH_MODES 2
#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
#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT)
const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used
@ -886,7 +887,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#endif // USE_ADE7953
#ifdef USE_CSE7761
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3)
AGPIO(GPIO_CSE7761_RX) + MAX_CSE7761, // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT)
#endif
#ifdef USE_CSE7766
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)

View File

@ -20,7 +20,7 @@
#ifdef USE_ENERGY_SENSOR
#ifdef USE_CSE7761
/*********************************************************************************************\
* CSE7761 - Energy (Sonoff Dual R3 Pow)
* CSE7761 - Energy (Sonoff Dual R3 Pow and Pox CT)
*
* Without zero-cross detection
* {"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
TasmotaSerial *Cse7761Serial = nullptr;
enum CSE7761Model { CSE7761_MODEL_DUALR3, CSE7761_MODEL_POWCT }; // Model index number starting from 0
struct {
uint32_t frequency = 0;
uint32_t voltage_rms = 0;
@ -98,6 +100,7 @@ struct {
uint8_t energy_update[2] = { 0 };
uint8_t init = 4;
uint8_t ready = 0;
uint8_t model;
} CSE7761Data;
/********************************************************************************************/
@ -442,16 +445,18 @@ void Cse7761GetData(void) {
#endif
CSE7761Data.active_power[0] = (0 == CSE7761Data.current_rms[0]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
value = Cse7761ReadFallback(CSE7761_REG_RMSIB, CSE7761Data.current_rms[1], 3);
if (2 == Energy->phase_count) {
value = Cse7761ReadFallback(CSE7761_REG_RMSIB, CSE7761Data.current_rms[1], 3);
#ifdef CSE7761_SIMULATE
value = 29760; // 0.185A
value = 29760; // 0.185A
#endif
CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA
value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4);
CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA
value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4);
#ifdef CSE7761_SIMULATE
value = 2126641; // 44.05W
value = 2126641; // 44.05W
#endif
CSE7761Data.active_power[1] = (0 == CSE7761Data.current_rms[1]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
CSE7761Data.active_power[1] = (0 == CSE7761Data.current_rms[1]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("C61: F%d, U%d, I%d/%d, P%d/%d"),
CSE7761Data.frequency, CSE7761Data.voltage_rms,
@ -459,16 +464,20 @@ void Cse7761GetData(void) {
CSE7761Data.active_power[0], CSE7761Data.active_power[1]);
if (Energy->power_on) { // Powered on
// Voltage = RmsU * RmsUC * 10 / 0x400000
// Energy->voltage[0] = (float)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)); // V
Energy->voltage[1] = Energy->voltage[0];
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
if (0 == channel) {
// Voltage = RmsU * RmsUC * 10 / 0x400000
// Energy->voltage[0] = (float)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)); // V
#ifdef CSE7761_FREQUENCY
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
Energy->frequency[1] = Energy->frequency[0];
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
#endif
for (uint32_t channel = 0; channel < 2; channel++) {
} else {
Energy->voltage[1] = Energy->voltage[0];
#ifdef CSE7761_FREQUENCY
Energy->frequency[1] = Energy->frequency[0];
#endif
}
Energy->data_valid[channel] = 0;
uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel);
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
@ -563,7 +572,7 @@ void Cse7761EverySecond(void) {
}
else {
if (2 == CSE7761Data.ready) {
for (uint32_t channel = 0; channel < 2; channel++) {
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
if (CSE7761Data.energy_update[channel]) {
Energy->kWhtoday_delta[channel] += ((CSE7761Data.energy[channel] * 1000) / CSE7761Data.energy_update[channel]) / 36;
CSE7761Data.energy[channel] = 0;
@ -577,7 +586,7 @@ void Cse7761EverySecond(void) {
void Cse7761SnsInit(void) {
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX), Pin(GPIO_CSE7761_TX), 1);
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX, GPIO_ANY), Pin(GPIO_CSE7761_TX), 1);
if (Cse7761Serial->begin(38400, SERIAL_8E1)) {
if (Cse7761Serial->hardwareSerial()) {
SetSerial(38400, TS_SERIAL_8E1);
@ -599,10 +608,15 @@ void Cse7761SnsInit(void) {
}
void Cse7761DrvInit(void) {
if (PinUsed(GPIO_CSE7761_RX) && PinUsed(GPIO_CSE7761_TX)) {
if (PinUsed(GPIO_CSE7761_RX, GPIO_ANY) && PinUsed(GPIO_CSE7761_TX)) {
CSE7761Data.model = GetPin(Pin(GPIO_CSE7761_RX, GPIO_ANY)) - AGPIO(GPIO_CSE7761_RX);
CSE7761Data.ready = 0;
CSE7761Data.init = 4; // Init setup steps
Energy->phase_count = 2; // Handle two channels as two phases
CSE7761Data.init = 4; // Init setup steps
// Energy->phase_count = 1; // Handle one channel (default set by xdrv_03_energy.ino)
if (CSE7761_MODEL_DUALR3 == CSE7761Data.model) {
Energy->phase_count = 2; // Handle two channels as two phases
}
Energy->voltage_common = true; // Use common voltage
#ifdef CSE7761_FREQUENCY
Energy->frequency_common = true; // Use common frequency
@ -615,7 +629,10 @@ void Cse7761DrvInit(void) {
bool Cse7761Command(void) {
bool serviced = true;
uint32_t channel = (2 == XdrvMailbox.index) ? 1 : 0;
uint32_t channel = 0;
if (Energy->phase_count > 1) {
channel = (2 == XdrvMailbox.index) ? 1 : 0;
}
uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123
if (CMND_POWERCAL == Energy->command_code) {