Add frequency to ADE7953 energy monitor

Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778)
This commit is contained in:
Theo Arends 2019-10-30 16:06:53 +01:00
parent 6fc9dccfe8
commit 8ca843f9ab
3 changed files with 31 additions and 22 deletions

View File

@ -3,6 +3,7 @@
* Remove references to versions before 6.x * Remove references to versions before 6.x
* Change default GUI to dark theme * 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 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 * 6.7.1.1 20191026
* Change ArduinoSlave to TasmotaSlave (Experimental) * Change ArduinoSlave to TasmotaSlave (Experimental)

View File

@ -95,7 +95,7 @@ struct ENERGY {
uint8_t data_valid[3] = { 0, 0, 0 }; uint8_t data_valid[3] = { 0, 0, 0 };
uint8_t phase_count = 1; // Number of phases active 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 voltage_available = true; // Enable if voltage is measured
bool current_available = true; // Enable if current is measured bool current_available = true; // Enable if current is measured
@ -1014,7 +1014,7 @@ void EnergyShow(bool json)
} }
if (!isnan(Energy.frequency[0])) { if (!isnan(Energy.frequency[0])) {
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"), 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) { if (Energy.voltage_available) {
@ -1084,7 +1084,7 @@ void EnergyShow(bool json)
} }
if (!isnan(Energy.frequency[0])) { if (!isnan(Energy.frequency[0])) {
WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"), 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]); WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr[0]);

View File

@ -36,20 +36,22 @@
#define ADE7953_ADDR 0x38 #define ADE7953_ADDR 0x38
const uint8_t Ade7953Registers[] { const uint16_t Ade7953Registers[] {
0x1B, // RMS current channel B (Relay 1) 0x31B, // RMS current channel B (Relay 1)
0x13, // Active power channel B 0x313, // Active power channel B
0x11, // Apparent power channel B 0x311, // Apparent power channel B
0x15, // Reactive power channel B 0x315, // Reactive power channel B
0x1A, // RMS current channel A (Relay 2) 0x31A, // RMS current channel A (Relay 2)
0x12, // Active power channel A 0x312, // Active power channel A
0x10, // Apparent power channel A 0x310, // Apparent power channel A
0x14, // Reactive power channel A 0x314, // Reactive power channel A
0x1C // RMS voltage (Both relays) 0x31C, // RMS voltage (Both relays)
0x10E // 16-bit unsigned period register
}; };
struct Ade7953 { struct Ade7953 {
uint32_t voltage_rms = 0; uint32_t voltage_rms = 0;
uint32_t period = 0;
uint32_t current_rms[2] = { 0, 0 }; uint32_t current_rms[2] = { 0, 0 };
uint32_t active_power[2] = { 0, 0 }; uint32_t active_power[2] = { 0, 0 };
uint8_t init_step = 0; uint8_t init_step = 0;
@ -118,17 +120,20 @@ void Ade7953Init(void)
void Ade7953GetData(void) void Ade7953GetData(void)
{ {
int32_t reg[2][4]; int32_t reg[2][4];
for (uint32_t i = 0; i < sizeof(Ade7953Registers); i++) { for (uint32_t i = 0; i < sizeof(Ade7953Registers)/sizeof(uint16_t); i++) {
int32_t value = Ade7953Read(0x300 + Ade7953Registers[i]); int32_t value = Ade7953Read(Ade7953Registers[i]);
if (8 == i) { if (8 == i) {
Ade7953.voltage_rms = value; // RMS voltage (Both relays) Ade7953.voltage_rms = value; // RMS voltage (Both relays)
} else if (9 == i) {
Ade7953.period = value; // period
} else { } else {
reg[i >> 2][i &3] = value; reg[i >> 2][i &3] = value;
} }
} }
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: %d, [%d, %d, %d, %d], [%d, %d, %d, %d]"), AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: %d, %d, [%d, %d, %d, %d], [%d, %d, %d, %d]"),
Ade7953.voltage_rms, reg[0][0], reg[0][1], reg[0][2], reg[0][3], Ade7953.voltage_rms, Ade7953.period,
reg[1][0], reg[1][1], reg[1][2], reg[1][3]); 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 apparent_power[2] = { 0, 0 };
uint32_t reactive_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 current_rms_sum = Ade7953.current_rms[0] + Ade7953.current_rms[1];
uint32_t active_power_sum = Ade7953.active_power[0] + Ade7953.active_power[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"), AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ADE: U %d, C %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); 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 if (Energy.power_on) { // Powered on
Energy.voltage[0] = (float)Ade7953.voltage_rms / Settings.energy_voltage_calibration; 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++) { for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0; Energy.data_valid[channel] = 0;
@ -202,7 +210,7 @@ void Ade7953DrvInit(void)
Ade7953.init_step = 2; Ade7953.init_step = 2;
Energy.phase_count = 2; // Handle two channels as two phases 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; energy_flg = XNRG_07;
} }
@ -278,4 +286,4 @@ bool Xnrg07(uint8_t function)
#endif // USE_ADE7953 #endif // USE_ADE7953
#endif // USE_ENERGY_SENSOR #endif // USE_ENERGY_SENSOR
#endif // USE_I2C #endif // USE_I2C