From 314dbf5e6b498b6d37ed403bc517a7d1efac1eac Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 29 Oct 2022 19:08:06 +0200 Subject: [PATCH] Add support for second energy channel calibration --- .../tasmota_xdrv_driver/xdrv_03_energy.ino | 75 ++++++++++++------- .../tasmota_xnrg_energy/xnrg_01_hlw8012.ino | 6 +- .../tasmota_xnrg_energy/xnrg_02_cse7766.ino | 9 ++- .../tasmota_xnrg_energy/xnrg_04_mcp39f501.ino | 8 +- .../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 23 ++++-- .../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 17 +++-- .../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 16 ++-- .../tasmota_xnrg_energy/xnrg_22_bl6523.ino | 60 +++++++-------- tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 11 ++- 9 files changed, 135 insertions(+), 90 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino index f6e90ca2b..d0a308a16 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino @@ -637,11 +637,6 @@ void EnergyEverySecond(void) * Commands \*********************************************************************************************/ -void EnergyCommandCalResponse(uint32_t nvalue) { - snprintf_P(XdrvMailbox.command, CMDSZ, PSTR("%sCal"), XdrvMailbox.command); - ResponseCmndNumber(nvalue); -} - void ResponseCmndEnergyTotalYesterdayToday(void) { char value_chr[TOPSZ]; // Used by EnergyFormatIndex char value2_chr[TOPSZ]; @@ -835,71 +830,101 @@ void CmndTariff(void) { GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF } +void EnergyCommandCalSetResponse(uint32_t cal_type) { + if (XdrvMailbox.payload > 999) { + uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0; + if (channel) { + switch (cal_type) { + case 0: Settings->energy_power_calibration2 = XdrvMailbox.payload; break; + case 1: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break; + case 2: Settings->energy_current_calibration2 = XdrvMailbox.payload; break; + case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break; + } + } else { + switch (cal_type) { + case 0: Settings->energy_power_calibration = XdrvMailbox.payload; break; + case 1: Settings->energy_voltage_calibration = XdrvMailbox.payload; break; + case 2: Settings->energy_current_calibration = XdrvMailbox.payload; break; + case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break; + } + } + } + if (3 == cal_type) { + ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration); + } else { + uint32_t cal_array[2][3]; + memcpy(&cal_array, &Settings->energy_power_calibration, 24); + if (2 == Energy.phase_count) { + ResponseAppend_P(PSTR("[%d,%d]}"), cal_array[0][cal_type], cal_array[1][cal_type]); + } else { + ResponseAppend_P(PSTR("%d}"), cal_array[0][cal_type]); + } + } +} + +void EnergyCommandCalResponse(uint32_t cal_type) { + Response_P(PSTR("{\"%s\":"), XdrvMailbox.command); + EnergyCommandCalSetResponse(cal_type); +} + +void EnergyCommandSetCalResponse(uint32_t cal_type) { + Response_P(PSTR("{\"%sCal\":"), XdrvMailbox.command); + EnergyCommandCalSetResponse(cal_type); +} + void CmndPowerCal(void) { Energy.command_code = CMND_POWERCAL; if (XnrgCall(FUNC_COMMAND)) { // microseconds - if (XdrvMailbox.payload > 999) { - Settings->energy_power_calibration = XdrvMailbox.payload; - } - ResponseCmndNumber(Settings->energy_power_calibration); + EnergyCommandCalResponse(0); } } void CmndVoltageCal(void) { Energy.command_code = CMND_VOLTAGECAL; if (XnrgCall(FUNC_COMMAND)) { // microseconds - if (XdrvMailbox.payload > 999) { - Settings->energy_voltage_calibration = XdrvMailbox.payload; - } - ResponseCmndNumber(Settings->energy_voltage_calibration); + EnergyCommandCalResponse(1); } } void CmndCurrentCal(void) { Energy.command_code = CMND_CURRENTCAL; if (XnrgCall(FUNC_COMMAND)) { // microseconds - if (XdrvMailbox.payload > 999) { - Settings->energy_current_calibration = XdrvMailbox.payload; - } - ResponseCmndNumber(Settings->energy_current_calibration); + EnergyCommandCalResponse(2); } } void CmndFrequencyCal(void) { Energy.command_code = CMND_FREQUENCYCAL; if (XnrgCall(FUNC_COMMAND)) { // microseconds - if (XdrvMailbox.payload > 999) { - Settings->energy_frequency_calibration = XdrvMailbox.payload; - } - ResponseCmndNumber(Settings->energy_frequency_calibration); + EnergyCommandCalResponse(3); } } void CmndPowerSet(void) { Energy.command_code = CMND_POWERSET; if (XnrgCall(FUNC_COMMAND)) { // Watt - EnergyCommandCalResponse(Settings->energy_power_calibration); + EnergyCommandSetCalResponse(0); } } void CmndVoltageSet(void) { Energy.command_code = CMND_VOLTAGESET; if (XnrgCall(FUNC_COMMAND)) { // Volt - EnergyCommandCalResponse(Settings->energy_voltage_calibration); + EnergyCommandSetCalResponse(1); } } void CmndCurrentSet(void) { Energy.command_code = CMND_CURRENTSET; if (XnrgCall(FUNC_COMMAND)) { // milliAmpere - EnergyCommandCalResponse(Settings->energy_current_calibration); + EnergyCommandSetCalResponse(2); } } void CmndFrequencySet(void) { Energy.command_code = CMND_FREQUENCYSET; if (XnrgCall(FUNC_COMMAND)) { // Hz - EnergyCommandCalResponse(Settings->energy_frequency_calibration); + EnergyCommandSetCalResponse(3); } } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino index 883dfdbb2..d28347af5 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino @@ -290,17 +290,17 @@ bool HlwCommand(void) { } else if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len && Hlw.cf_power_pulse_length ) { - Settings->energy_power_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio; + XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio; } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len && Hlw.cf1_voltage_pulse_length ) { - Settings->energy_voltage_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio; + XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio; } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len && Hlw.cf1_current_pulse_length) { - Settings->energy_current_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio; + XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio; } } else serviced = false; // Unknown command diff --git a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino index 296bd6520..6717304cf 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino @@ -63,7 +63,8 @@ void CseReceived(void) { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load // 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W) - // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok + // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok, F1 = CF overflow, no problem + // 55 5A 02 F1 E8 00 07 9D 00 3F 3E 00 35 F8 50 DB 38 00 B2 A2 F1 D6 97 3E - CF overflow // 55 5A 02 DB 40 00 03 25 00 3D 18 03 8E CD 4F 0A 60 2A 56 85 61 01 02 1A - OK voltage // 55 5A 02 DB 40 07 17 1D 00 3D 18 03 8E CD 4F 0A 60 2B EF EA 61 01 02 2C - Wrong voltage @@ -256,17 +257,17 @@ bool CseCommand(void) { if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len && Cse.power_cycle) { - Settings->energy_power_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF; + XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF; } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len && Cse.voltage_cycle) { - Settings->energy_voltage_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF; + XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF; } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len && Cse.current_cycle) { - Settings->energy_current_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000; + XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000; } } else serviced = false; // Unknown command diff --git a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino index 7601731a4..807176c64 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino @@ -602,7 +602,7 @@ bool McpCommand(void) if (XdrvMailbox.data_len && mcp_active_power) { value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100); if ((value > 100) && (value < 200000)) { // Between 1W and 2000W - Settings->energy_power_calibration = value; + XdrvMailbox.payload = value; mcp_calibrate |= MCP_CALIBRATE_POWER; McpGetCalibration(); } @@ -612,7 +612,7 @@ bool McpCommand(void) if (XdrvMailbox.data_len && mcp_voltage_rms) { value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10); if ((value > 1000) && (value < 2600)) { // Between 100V and 260V - Settings->energy_voltage_calibration = value; + XdrvMailbox.payload = value; mcp_calibrate |= MCP_CALIBRATE_VOLTAGE; McpGetCalibration(); } @@ -622,7 +622,7 @@ bool McpCommand(void) if (XdrvMailbox.data_len && mcp_current_rms) { value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10); if ((value > 100) && (value < 80000)) { // Between 10mA and 8A - Settings->energy_current_calibration = value; + XdrvMailbox.payload = value; mcp_calibrate |= MCP_CALIBRATE_CURRENT; McpGetCalibration(); } @@ -632,7 +632,7 @@ bool McpCommand(void) if (XdrvMailbox.data_len && mcp_line_frequency) { value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000); if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz - Settings->energy_frequency_calibration = value; + XdrvMailbox.payload = value; mcp_calibrate |= MCP_CALIBRATE_FREQUENCY; McpGetFrequency(); } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino index 49686aca8..4cf12061b 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino @@ -463,12 +463,16 @@ void Ade7953GetData(void) { for (uint32_t channel = 0; channel < 2; channel++) { Energy.data_valid[channel] = 0; + float power_calibration = ((channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration) / 10; + float voltage_calibration = (channel) ? Settings->energy_voltage_calibration2 : Settings->energy_voltage_calibration; + float current_calibration = ((channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration) * 10; + Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1); - divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration; + divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration; Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider; - divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10); + divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration; Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider; - divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10); + divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration; Energy.reactive_power[channel] = (float)reactive_power[channel] / divider; if (ADE7953_SHELLY_EM == Ade7953.model) { if (bitRead(acc_mode, 10 +channel)) { // APSIGN @@ -478,12 +482,12 @@ void Ade7953GetData(void) { Energy.reactive_power[channel] *= -1; } } - divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10); + divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration; Energy.apparent_power[channel] = (float)apparent_power[channel] / divider; if (0 == Energy.active_power[channel]) { Energy.current[channel] = 0; } else { - divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10); + divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : current_calibration; Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider; Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36; } @@ -657,6 +661,9 @@ void Ade7953DrvInit(void) { Settings->energy_power_calibration = ADE7953_PREF; Settings->energy_voltage_calibration = ADE7953_UREF; Settings->energy_current_calibration = ADE7953_IREF; + Settings->energy_power_calibration2 = ADE7953_PREF; + Settings->energy_voltage_calibration2 = ADE7953_UREF; + Settings->energy_current_calibration2 = ADE7953_IREF; } Ade7953Defaults(); @@ -705,21 +712,21 @@ bool Ade7953Command(void) { else if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len && Ade7953.active_power[channel]) { if ((value > 100) && (value < 200000)) { // Between 1W and 2000W - Settings->energy_power_calibration = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W + XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W } } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) { if ((value > 10000) && (value < 26000)) { // Between 100V and 260V - Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V + XdrvMailbox.payload = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V } } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) { if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A - Settings->energy_current_calibration = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA + XdrvMailbox.payload = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA } } } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino index f73a276b8..dd44ac14f 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino @@ -193,9 +193,11 @@ void Bl09XXUpdateEnergy() { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature); #endif for (uint32_t chan = 0; chan < Energy.phase_count; chan++) { - if (Bl09XX.power[chan] > Settings->energy_power_calibration) { // We need at least 1W - Energy.active_power[chan] = (float)Bl09XX.power[chan] / Settings->energy_power_calibration; - Energy.current[chan] = (float)Bl09XX.current[chan] / Settings->energy_current_calibration; + uint32_t power_calibration = (chan) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration; + uint32_t current_calibration = (chan) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration; + if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W + Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration; + Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration; } else { Energy.active_power[chan] = 0; Energy.current[chan] = 0; @@ -289,6 +291,9 @@ void Bl09XXInit(void) { Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model]; Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model]; Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model]; + Settings->energy_voltage_calibration2 = bl09xx_uref[Bl09XX.model]; + Settings->energy_current_calibration2 = bl09xx_iref[Bl09XX.model]; + Settings->energy_power_calibration2 = bl09xx_pref[Bl09XX.model]; } if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) { Settings->energy_current_calibration *= 100; @@ -357,17 +362,17 @@ bool Bl09XXCommand(void) { if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len && Bl09XX.power[channel]) { - Settings->energy_power_calibration = (Bl09XX.power[channel] * 100) / value; + XdrvMailbox.payload = (Bl09XX.power[channel] * 100) / value; } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len && Bl09XX.voltage) { - Settings->energy_voltage_calibration = (Bl09XX.voltage * 100) / value; + XdrvMailbox.payload = (Bl09XX.voltage * 100) / value; } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len && Bl09XX.current[channel]) { - Settings->energy_current_calibration = (Bl09XX.current[channel] * 100) / value; + XdrvMailbox.payload = (Bl09XX.current[channel] * 100) / value; } } else serviced = false; // Unknown command diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino index ec6647a76..02c13e121 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino @@ -226,6 +226,8 @@ bool Cse7761ChipInit(void) { Settings->energy_voltage_calibration = Cse7761Ref(RmsUC); Settings->energy_current_calibration = Cse7761Ref(RmsIAC); Settings->energy_power_calibration = Cse7761Ref(PowerPAC); + Settings->energy_current_calibration2 = Settings->energy_current_calibration; + Settings->energy_power_calibration2 = Settings->energy_power_calibration; } // Just to fix intermediate users if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) { @@ -466,15 +468,17 @@ void Cse7761GetData(void) { for (uint32_t channel = 0; channel < 2; channel++) { Energy.data_valid[channel] = 0; + uint32_t power_calibration = (channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration; // Active power = PowerPA * PowerPAC * 1000 / 0x80000000 // Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W - Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / Settings->energy_power_calibration; // W + Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W if (0 == Energy.active_power[channel]) { Energy.current[channel] = 0; } else { + uint32_t current_calibration = (channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration; // Current = RmsIA * RmsIAC / 0x800000 // Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A - Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / Settings->energy_current_calibration; // A + Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A CSE7761Data.energy[channel] += Energy.active_power[channel]; CSE7761Data.energy_update[channel]++; } @@ -616,7 +620,7 @@ bool Cse7761Command(void) { else if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len && CSE7761Data.active_power[channel]) { if ((value > 100) && (value < 200000)) { // Between 1W and 2000W - Settings->energy_power_calibration = ((CSE7761Data.active_power[channel]) / value) * 100; + XdrvMailbox.payload = ((CSE7761Data.active_power[channel]) / value) * 100; } } } @@ -627,7 +631,7 @@ bool Cse7761Command(void) { else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len && CSE7761Data.voltage_rms) { if ((value > 10000) && (value < 26000)) { // Between 100V and 260V - Settings->energy_voltage_calibration = (CSE7761Data.voltage_rms * 100) / value; + XdrvMailbox.payload = (CSE7761Data.voltage_rms * 100) / value; } } } @@ -638,7 +642,7 @@ bool Cse7761Command(void) { else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len && CSE7761Data.current_rms[channel]) { if ((value > 1000) && (value < 1000000)) { // Between 10mA and 10A - Settings->energy_current_calibration = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000; + XdrvMailbox.payload = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000; } } } @@ -650,7 +654,7 @@ bool Cse7761Command(void) { else if (CMND_FREQUENCYSET == Energy.command_code) { if (XdrvMailbox.data_len && CSE7761Data.frequency) { if ((value > 4500) && (value < 6500)) { // Between 45.00Hz and 65.00Hz - Settings->energy_frequency_calibration = (CSE7761Data.frequency * 8 * value) / 100; + XdrvMailbox.payload = (CSE7761Data.frequency * 8 * value) / 100; } } } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino index f9714b052..c87fd2a30 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino @@ -22,24 +22,24 @@ /*********************************************************************************************\ * Chinese BL6523 based Watt hour meter * - * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh + * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh * To use Tasmota the user needs to add an ESP8266 or ESP32 * Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND) - * + * * Connection Eg (ESP8266) - Non - Isolated: * BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable) * BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable) * BL6523 GND -> ESP GND - * + * * Connection Eg (ESP32) - Non - Isolated: * BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable) * BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable) * BL6523 GND -> ESP GND - * + * * To build add the below to user_config_override.h * #define USE_ENERGY_SENSOR // Enable Energy sensor framework * #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸ - * + * * After Installation use the below template sample: * {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} \*********************************************************************************************/ @@ -106,7 +106,7 @@ bool Bl6523ReadData(void) Bl6523RxSerial->flush(); // Make room for another burst AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE); - + i=0; while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE) { @@ -116,15 +116,15 @@ bool Bl6523ReadData(void) break; } } - + uint8_t tx_buffer[BL6523_TX_DATASET_SIZE]; Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE); Bl6523TxSerial->flush(); // Make room for another burst - + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE); - + /* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */ uint8_t crc = rx_buffer[1]; //Addr for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++) @@ -136,15 +136,15 @@ bool Bl6523ReadData(void) if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1]) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE)); - Bl6523TxSerial->flush(); - Bl6523RxSerial->flush(); + Bl6523TxSerial->flush(); + Bl6523RxSerial->flush(); return false; } /* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum ) WRITE Sample(RX): RX: CA 3E 55 00 00 6C (WRPROT - allow) -RX: CA 14 00 00 10 DB (MODE) +RX: CA 14 00 00 10 DB (MODE) RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain ) RX: CA 19 08 00 00 DE (WA_CFDIV ) RX: CA 3E AA 00 00 17 (WRPROT - disable) @@ -154,8 +154,8 @@ RX: CA 3E AA 00 00 17 (WRPROT - disable) READ Sample(RX-TX) Data: RX: 35 05 TX: E4 00 00 16 (IA rms ) RX: 35 07 TX: D5 A3 2E 52 (V rms ) -RX: 35 09 TX: F0 FB 02 09 (FREQ) -RX: 35 0A TX: 00 00 00 F5 (WATT) +RX: 35 09 TX: F0 FB 02 09 (FREQ) +RX: 35 0A TX: 00 00 00 F5 (WATT) RX: 35 08 TX: 00 00 00 F7 (PF) RX: 35 0C TX: 00 00 00 F3 (WATT_HR) */ @@ -169,7 +169,7 @@ switch(rx_buffer[1]) { break; case BL6523_REG_FREQ : Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz - break; + break; case BL6523_REG_WATTS : Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_power_calibration; // -196.3 W break; @@ -181,7 +181,7 @@ switch(rx_buffer[1]) { powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]); powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits - powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1)))); + powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1)))); powf_word = powf_word & (0x7fffff >> (1+i)); } powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set @@ -190,8 +190,8 @@ switch(rx_buffer[1]) { case BL6523_REG_WATTHR : Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( Settings->energy_power_calibration - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal() break; - default : - break; + default : + break; } Energy.data_valid[SINGLE_PHASE] = 0; EnergyUpdateTotal(); @@ -201,7 +201,7 @@ switch(rx_buffer[1]) { Bl6523.discovery_triggered = true; } return true; - + } /*********************************************************************************************/ @@ -216,7 +216,7 @@ void Bl6523Update(void) { if (Bl6523.valid) { Bl6523.valid--; - } + } } } @@ -224,7 +224,7 @@ void Bl6523Update(void) void Bl6523Init(void) { - + Bl6523.type = 0; Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1); Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1); @@ -247,7 +247,7 @@ void Bl6523Init(void) AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" )); TasmotaGlobal.energy_driver = ENERGY_NONE; } - + } bool Bl6523Command(void) { @@ -262,28 +262,28 @@ bool Bl6523Command(void) { else if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value > 100) && (abs_value < 200000)) { // Between 1.00 and 2000.00 W - Settings->energy_power_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value > 10000) && (abs_value < 26000)) { // Between 100.00 and 260.00 V - Settings->energy_voltage_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value > 1000) && (abs_value < 1000000)) { // Between 10.00 mA and 10.00000 A - Settings->energy_current_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_FREQUENCYSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value > 4500) && (abs_value < 6500)) { // Between 45.00 and 65.00 Hz - Settings->energy_frequency_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } @@ -323,7 +323,7 @@ void Bl6523DrvInit(void) AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" )); TasmotaGlobal.energy_driver = ENERGY_NONE; } - + } /*********************************************************************************************\ @@ -333,7 +333,7 @@ void Bl6523DrvInit(void) bool Xnrg22(uint8_t function) { bool result = false; - + switch (function) { case FUNC_EVERY_250_MSECOND: @@ -341,7 +341,7 @@ bool Xnrg22(uint8_t function) break; case FUNC_COMMAND: result = Bl6523Command(); - break; + break; case FUNC_INIT: Bl6523Init(); break; @@ -349,7 +349,7 @@ bool Xnrg22(uint8_t function) Bl6523DrvInit(); break; } - + return result; } diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino index 065c909af..b77474a12 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino @@ -84,28 +84,28 @@ bool NrgDummyCommand(void) { else if (CMND_POWERSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value >= 100) && (abs_value <= 16000000)) { // Between 1.00 and 160000.00 W - Settings->energy_power_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_VOLTAGESET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value >= 10000) && (abs_value <= 40000)) { // Between 100.00 and 400.00 V - Settings->energy_voltage_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_CURRENTSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value >= 1000) && (abs_value <= 40000000)) { // Between 10.00 mA and 400.00000 A - Settings->energy_current_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } else if (CMND_FREQUENCYSET == Energy.command_code) { if (XdrvMailbox.data_len) { if ((abs_value >= 4500) && (abs_value <= 6500)) { // Between 45.00 and 65.00 Hz - Settings->energy_frequency_calibration = abs_value; + XdrvMailbox.payload = abs_value; } } } @@ -134,6 +134,9 @@ void NrgDummyDrvInit(void) { Settings->energy_voltage_calibration = NRG_DUMMY_UREF; Settings->energy_current_calibration = NRG_DUMMY_IREF; Settings->energy_power_calibration = NRG_DUMMY_PREF; + Settings->energy_voltage_calibration2 = NRG_DUMMY_UREF; + Settings->energy_current_calibration2 = NRG_DUMMY_IREF; + Settings->energy_power_calibration2 = NRG_DUMMY_PREF; } Energy.phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;