Prep energy for four+ phase support

This commit is contained in:
Theo Arends 2023-01-25 17:05:48 +01:00
parent e891830545
commit 2529759974
10 changed files with 1769 additions and 108 deletions

View File

@ -17,10 +17,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//#ifdef ESP8266 #ifdef ESP8266
#ifdef USE_ENERGY_SENSOR #ifdef USE_ENERGY_SENSOR
/*********************************************************************************************\ /*********************************************************************************************\
* Energy * Energy for ESP8266
\*********************************************************************************************/ \*********************************************************************************************/
#define XDRV_03 3 #define XDRV_03 3
@ -31,6 +31,8 @@
#define ENERGY_NONE 0 #define ENERGY_NONE 0
#define ENERGY_WATCHDOG 4 // Allow up to 4 seconds before deciding no valid data present #define ENERGY_WATCHDOG 4 // Allow up to 4 seconds before deciding no valid data present
#undef ENERGY_MAX_PHASES
#define ENERGY_MAX_PHASES 3 #define ENERGY_MAX_PHASES 3
#include <Ticker.h> #include <Ticker.h>
@ -860,7 +862,7 @@ void CmndTariff(void) {
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
} }
uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) { uint32_t EnergyGetCalibration(uint32_t cal_type, uint32_t chan = 0) {
uint32_t channel = ((1 == chan) && (2 == Energy->phase_count)) ? 1 : 0; uint32_t channel = ((1 == chan) && (2 == Energy->phase_count)) ? 1 : 0;
if (channel) { if (channel) {
switch (cal_type) { switch (cal_type) {
@ -878,32 +880,36 @@ uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
return Settings->energy_frequency_calibration; return Settings->energy_frequency_calibration;
} }
void EnergySetCalibration(uint32_t cal_type, uint32_t value, uint32_t chan = 0) {
uint32_t channel = ((1 == chan) && (2 == Energy->phase_count)) ? 1 : 0;
if (channel) {
switch (cal_type) {
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration2 = value; return;
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration2 = value; return;
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration2 = value; return;
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = value; return;
}
} else {
switch (cal_type) {
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration = value; return;
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration = value; return;
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration = value; return;
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = value; return;
}
}
}
void EnergyCommandCalSetResponse(uint32_t cal_type) { void EnergyCommandCalSetResponse(uint32_t cal_type) {
if (XdrvMailbox.payload > 99) { if (XdrvMailbox.payload > 99) {
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy->phase_count)) ? 1 : 0; EnergySetCalibration(cal_type, XdrvMailbox.payload, XdrvMailbox.index -1);
if (channel) {
switch (cal_type) {
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
} else {
switch (cal_type) {
case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration = XdrvMailbox.payload; break;
case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration = XdrvMailbox.payload; break;
case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
}
} }
if (ENERGY_FREQUENCY_CALIBRATION == cal_type) { if (ENERGY_FREQUENCY_CALIBRATION == cal_type) {
ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration); ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
} else { } else {
if (2 == Energy->phase_count) { if (2 == Energy->phase_count) {
ResponseAppend_P(PSTR("[%d,%d]}"), EnergyGetCalibration(0, cal_type), EnergyGetCalibration(1, cal_type)); ResponseAppend_P(PSTR("[%d,%d]}"), EnergyGetCalibration(cal_type), EnergyGetCalibration(cal_type, 1));
} else { } else {
ResponseAppend_P(PSTR("%d}"), EnergyGetCalibration(0, cal_type)); ResponseAppend_P(PSTR("%d}"), EnergyGetCalibration(cal_type));
} }
} }
} }
@ -1494,4 +1500,4 @@ bool Xsns03(uint32_t function)
} }
#endif // USE_ENERGY_SENSOR #endif // USE_ENERGY_SENSOR
//#endif // ESP8266 #endif // ESP8266

File diff suppressed because it is too large Load Diff

View File

@ -134,7 +134,7 @@ void HlwEvery200ms(void) {
Hlw.cf_pulse_counter = 0; Hlw.cf_pulse_counter = 0;
if (Hlw.cf_power_pulse_length && Energy->power_on && !Hlw.load_off) { if (Hlw.cf_power_pulse_length && Energy->power_on && !Hlw.load_off) {
hlw_w = (Hlw.power_ratio * Settings->energy_power_calibration) / Hlw.cf_power_pulse_length ; // W *10 hlw_w = (Hlw.power_ratio * EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) / Hlw.cf_power_pulse_length ; // W *10
Energy->active_power[0] = (float)hlw_w / 10; Energy->active_power[0] = (float)hlw_w / 10;
Hlw.power_retry = 1; // Workaround issue #5161 Hlw.power_retry = 1; // Workaround issue #5161
} else { } else {
@ -179,7 +179,7 @@ void HlwEvery200ms(void) {
Hlw.cf1_voltage_pulse_length = cf1_pulse_length; Hlw.cf1_voltage_pulse_length = cf1_pulse_length;
if (Hlw.cf1_voltage_pulse_length && Energy->power_on) { // If powered on always provide voltage if (Hlw.cf1_voltage_pulse_length && Energy->power_on) { // If powered on always provide voltage
hlw_u = (Hlw.voltage_ratio * Settings->energy_voltage_calibration) / Hlw.cf1_voltage_pulse_length ; // V *10 hlw_u = (Hlw.voltage_ratio * EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)) / Hlw.cf1_voltage_pulse_length ; // V *10
Energy->voltage[0] = (float)hlw_u / 10; Energy->voltage[0] = (float)hlw_u / 10;
} else { } else {
Energy->voltage[0] = 0; Energy->voltage[0] = 0;
@ -189,7 +189,7 @@ void HlwEvery200ms(void) {
Hlw.cf1_current_pulse_length = cf1_pulse_length; Hlw.cf1_current_pulse_length = cf1_pulse_length;
if (Hlw.cf1_current_pulse_length && Energy->active_power[0]) { // No current if no power being consumed if (Hlw.cf1_current_pulse_length && Energy->active_power[0]) { // No current if no power being consumed
hlw_i = (Hlw.current_ratio * Settings->energy_current_calibration) / Hlw.cf1_current_pulse_length; // mA hlw_i = (Hlw.current_ratio * EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION)) / Hlw.cf1_current_pulse_length; // mA
Energy->current[0] = (float)hlw_i / 1000; Energy->current[0] = (float)hlw_i / 1000;
} else { } else {
Energy->current[0] = 0; Energy->current[0] = 0;
@ -217,7 +217,7 @@ void HlwEverySecond(void) {
hlw_len = 10000 * 100 / Hlw.energy_period_counter; // Add *100 to fix rounding on loads at 3.6kW (#9160) hlw_len = 10000 * 100 / Hlw.energy_period_counter; // Add *100 to fix rounding on loads at 3.6kW (#9160)
Hlw.energy_period_counter = 0; Hlw.energy_period_counter = 0;
if (hlw_len) { if (hlw_len) {
Energy->kWhtoday_delta[0] += (((Hlw.power_ratio * Settings->energy_power_calibration) / 36) * 100) / hlw_len; Energy->kWhtoday_delta[0] += (((Hlw.power_ratio * EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) / 36) * 100) / hlw_len;
EnergyUpdateToday(); EnergyUpdateToday();
} }
} }
@ -225,10 +225,10 @@ void HlwEverySecond(void) {
} }
void HlwSnsInit(void) { void HlwSnsInit(void) {
if (!Settings->energy_power_calibration || (4975 == Settings->energy_power_calibration)) { if (!EnergyGetCalibration(ENERGY_POWER_CALIBRATION) || (4975 == EnergyGetCalibration(ENERGY_POWER_CALIBRATION))) {
Settings->energy_power_calibration = HLW_PREF_PULSE; EnergySetCalibration(ENERGY_POWER_CALIBRATION, HLW_PREF_PULSE);
Settings->energy_voltage_calibration = HLW_UREF_PULSE; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, HLW_UREF_PULSE);
Settings->energy_current_calibration = HLW_IREF_PULSE; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, HLW_IREF_PULSE);
} }
if (Hlw.model_type) { if (Hlw.model_type) {

View File

@ -77,26 +77,26 @@ void CseReceived(void) {
} }
// Get chip calibration data (coefficients) and use as initial defaults // Get chip calibration data (coefficients) and use as initial defaults
if (HLW_UREF_PULSE == Settings->energy_voltage_calibration) { if (HLW_UREF_PULSE == EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)) {
long voltage_coefficient = 191200; // uSec long voltage_coefficient = 191200; // uSec
if (CSE_NOT_CALIBRATED != header) { if (CSE_NOT_CALIBRATED != header) {
voltage_coefficient = Cse.rx_buffer[2] << 16 | Cse.rx_buffer[3] << 8 | Cse.rx_buffer[4]; voltage_coefficient = Cse.rx_buffer[2] << 16 | Cse.rx_buffer[3] << 8 | Cse.rx_buffer[4];
} }
Settings->energy_voltage_calibration = voltage_coefficient / CSE_UREF; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, voltage_coefficient / CSE_UREF);
} }
if (HLW_IREF_PULSE == Settings->energy_current_calibration) { if (HLW_IREF_PULSE == EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION)) {
long current_coefficient = 16140; // uSec long current_coefficient = 16140; // uSec
if (CSE_NOT_CALIBRATED != header) { if (CSE_NOT_CALIBRATED != header) {
current_coefficient = Cse.rx_buffer[8] << 16 | Cse.rx_buffer[9] << 8 | Cse.rx_buffer[10]; current_coefficient = Cse.rx_buffer[8] << 16 | Cse.rx_buffer[9] << 8 | Cse.rx_buffer[10];
} }
Settings->energy_current_calibration = current_coefficient; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, current_coefficient);
} }
if (HLW_PREF_PULSE == Settings->energy_power_calibration) { if (HLW_PREF_PULSE == EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) {
long power_coefficient = 5364000; // uSec long power_coefficient = 5364000; // uSec
if (CSE_NOT_CALIBRATED != header) { if (CSE_NOT_CALIBRATED != header) {
power_coefficient = Cse.rx_buffer[14] << 16 | Cse.rx_buffer[15] << 8 | Cse.rx_buffer[16]; power_coefficient = Cse.rx_buffer[14] << 16 | Cse.rx_buffer[15] << 8 | Cse.rx_buffer[16];
} }
Settings->energy_power_calibration = power_coefficient / CSE_PREF; EnergySetCalibration(ENERGY_POWER_CALIBRATION, power_coefficient / CSE_PREF);
} }
uint8_t adjustement = Cse.rx_buffer[20]; uint8_t adjustement = Cse.rx_buffer[20];
@ -107,7 +107,7 @@ void CseReceived(void) {
if (Energy->power_on) { // Powered on if (Energy->power_on) { // Powered on
if (adjustement & 0x40) { // Voltage valid if (adjustement & 0x40) { // Voltage valid
Energy->voltage[0] = (float)(Settings->energy_voltage_calibration * CSE_UREF) / (float)Cse.voltage_cycle; Energy->voltage[0] = (float)(EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION) * CSE_UREF) / (float)Cse.voltage_cycle;
} }
if (adjustement & 0x10) { // Power valid if (adjustement & 0x10) { // Power valid
Cse.power_invalid = 0; Cse.power_invalid = 0;
@ -117,7 +117,7 @@ void CseReceived(void) {
if (0 == Cse.power_cycle_first) { Cse.power_cycle_first = Cse.power_cycle; } // Skip first incomplete Cse.power_cycle if (0 == Cse.power_cycle_first) { Cse.power_cycle_first = Cse.power_cycle; } // Skip first incomplete Cse.power_cycle
if (Cse.power_cycle_first != Cse.power_cycle) { if (Cse.power_cycle_first != Cse.power_cycle) {
Cse.power_cycle_first = -1; Cse.power_cycle_first = -1;
Energy->active_power[0] = (float)(Settings->energy_power_calibration * CSE_PREF) / (float)Cse.power_cycle; Energy->active_power[0] = (float)(EnergyGetCalibration(ENERGY_POWER_CALIBRATION) * CSE_PREF) / (float)Cse.power_cycle;
} else { } else {
Energy->active_power[0] = 0; Energy->active_power[0] = 0;
} }
@ -134,7 +134,7 @@ void CseReceived(void) {
if (0 == Energy->active_power[0]) { if (0 == Energy->active_power[0]) {
Energy->current[0] = 0; Energy->current[0] = 0;
} else { } else {
Energy->current[0] = (float)Settings->energy_current_calibration / (float)Cse.current_cycle; Energy->current[0] = (float)EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION) / (float)Cse.current_cycle;
} }
} }
} else { // Powered off } else { // Powered off
@ -204,7 +204,7 @@ void CseEverySecond(void) {
cf_pulses = Cse.cf_pulses - Cse.cf_pulses_last_time; cf_pulses = Cse.cf_pulses - Cse.cf_pulses_last_time;
} }
if (cf_pulses && Energy->active_power[0]) { if (cf_pulses && Energy->active_power[0]) {
uint32_t delta = (cf_pulses * Settings->energy_power_calibration) / 36; uint32_t delta = (cf_pulses * EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) / 36;
// prevent invalid load delta steps even checksum is valid (issue #5789): // prevent invalid load delta steps even checksum is valid (issue #5789):
// prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155): // prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155):
// if (delta <= (4000 * 1000 / 36)) { // max load for S31/Pow R2: 4.00kW // if (delta <= (4000 * 1000 / 36)) { // max load for S31/Pow R2: 4.00kW

View File

@ -214,15 +214,15 @@ void McpParseCalibration(void)
cal_registers.accumulation_interval = McpExtractInt(mcp_buffer, 52, 2); cal_registers.accumulation_interval = McpExtractInt(mcp_buffer, 52, 2);
if (mcp_calibrate & MCP_CALIBRATE_POWER) { if (mcp_calibrate & MCP_CALIBRATE_POWER) {
cal_registers.calibration_active_power = Settings->energy_power_calibration; cal_registers.calibration_active_power = EnergyGetCalibration(ENERGY_POWER_CALIBRATION);
if (McpCalibrationCalc(&cal_registers, 16)) { action = true; } if (McpCalibrationCalc(&cal_registers, 16)) { action = true; }
} }
if (mcp_calibrate & MCP_CALIBRATE_VOLTAGE) { if (mcp_calibrate & MCP_CALIBRATE_VOLTAGE) {
cal_registers.calibration_voltage = Settings->energy_voltage_calibration; cal_registers.calibration_voltage = EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION);
if (McpCalibrationCalc(&cal_registers, 0)) { action = true; } if (McpCalibrationCalc(&cal_registers, 0)) { action = true; }
} }
if (mcp_calibrate & MCP_CALIBRATE_CURRENT) { if (mcp_calibrate & MCP_CALIBRATE_CURRENT) {
cal_registers.calibration_current = Settings->energy_current_calibration; cal_registers.calibration_current = EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION);
if (McpCalibrationCalc(&cal_registers, 8)) { action = true; } if (McpCalibrationCalc(&cal_registers, 8)) { action = true; }
} }
mcp_timeout = 0; mcp_timeout = 0;
@ -230,9 +230,9 @@ void McpParseCalibration(void)
mcp_calibrate = 0; mcp_calibrate = 0;
Settings->energy_power_calibration = cal_registers.calibration_active_power; EnergySetCalibration(ENERGY_POWER_CALIBRATION, cal_registers.calibration_active_power);
Settings->energy_voltage_calibration = cal_registers.calibration_voltage; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, cal_registers.calibration_voltage);
Settings->energy_current_calibration = cal_registers.calibration_current; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, cal_registers.calibration_current);
mcp_system_configuration = cal_registers.system_configuration; mcp_system_configuration = cal_registers.system_configuration;
@ -386,7 +386,7 @@ void McpParseFrequency(void)
uint16_t gain_line_frequency = mcp_buffer[4] * 256 + mcp_buffer[5]; uint16_t gain_line_frequency = mcp_buffer[4] * 256 + mcp_buffer[5];
if (mcp_calibrate & MCP_CALIBRATE_FREQUENCY) { if (mcp_calibrate & MCP_CALIBRATE_FREQUENCY) {
line_frequency_ref = Settings->energy_frequency_calibration; line_frequency_ref = EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION);
if ((0xFFFF == mcp_line_frequency) || (0 == gain_line_frequency)) { // Reset values to 50Hz if ((0xFFFF == mcp_line_frequency) || (0 == gain_line_frequency)) { // Reset values to 50Hz
mcp_line_frequency = 50000; mcp_line_frequency = 50000;
@ -398,7 +398,7 @@ void McpParseFrequency(void)
McpSetFrequency(line_frequency_ref, gain_line_frequency); McpSetFrequency(line_frequency_ref, gain_line_frequency);
} }
Settings->energy_frequency_calibration = line_frequency_ref; EnergySetCalibration(ENERGY_FREQUENCY_CALIBRATION, line_frequency_ref);
mcp_calibrate = 0; mcp_calibrate = 0;
} }

View File

@ -496,12 +496,12 @@ void Ade7953GetData(void) {
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
Energy->data_valid[channel] = 0; Energy->data_valid[channel] = 0;
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10; float power_calibration = (float)EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel) / 10;
#ifdef ADE7953_ACCU_ENERGY #ifdef ADE7953_ACCU_ENERGY
power_calibration /= ADE7953_POWER_CORRECTION; power_calibration /= ADE7953_POWER_CORRECTION;
#endif // ADE7953_ACCU_ENERGY #endif // ADE7953_ACCU_ENERGY
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION); float voltage_calibration = (float)EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION, channel);
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10; float current_calibration = (float)EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION, channel) * 10;
Energy->frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1); Energy->frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration; divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
@ -705,14 +705,12 @@ void Ade7953DrvInit(void) {
#ifdef USE_ESP32_SPI #ifdef USE_ESP32_SPI
} }
#endif // USE_ESP32_SPI #endif // USE_ESP32_SPI
if (EnergyGetCalibration(ENERGY_POWER_CALIBRATION) == HLW_PREF_PULSE) {
if (HLW_PREF_PULSE == Settings->energy_power_calibration) { for (uint32_t i = 0; i < 4; i++) {
Settings->energy_power_calibration = ADE7953_PREF; EnergySetCalibration(ENERGY_POWER_CALIBRATION, ADE7953_PREF, i);
Settings->energy_voltage_calibration = ADE7953_UREF; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, ADE7953_UREF, i);
Settings->energy_current_calibration = ADE7953_IREF; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, ADE7953_IREF, i);
Settings->energy_power_calibration2 = ADE7953_PREF; }
Settings->energy_voltage_calibration2 = ADE7953_UREF;
Settings->energy_current_calibration2 = ADE7953_IREF;
} }
Ade7953Defaults(); Ade7953Defaults();

View File

@ -188,13 +188,13 @@ bool Bl09XXDecode42(void) {
void Bl09XXUpdateEnergy() { void Bl09XXUpdateEnergy() {
if (Energy->power_on) { // Powered on if (Energy->power_on) { // Powered on
Energy->voltage[0] = (float)Bl09XX.voltage / Settings->energy_voltage_calibration; Energy->voltage[0] = (float)Bl09XX.voltage / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION);
#ifdef DEBUG_BL09XX #ifdef DEBUG_BL09XX
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy->voltage[0], &Bl09XX.temperature); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy->voltage[0], &Bl09XX.temperature);
#endif #endif
for (uint32_t chan = 0; chan < Energy->phase_count; chan++) { for (uint32_t chan = 0; chan < Energy->phase_count; chan++) {
uint32_t power_calibration = EnergyGetCalibration(chan, ENERGY_POWER_CALIBRATION); uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, chan);
uint32_t current_calibration = EnergyGetCalibration(chan, ENERGY_CURRENT_CALIBRATION); uint32_t current_calibration = EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION, chan);
if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
Energy->active_power[chan] = (float)Bl09XX.power[chan] / power_calibration; Energy->active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
Energy->current[chan] = (float)Bl09XX.current[chan] / current_calibration; Energy->current[chan] = (float)Bl09XX.current[chan] / current_calibration;
@ -287,16 +287,16 @@ void Bl09XXInit(void) {
if (Bl09XXSerial->hardwareSerial()) { if (Bl09XXSerial->hardwareSerial()) {
ClaimSerial(); ClaimSerial();
} }
if (HLW_UREF_PULSE == Settings->energy_voltage_calibration) { if (HLW_UREF_PULSE == EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION)) {
Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model]; for (uint32_t i = 0; i < 2; i++) {
Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model]; EnergySetCalibration(ENERGY_POWER_CALIBRATION, bl09xx_pref[Bl09XX.model], i);
Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model]; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, bl09xx_uref[Bl09XX.model], i);
Settings->energy_voltage_calibration2 = bl09xx_uref[Bl09XX.model]; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, bl09xx_iref[Bl09XX.model], i);
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))) { if ((BL0940_MODEL == Bl09XX.model) && (EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION) < (BL0940_IREF / 20))) {
Settings->energy_current_calibration *= 100; uint32_t current_calibration = EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION) * 100;
EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, current_calibration);
} }
if (BL0942_MODEL != Bl09XX.model) { if (BL0942_MODEL != Bl09XX.model) {

View File

@ -221,17 +221,17 @@ bool Cse7761ChipInit(void) {
CSE7761Data.coefficient[PowerPAC] = CSE7761_PREF; CSE7761Data.coefficient[PowerPAC] = CSE7761_PREF;
// CSE7761Data.coefficient[PowerPBC] = 0xADD7; // CSE7761Data.coefficient[PowerPBC] = 0xADD7;
} }
if (HLW_PREF_PULSE == Settings->energy_power_calibration) { if (HLW_PREF_PULSE == EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) {
Settings->energy_frequency_calibration = CSE7761_FREF; for (uint32_t i = 0; i < 2; i++) {
Settings->energy_voltage_calibration = Cse7761Ref(RmsUC); EnergySetCalibration(ENERGY_POWER_CALIBRATION, Cse7761Ref(PowerPAC), i);
Settings->energy_current_calibration = Cse7761Ref(RmsIAC); EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, Cse7761Ref(RmsUC), i);
Settings->energy_power_calibration = Cse7761Ref(PowerPAC); EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, Cse7761Ref(RmsIAC), i);
Settings->energy_current_calibration2 = Settings->energy_current_calibration; EnergySetCalibration(ENERGY_FREQUENCY_CALIBRATION, CSE7761_FREF, i);
Settings->energy_power_calibration2 = Settings->energy_power_calibration; }
} }
// Just to fix intermediate users // Just to fix intermediate users
if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) { if (EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) < CSE7761_FREF / 2) {
Settings->energy_frequency_calibration = CSE7761_FREF; EnergySetCalibration(ENERGY_FREQUENCY_CALIBRATION, CSE7761_FREF);
} }
Cse7761Write(CSE7761_SPECIAL_COMMAND, CSE7761_CMD_ENABLE_WRITE); Cse7761Write(CSE7761_SPECIAL_COMMAND, CSE7761_CMD_ENABLE_WRITE);
@ -461,21 +461,21 @@ void Cse7761GetData(void) {
if (Energy->power_on) { // Powered on if (Energy->power_on) { // Powered on
// Voltage = RmsU * RmsUC * 10 / 0x400000 // 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)(((uint64_t)CSE7761Data.voltage_rms * CSE7761Data.coefficient[RmsUC] * 10) >> 22) / 1000; // V
Energy->voltage[0] = ((float)CSE7761Data.voltage_rms / Settings->energy_voltage_calibration); // 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)Settings->energy_frequency_calibration / 8 / CSE7761Data.frequency) : 0; // Hz Energy->frequency[0] = (CSE7761Data.frequency) ? ((float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION) / 8 / CSE7761Data.frequency) : 0; // Hz
#endif #endif
for (uint32_t channel = 0; channel < 2; channel++) { for (uint32_t channel = 0; channel < 2; channel++) {
Energy->data_valid[channel] = 0; Energy->data_valid[channel] = 0;
uint32_t power_calibration = EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION); uint32_t power_calibration = EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel);
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000 // 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)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
Energy->active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W Energy->active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
if (0 == Energy->active_power[channel]) { if (0 == Energy->active_power[channel]) {
Energy->current[channel] = 0; Energy->current[channel] = 0;
} else { } else {
uint32_t current_calibration = EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION); uint32_t current_calibration = EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION, channel);
// Current = RmsIA * RmsIAC / 0x800000 // 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)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
Energy->current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A Energy->current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A

View File

@ -162,16 +162,16 @@ RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
switch(rx_buffer[1]) { switch(rx_buffer[1]) {
case BL6523_REG_AMPS : case BL6523_REG_AMPS :
Energy->current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_current_calibration; // 1.260 A Energy->current[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION); // 1.260 A
break; break;
case BL6523_REG_VOLTS : case BL6523_REG_VOLTS :
Energy->voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_voltage_calibration; // 230.2 V Energy->voltage[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION); // 230.2 V
break; break;
case BL6523_REG_FREQ : 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 Energy->frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION); // 50.0 Hz
break; break;
case BL6523_REG_WATTS : 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 Energy->active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / EnergyGetCalibration(ENERGY_POWER_CALIBRATION); // -196.3 W
break; break;
case BL6523_REG_POWF : case BL6523_REG_POWF :
/* Power factor =(sign bit)*((PF[22]×2^1PF[21]×2^2。。。) /* Power factor =(sign bit)*((PF[22]×2^1PF[21]×2^2。。。)
@ -188,7 +188,7 @@ switch(rx_buffer[1]) {
Energy->power_factor[SINGLE_PHASE] = powf; Energy->power_factor[SINGLE_PHASE] = powf;
break; break;
case BL6523_REG_WATTHR : 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() Energy->import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( EnergyGetCalibration(ENERGY_POWER_CALIBRATION) - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal()
break; break;
default : default :
break; break;
@ -310,13 +310,12 @@ void Bl6523DrvInit(void)
if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) { if (PinUsed(GPIO_BL6523_RX) && PinUsed(GPIO_BL6523_TX)) {
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Success" )); AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Success" ));
TasmotaGlobal.energy_driver = XNRG_22; TasmotaGlobal.energy_driver = XNRG_22;
if (HLW_PREF_PULSE == Settings->energy_power_calibration) { if (HLW_PREF_PULSE == EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) {
Settings->energy_frequency_calibration = BL6523_FREF; EnergySetCalibration(ENERGY_POWER_CALIBRATION, BL6523_PREF);
Settings->energy_voltage_calibration = BL6523_UREF; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, BL6523_UREF);
Settings->energy_current_calibration = BL6523_IREF; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, BL6523_IREF);
Settings->energy_power_calibration = BL6523_PREF; EnergySetCalibration(ENERGY_FREQUENCY_CALIBRATION, BL6523_FREF);
} }
} }
else else
{ {

View File

@ -56,10 +56,10 @@ void NrgDummyEverySecond(void) {
if (Energy->power_on) { // Powered on if (Energy->power_on) { // Powered on
for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { for (uint32_t channel = 0; channel < Energy->phase_count; channel++) {
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 100; float power_calibration = (float)EnergyGetCalibration(ENERGY_POWER_CALIBRATION, channel) / 100;
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION) / 100; float voltage_calibration = (float)EnergyGetCalibration(ENERGY_VOLTAGE_CALIBRATION, channel) / 100;
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) / 100000; float current_calibration = (float)EnergyGetCalibration(ENERGY_CURRENT_CALIBRATION, channel) / 100000;
float frequency_calibration = (float)EnergyGetCalibration(channel, ENERGY_FREQUENCY_CALIBRATION) / 100; float frequency_calibration = (float)EnergyGetCalibration(ENERGY_FREQUENCY_CALIBRATION, channel) / 100;
Energy->voltage[channel] = voltage_calibration; // V Energy->voltage[channel] = voltage_calibration; // V
Energy->frequency[channel] = frequency_calibration; // Hz Energy->frequency[channel] = frequency_calibration; // Hz
@ -135,17 +135,17 @@ bool NrgDummyCommand(void) {
void NrgDummyDrvInit(void) { void NrgDummyDrvInit(void) {
if (TasmotaGlobal.gpio_optiona.dummy_energy && TasmotaGlobal.devices_present) { if (TasmotaGlobal.gpio_optiona.dummy_energy && TasmotaGlobal.devices_present) {
if (HLW_PREF_PULSE == Settings->energy_power_calibration) { Energy->phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
Settings->energy_frequency_calibration = NRG_DUMMY_FREF;
Settings->energy_voltage_calibration = NRG_DUMMY_UREF; if (HLW_PREF_PULSE == EnergyGetCalibration(ENERGY_POWER_CALIBRATION)) {
Settings->energy_current_calibration = NRG_DUMMY_IREF; for (uint32_t i = 0; i < Energy->phase_count; i++) {
Settings->energy_power_calibration = NRG_DUMMY_PREF; EnergySetCalibration(ENERGY_POWER_CALIBRATION, NRG_DUMMY_PREF, i);
Settings->energy_voltage_calibration2 = NRG_DUMMY_UREF; EnergySetCalibration(ENERGY_VOLTAGE_CALIBRATION, NRG_DUMMY_UREF, i);
Settings->energy_current_calibration2 = NRG_DUMMY_IREF; EnergySetCalibration(ENERGY_CURRENT_CALIBRATION, NRG_DUMMY_IREF, i);
Settings->energy_power_calibration2 = NRG_DUMMY_PREF; EnergySetCalibration(ENERGY_FREQUENCY_CALIBRATION, NRG_DUMMY_FREF, i);
}
} }
Energy->phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
Energy->voltage_common = NRG_DUMMY_U_COMMON; // Phase voltage = false, Common voltage = true Energy->voltage_common = NRG_DUMMY_U_COMMON; // Phase voltage = false, Common voltage = true
Energy->frequency_common = NRG_DUMMY_F_COMMON; // Phase frequency = false, Common frequency = true Energy->frequency_common = NRG_DUMMY_F_COMMON; // Phase frequency = false, Common frequency = true
Energy->type_dc = NRG_DUMMY_DC; // AC = false, DC = true; Energy->type_dc = NRG_DUMMY_DC; // AC = false, DC = true;