mirror of https://github.com/arendst/Tasmota.git
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_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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue