From 8ca843f9ab3668eee6470d96e8f516bc006a09fb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 30 Oct 2019 16:06:53 +0100 Subject: [PATCH] Add frequency to ADE7953 energy monitor Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778) --- tasmota/_changelog.ino | 1 + tasmota/xdrv_03_energy.ino | 6 ++--- tasmota/xnrg_07_ade7953.ino | 46 ++++++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/tasmota/_changelog.ino b/tasmota/_changelog.ino index dce497fdf..a18d6d4bf 100644 --- a/tasmota/_changelog.ino +++ b/tasmota/_changelog.ino @@ -3,6 +3,7 @@ * Remove references to versions before 6.x * Change default GUI to dark theme * Add command SetOption73 0/1 to re-enable HTTP Cross-Origin Resource Sharing (CORS) now default disabled (#6767) + * Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778) * * 6.7.1.1 20191026 * Change ArduinoSlave to TasmotaSlave (Experimental) diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 13bb8948a..e68b8215e 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -95,7 +95,7 @@ struct ENERGY { uint8_t data_valid[3] = { 0, 0, 0 }; uint8_t phase_count = 1; // Number of phases active - bool voltage_common = false; // Use single voltage + bool voltage_common = false; // Use single voltage and frequency bool voltage_available = true; // Enable if voltage is measured bool current_available = true; // Enable if current is measured @@ -1014,7 +1014,7 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"), - EnergyFormat(value_chr, frequency_chr[0], json)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); } } if (Energy.voltage_available) { @@ -1084,7 +1084,7 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"), - EnergyFormat(value_chr, frequency_chr[0], json)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); } } WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr[0]); diff --git a/tasmota/xnrg_07_ade7953.ino b/tasmota/xnrg_07_ade7953.ino index 5f789e3c8..fd11da99e 100644 --- a/tasmota/xnrg_07_ade7953.ino +++ b/tasmota/xnrg_07_ade7953.ino @@ -36,20 +36,22 @@ #define ADE7953_ADDR 0x38 -const uint8_t Ade7953Registers[] { - 0x1B, // RMS current channel B (Relay 1) - 0x13, // Active power channel B - 0x11, // Apparent power channel B - 0x15, // Reactive power channel B - 0x1A, // RMS current channel A (Relay 2) - 0x12, // Active power channel A - 0x10, // Apparent power channel A - 0x14, // Reactive power channel A - 0x1C // RMS voltage (Both relays) +const uint16_t Ade7953Registers[] { + 0x31B, // RMS current channel B (Relay 1) + 0x313, // Active power channel B + 0x311, // Apparent power channel B + 0x315, // Reactive power channel B + 0x31A, // RMS current channel A (Relay 2) + 0x312, // Active power channel A + 0x310, // Apparent power channel A + 0x314, // Reactive power channel A + 0x31C, // RMS voltage (Both relays) + 0x10E // 16-bit unsigned period register }; struct Ade7953 { uint32_t voltage_rms = 0; + uint32_t period = 0; uint32_t current_rms[2] = { 0, 0 }; uint32_t active_power[2] = { 0, 0 }; uint8_t init_step = 0; @@ -118,17 +120,20 @@ void Ade7953Init(void) void Ade7953GetData(void) { int32_t reg[2][4]; - for (uint32_t i = 0; i < sizeof(Ade7953Registers); i++) { - int32_t value = Ade7953Read(0x300 + Ade7953Registers[i]); + for (uint32_t i = 0; i < sizeof(Ade7953Registers)/sizeof(uint16_t); i++) { + int32_t value = Ade7953Read(Ade7953Registers[i]); if (8 == i) { Ade7953.voltage_rms = value; // RMS voltage (Both relays) + } else if (9 == i) { + Ade7953.period = value; // period } else { reg[i >> 2][i &3] = value; } } - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: %d, [%d, %d, %d, %d], [%d, %d, %d, %d]"), - Ade7953.voltage_rms, reg[0][0], reg[0][1], reg[0][2], reg[0][3], - reg[1][0], reg[1][1], reg[1][2], reg[1][3]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: %d, %d, [%d, %d, %d, %d], [%d, %d, %d, %d]"), + Ade7953.voltage_rms, Ade7953.period, + reg[0][0], reg[0][1], reg[0][2], reg[0][3], + reg[1][0], reg[1][1], reg[1][2], reg[1][3]); uint32_t apparent_power[2] = { 0, 0 }; uint32_t reactive_power[2] = { 0, 0 }; @@ -148,11 +153,14 @@ void Ade7953GetData(void) uint32_t current_rms_sum = Ade7953.current_rms[0] + Ade7953.current_rms[1]; uint32_t active_power_sum = Ade7953.active_power[0] + Ade7953.active_power[1]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ADE: U %d, I %d + %d = %d, P %d + %d = %d"), - Ade7953.voltage_rms, Ade7953.current_rms[0], Ade7953.current_rms[1], current_rms_sum, Ade7953.active_power[0], Ade7953.active_power[1], active_power_sum); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ADE: U %d, C %d, I %d + %d = %d, P %d + %d = %d"), + Ade7953.voltage_rms, Ade7953.period, + Ade7953.current_rms[0], Ade7953.current_rms[1], current_rms_sum, + Ade7953.active_power[0], Ade7953.active_power[1], active_power_sum); if (Energy.power_on) { // Powered on Energy.voltage[0] = (float)Ade7953.voltage_rms / Settings.energy_voltage_calibration; + Energy.frequency[0] = 223750.0f / ( (float)Ade7953.period + 1); for (uint32_t channel = 0; channel < 2; channel++) { Energy.data_valid[channel] = 0; @@ -202,7 +210,7 @@ void Ade7953DrvInit(void) Ade7953.init_step = 2; Energy.phase_count = 2; // Handle two channels as two phases - Energy.voltage_common = true; // Use common voltage + Energy.voltage_common = true; // Use common voltage and frequency energy_flg = XNRG_07; } @@ -278,4 +286,4 @@ bool Xnrg07(uint8_t function) #endif // USE_ADE7953 #endif // USE_ENERGY_SENSOR -#endif // USE_I2C +#endif // USE_I2C \ No newline at end of file