mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 12:46:34 +00:00
Prep support Sonoff Pow CT
This commit is contained in:
parent
344fdf94f7
commit
0e6e4e8949
@ -509,6 +509,7 @@ const char kSensorNamesFixed[] PROGMEM =
|
|||||||
#define MAX_DINGTIAN_SHIFT 4
|
#define MAX_DINGTIAN_SHIFT 4
|
||||||
#define MAX_MAGIC_SWITCH_MODES 2
|
#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_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 = {
|
const uint16_t kGpioNiceList[] PROGMEM = {
|
||||||
GPIO_NONE, // Not used
|
GPIO_NONE, // Not used
|
||||||
@ -886,7 +887,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||||||
#endif // USE_ADE7953
|
#endif // USE_ADE7953
|
||||||
#ifdef USE_CSE7761
|
#ifdef USE_CSE7761
|
||||||
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
|
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
|
#endif
|
||||||
#ifdef USE_CSE7766
|
#ifdef USE_CSE7766
|
||||||
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)
|
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#ifdef USE_ENERGY_SENSOR
|
#ifdef USE_ENERGY_SENSOR
|
||||||
#ifdef USE_CSE7761
|
#ifdef USE_CSE7761
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* CSE7761 - Energy (Sonoff Dual R3 Pow)
|
* CSE7761 - Energy (Sonoff Dual R3 Pow and Pox CT)
|
||||||
*
|
*
|
||||||
* Without zero-cross detection
|
* 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}
|
* {"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;
|
TasmotaSerial *Cse7761Serial = nullptr;
|
||||||
|
|
||||||
|
enum CSE7761Model { CSE7761_MODEL_DUALR3, CSE7761_MODEL_POWCT }; // Model index number starting from 0
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t frequency = 0;
|
uint32_t frequency = 0;
|
||||||
uint32_t voltage_rms = 0;
|
uint32_t voltage_rms = 0;
|
||||||
@ -98,6 +100,7 @@ struct {
|
|||||||
uint8_t energy_update[2] = { 0 };
|
uint8_t energy_update[2] = { 0 };
|
||||||
uint8_t init = 4;
|
uint8_t init = 4;
|
||||||
uint8_t ready = 0;
|
uint8_t ready = 0;
|
||||||
|
uint8_t model;
|
||||||
} CSE7761Data;
|
} CSE7761Data;
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
@ -442,16 +445,18 @@ void Cse7761GetData(void) {
|
|||||||
#endif
|
#endif
|
||||||
CSE7761Data.active_power[0] = (0 == CSE7761Data.current_rms[0]) ? 0 : (value & 0x80000000) ? (~value) + 1 : value;
|
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
|
#ifdef CSE7761_SIMULATE
|
||||||
value = 29760; // 0.185A
|
value = 29760; // 0.185A
|
||||||
#endif
|
#endif
|
||||||
CSE7761Data.current_rms[1] = ((value >= 0x800000) || (value < 1600)) ? 0 : value; // No load threshold of 10mA
|
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);
|
value = Cse7761ReadFallback(CSE7761_REG_POWERPB, CSE7761Data.active_power[1], 4);
|
||||||
#ifdef CSE7761_SIMULATE
|
#ifdef CSE7761_SIMULATE
|
||||||
value = 2126641; // 44.05W
|
value = 2126641; // 44.05W
|
||||||
#endif
|
#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"),
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("C61: F%d, U%d, I%d/%d, P%d/%d"),
|
||||||
CSE7761Data.frequency, CSE7761Data.voltage_rms,
|
CSE7761Data.frequency, CSE7761Data.voltage_rms,
|
||||||
@ -459,16 +464,20 @@ void Cse7761GetData(void) {
|
|||||||
CSE7761Data.active_power[0], CSE7761Data.active_power[1]);
|
CSE7761Data.active_power[0], CSE7761Data.active_power[1]);
|
||||||
|
|
||||||
if (Energy->power_on) { // Powered on
|
if (Energy->power_on) { // Powered on
|
||||||
// Voltage = RmsU * RmsUC * 10 / 0x400000
|
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
|
||||||
// Energy->voltage[0] = (float)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
|
if (0 == channel) {
|
||||||
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)); // V
|
// Voltage = RmsU * RmsUC * 10 / 0x400000
|
||||||
Energy->voltage[1] = Energy->voltage[0];
|
// 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
|
#ifdef CSE7761_FREQUENCY
|
||||||
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
|
Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
|
||||||
Energy->frequency[1] = Energy->frequency[0];
|
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
for (uint32_t channel = 0; channel < 2; channel++) {
|
Energy->voltage[1] = Energy->voltage[0];
|
||||||
|
#ifdef CSE7761_FREQUENCY
|
||||||
|
Energy->frequency[1] = Energy->frequency[0];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Energy->data_valid[channel] = 0;
|
Energy->data_valid[channel] = 0;
|
||||||
uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel);
|
uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel);
|
||||||
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
|
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
|
||||||
@ -563,7 +572,7 @@ void Cse7761EverySecond(void) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (2 == CSE7761Data.ready) {
|
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]) {
|
if (CSE7761Data.energy_update[channel]) {
|
||||||
Energy->kWhtoday_delta[channel] += ((CSE7761Data.energy[channel] * 1000) / CSE7761Data.energy_update[channel]) / 36;
|
Energy->kWhtoday_delta[channel] += ((CSE7761Data.energy[channel] * 1000) / CSE7761Data.energy_update[channel]) / 36;
|
||||||
CSE7761Data.energy[channel] = 0;
|
CSE7761Data.energy[channel] = 0;
|
||||||
@ -577,7 +586,7 @@ void Cse7761EverySecond(void) {
|
|||||||
|
|
||||||
void Cse7761SnsInit(void) {
|
void Cse7761SnsInit(void) {
|
||||||
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
// 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->begin(38400, SERIAL_8E1)) {
|
||||||
if (Cse7761Serial->hardwareSerial()) {
|
if (Cse7761Serial->hardwareSerial()) {
|
||||||
SetSerial(38400, TS_SERIAL_8E1);
|
SetSerial(38400, TS_SERIAL_8E1);
|
||||||
@ -599,10 +608,15 @@ void Cse7761SnsInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Cse7761DrvInit(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.ready = 0;
|
||||||
CSE7761Data.init = 4; // Init setup steps
|
CSE7761Data.init = 4; // Init setup steps
|
||||||
Energy->phase_count = 2; // Handle two channels as two phases
|
|
||||||
|
// 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
|
Energy->voltage_common = true; // Use common voltage
|
||||||
#ifdef CSE7761_FREQUENCY
|
#ifdef CSE7761_FREQUENCY
|
||||||
Energy->frequency_common = true; // Use common frequency
|
Energy->frequency_common = true; // Use common frequency
|
||||||
@ -615,7 +629,10 @@ void Cse7761DrvInit(void) {
|
|||||||
bool Cse7761Command(void) {
|
bool Cse7761Command(void) {
|
||||||
bool serviced = true;
|
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
|
uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123
|
||||||
|
|
||||||
if (CMND_POWERCAL == Energy->command_code) {
|
if (CMND_POWERCAL == Energy->command_code) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user