mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +00:00
Prep EnergyConfig
This commit is contained in:
parent
3400e7530e
commit
a927ddfd9f
@ -833,7 +833,9 @@ void CmndModuleAddress(void) {
|
||||
void CmndEnergyConfig(void) {
|
||||
Energy.command_code = CMND_ENERGYCONFIG;
|
||||
if (XnrgCall(FUNC_COMMAND)) {
|
||||
ResponseCmndDone();
|
||||
if (!ResponseLength()) {
|
||||
ResponseCmndDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
/*********************************************************************************************\
|
||||
* ADE7880 - Energy used in Shelly 3EM
|
||||
*
|
||||
* {"NAME":"Shelly 3EM","GPIO":[1,1,544,1,32,8065,0,0,640,8064,608,224,8096,0],"FLAG":0,"BASE":18}
|
||||
* {"NAME":"Shelly 3EM","GPIO":[1,1,288,1,32,8065,0,0,640,8064,608,224,8096,0],"FLAG":0,"BASE":18}
|
||||
*
|
||||
* Based on datasheet from https://www.analog.com/en/products/ade7880.html
|
||||
*
|
||||
@ -24,8 +24,6 @@
|
||||
|
||||
#define ADE7880_ADDR 0x38
|
||||
|
||||
//#define ADE7880_COMPMODE_FREQ 0x4000 // Connected to networks with fundamental frequencies between 55 Hz and 66 Hz. Default 45 Hz to 55 Hz
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
//#define ADE7880_DEBUG
|
||||
@ -76,6 +74,7 @@ Derive these parameters from the original Shelly 3EM 4M firmware dump. Look for
|
||||
}
|
||||
}
|
||||
*/
|
||||
#define ADE7880_FREQ_INIT 0 // Connected to networks with fundamental frequencies between 55 Hz and 66 Hz (1). Default 45 Hz to 55 Hz (0).
|
||||
#define ADE7880_AIGAIN_INIT 3166385 // rms, current_a
|
||||
#define ADE7880_BIGAIN_INIT 3125691 // rms, current_b
|
||||
#define ADE7880_CIGAIN_INIT 3131983 // rms, current_c
|
||||
@ -90,38 +89,6 @@ Derive these parameters from the original Shelly 3EM 4M firmware dump. Look for
|
||||
#define ADE7880_BPGAIN_INIT -1347328 // powers, totactive, b
|
||||
#define ADE7880_CPGAIN_INIT -1351979 // powers, totactive, c
|
||||
|
||||
/*
|
||||
// Original defines from logic analyzer
|
||||
#define ADE7880_AIGAIN_INIT 0x002FFED1 // = 3145425
|
||||
#define ADE7880_BIGAIN_INIT 0x00309661 // = 3184225
|
||||
#define ADE7880_CIGAIN_INIT 0x0030DBFD // = 3202045
|
||||
#define ADE7880_NIGAIN_INIT 0x04D906AC // = 81331884 (14223020)
|
||||
#define ADE7880_AVGAIN_INIT 0xFFF43977 // = -771720
|
||||
#define ADE7880_BVGAIN_INIT 0xFFF4DD00 // = -729855
|
||||
#define ADE7880_CVGAIN_INIT 0xFFF4A306 // = -744697
|
||||
#define ADE7880_APHCAL_INIT 0xD895 // = 55445 (149)
|
||||
#define ADE7880_BPHCAL_INIT 0xD8A9 // = 55456 (169)
|
||||
#define ADE7880_CPHCAL_INIT 0xD89D // = 55453 (157)
|
||||
#define ADE7880_APGAIN_INIT 0xFF14B7E3 // = -15419420
|
||||
#define ADE7880_BPGAIN_INIT 0xFF14A7B1 // = -15423566
|
||||
#define ADE7880_CPGAIN_INIT 0xFF14999C // = -15427171
|
||||
*/
|
||||
/*
|
||||
#define ADE7880_AIGAIN_INIT 3145425
|
||||
#define ADE7880_BIGAIN_INIT 3184225
|
||||
#define ADE7880_CIGAIN_INIT 3202045
|
||||
#define ADE7880_NIGAIN_INIT 14223020
|
||||
#define ADE7880_AVGAIN_INIT -771720
|
||||
#define ADE7880_BVGAIN_INIT -729855
|
||||
#define ADE7880_CVGAIN_INIT -744697
|
||||
#define ADE7880_APHCAL_INIT 149
|
||||
#define ADE7880_BPHCAL_INIT 169
|
||||
#define ADE7880_CPHCAL_INIT 157
|
||||
#define ADE7880_APGAIN_INIT -15419420
|
||||
#define ADE7880_BPGAIN_INIT -15423566
|
||||
#define ADE7880_CPGAIN_INIT -15427171
|
||||
*/
|
||||
|
||||
enum Ade7880DspRegisters {
|
||||
ADE7880_AIGAIN = 0x4380, // 0x4380 R/W 24 32 ZPSE S 0x000000 Phase A current gain adjust.
|
||||
ADE7880_AVGAIN, // 0x4381 R/W 24 32 ZPSE S 0x000000 Phase A voltage gain adjust.
|
||||
@ -317,16 +284,14 @@ enum Ade7880PowerQualityRegisters {
|
||||
};
|
||||
|
||||
struct Ade7880 {
|
||||
int32_t nirms;
|
||||
int32_t isum;
|
||||
int32_t active_energy[3];
|
||||
int32_t apparent_energy[3];
|
||||
uint16_t angle[3];
|
||||
|
||||
uint8_t init_state;
|
||||
int32_t calib_current[4];
|
||||
int32_t calib_voltage[3];
|
||||
int32_t calib_acpower[3];
|
||||
uint16_t calib_angle[3];
|
||||
bool calib_frequency;
|
||||
bool irq0_state;
|
||||
uint8_t cycle_count;
|
||||
uint8_t irq0_state;
|
||||
uint8_t irq1_state;
|
||||
} Ade7880;
|
||||
|
||||
/*********************************************************************************************/
|
||||
@ -430,6 +395,7 @@ bool Ade7880Init(void) {
|
||||
#ifdef ADE7880_PROFILING
|
||||
uint32_t start = millis();
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
uint32_t status1 = Ade7880ReadVerify(ADE7880_STATUS1); // 0x01A08000
|
||||
if (bitRead(status1, 15)) { // RSTDONE
|
||||
// Power on or Reset
|
||||
@ -440,43 +406,25 @@ bool Ade7880Init(void) {
|
||||
return false;
|
||||
}
|
||||
uint8_t version = Ade7880ReadVerify(ADE7880_Version); // 0x01
|
||||
|
||||
delayMicroseconds(240); // Grab parameters from flash/filesystem
|
||||
|
||||
Ade7880WriteVerify(ADE7880_Gain, 0x0000); // Gain register set to 1 for current, and voltage
|
||||
Ade7880WriteVerify(ADE7880_APGAIN, ADE7880_APGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_BPGAIN, ADE7880_BPGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_CPGAIN, ADE7880_CPGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_AVGAIN, ADE7880_AVGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_BVGAIN, ADE7880_BVGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_CVGAIN, ADE7880_CVGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_AIGAIN, ADE7880_AIGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_BIGAIN, ADE7880_BIGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_CIGAIN, ADE7880_CIGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_NIGAIN, ADE7880_NIGAIN_INIT);
|
||||
Ade7880WriteVerify(ADE7880_APHCAL, ADE7880_APHCAL_INIT);
|
||||
Ade7880WriteVerify(ADE7880_BPHCAL, ADE7880_BPHCAL_INIT);
|
||||
Ade7880WriteVerify(ADE7880_CPHCAL, ADE7880_CPHCAL_INIT);
|
||||
#ifdef ADE7880_COMPMODE_FREQ
|
||||
Ade7880WriteVerify(ADE7880_COMPMODE, 0x01FF | ADE7880_COMPMODE_FREQ); // Connected to networks with fundamental frequencies between 55 Hz and 66 Hz. Default is 45 Hz and 55 Hz.
|
||||
#endif
|
||||
if (Ade7880.calib_frequency) {
|
||||
Ade7880WriteVerify(ADE7880_COMPMODE, 0x41FF); // Connected to networks with fundamental frequencies between 55 Hz and 66 Hz. Default is 45 Hz and 55 Hz.
|
||||
}
|
||||
for (uint32_t phase = 0; phase < 3; phase++) {
|
||||
Ade7880WriteVerify(ADE7880_AVGAIN + (phase * 2), Ade7880.calib_voltage[phase]);
|
||||
Ade7880WriteVerify(ADE7880_AIGAIN + (phase * 2), Ade7880.calib_current[phase]);
|
||||
Ade7880WriteVerify(ADE7880_APGAIN + (phase * 2), Ade7880.calib_acpower[phase]);
|
||||
Ade7880WriteVerify(ADE7880_APHCAL + phase, Ade7880.calib_angle[phase]);
|
||||
}
|
||||
Ade7880WriteVerify(ADE7880_NIGAIN, Ade7880.calib_current[3]);
|
||||
bool error = false;
|
||||
if (Ade7880ReadVerify(ADE7880_AVGAIN) != (ADE7880_AVGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_BVGAIN) != (ADE7880_BVGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_CVGAIN) != (ADE7880_CVGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_AIGAIN) != ADE7880_AIGAIN_INIT) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_BIGAIN) != ADE7880_BIGAIN_INIT) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_CIGAIN) != ADE7880_CIGAIN_INIT) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_NIGAIN) != ADE7880_NIGAIN_INIT) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_APGAIN) != (ADE7880_APGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_BPGAIN) != (ADE7880_BPGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_CPGAIN) != (ADE7880_CPGAIN_INIT & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_APHCAL) != (ADE7880_APHCAL_INIT & 0x00FF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_BPHCAL) != (ADE7880_BPHCAL_INIT & 0x00FF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_CPHCAL) != (ADE7880_CPHCAL_INIT & 0x00FF)) { error = true; }
|
||||
#ifdef ADE7880_COMPMODE_FREQ
|
||||
else if (Ade7880ReadVerify(ADE7880_COMPMODE) != (0x01FF | ADE7880_COMPMODE_FREQ)) { error = true; }
|
||||
#endif
|
||||
for (uint32_t phase = 0; phase < 3; phase++) {
|
||||
if (Ade7880ReadVerify(ADE7880_AVGAIN + (phase * 2)) != (Ade7880.calib_voltage[phase] & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_AIGAIN + (phase * 2)) != Ade7880.calib_current[phase]) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_APGAIN + (phase * 2)) != (Ade7880.calib_acpower[phase] & 0x0FFFFFFF)) { error = true; }
|
||||
else if (Ade7880ReadVerify(ADE7880_APHCAL + phase) != (Ade7880.calib_angle[phase] & 0x00FF)) { error = true; }
|
||||
}
|
||||
if (Ade7880ReadVerify(ADE7880_NIGAIN) != Ade7880.calib_current[3]) { error = true; }
|
||||
if (error) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Error initializing parameters"));
|
||||
return false;
|
||||
@ -487,12 +435,10 @@ bool Ade7880Init(void) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Error setting LCYCMODE register"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Ade7880WriteVerify(ADE7880_LINECYC, 0x0064)) { // = 100
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Error setting LINECYC register"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Ade7880WriteVerify(ADE7880_MASK0, 0x00000020); // IRQ0 at end of an integration over an integer number of half line cycles set in the LINECYC register.
|
||||
if (!Ade7880VerifyWrite(ADE7880_MASK0)) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Error setting MASK0 register"));
|
||||
@ -501,31 +447,47 @@ bool Ade7880Init(void) {
|
||||
Ade7880Write(ADE7880_MASK0, 0x00000020);
|
||||
Ade7880Write(ADE7880_MASK0, 0x00000020);
|
||||
Ade7880Write(ADE7880_MASK0, 0x00000020);
|
||||
|
||||
Ade7880Write(ADE7880_DSPWP_SEL, 0xAD); // Select DSP write protection
|
||||
Ade7880Write(ADE7880_DSPWP_SET, 0x80); // Write protect DSP area
|
||||
|
||||
Ade7880WriteVerify(ADE7880_Run, 0x0201); // Start DSP
|
||||
|
||||
#ifdef ADE7880_PROFILING
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Init done in %d ms"), millis() - start);
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ade7880Service1(void) {
|
||||
// Init sequence
|
||||
SkipSleep(false);
|
||||
bool result = Ade7880Init();
|
||||
Ade7880.irq1_state = 0;
|
||||
return result;
|
||||
}
|
||||
bool Ade7880SetCalibrate(void) {
|
||||
|
||||
void IRAM_ATTR Ade7880Isr1(void) {
|
||||
// Init sequence
|
||||
if (!Ade7880.irq1_state) {
|
||||
Ade7880.irq1_state = 1;
|
||||
SkipSleep(true);
|
||||
#ifdef ADE7880_PROFILING
|
||||
uint32_t start = millis();
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
int reset = Pin(GPIO_RESET);
|
||||
if (-1 == reset) { reset = 16; } // Reset pin ADE7880 in Shelly 3EM
|
||||
pinMode(reset, OUTPUT);
|
||||
digitalWrite(reset, 0);
|
||||
delay(1);
|
||||
digitalWrite(reset, 1);
|
||||
pinMode(reset, INPUT);
|
||||
|
||||
Ade7880.cycle_count = 2; // Skip first two cycles
|
||||
|
||||
uint32_t timeout = millis() + 40; // Should be reset within 10 ms
|
||||
while (!TimeReached(timeout)) { // Wait up to 100 ms
|
||||
if (!digitalRead(Pin(GPIO_ADE7880_IRQ, 1))) {
|
||||
|
||||
#ifdef ADE7880_PROFILING
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Reset in %d ms"), millis() - start);
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
if (Ade7880Init()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
@ -535,6 +497,7 @@ void Ade7880Cycle(void) {
|
||||
#ifdef ADE7880_PROFILING
|
||||
uint32_t start = millis();
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
uint32_t status0 = Ade7880ReadVerify(ADE7880_STATUS0); // 0x000FEFE0
|
||||
if (!bitRead(status0, 5)) { // LENERGY
|
||||
return;
|
||||
@ -542,42 +505,20 @@ void Ade7880Cycle(void) {
|
||||
Ade7880WriteVerify(ADE7880_STATUS0, 0x00000020); // Acknowledge LENERGY - Reset IRQ0 line
|
||||
status0 = Ade7880ReadVerify(ADE7880_STATUS0); // 0x000FEFC0
|
||||
}
|
||||
if (Ade7880.cycle_count < 2) { // Allow calibration stabilization
|
||||
Ade7880.cycle_count++;
|
||||
return; // Skip first two cycles
|
||||
if (Ade7880.cycle_count) { // Allow calibration stabilization
|
||||
Ade7880.cycle_count--;
|
||||
return; // Skip first cycles
|
||||
}
|
||||
for (uint32_t phase = 0; phase < 3; phase++) {
|
||||
Energy.data_valid[phase] = 0;
|
||||
Energy.voltage[phase] = (float)Ade7880ReadVerify(ADE7880_AVRMS + (phase * 2)) / 10000; // 0x0024CC94 = 241.1668 V
|
||||
Energy.current[phase] = (float)Ade7880ReadVerify(ADE7880_AIRMS + (phase * 2)) / 1000000; // 0x00002D6D = 0.011629 A
|
||||
Energy.active_power[phase] = (float)Ade7880ReadVerify(ADE7880_AWATT + phase) / 100; // 0xFFFFF524 = -27.79 W (wrong calibration)
|
||||
Energy.apparent_power[phase] = (float)Ade7880ReadVerify(ADE7880_AVA + phase) / 100; // 0xFFFFF50D
|
||||
Energy.frequency[phase] = 256000.0f / Ade7880ReadVerify(ADE7880_APERIOD + phase); // Page 34 and based on ADE7880_FREQ_INIT
|
||||
Ade7880.active_energy[phase] = Ade7880ReadVerify(ADE7880_AWATTHR + phase); // 0xFFFFFF8F = -1.12 Whr ??
|
||||
}
|
||||
// Incandescent light bulb, 242V, 0.11A, Pf100%, 27.9W
|
||||
Energy.voltage[0] = (float)Ade7880ReadVerify(ADE7880_AVRMS) / 10000; // 0x0024CC94 = 241.1668 V
|
||||
Energy.current[0] = (float)Ade7880ReadVerify(ADE7880_AIRMS) / 1000000; // 0x00002D6D = 0.011629 A
|
||||
Energy.voltage[1] = (float)Ade7880ReadVerify(ADE7880_BVRMS) / 10000; // 0x000003E8
|
||||
Energy.current[1] = (float)Ade7880ReadVerify(ADE7880_BIRMS) / 1000000; // 0x0000053C = 0.001340 A
|
||||
Energy.voltage[2] = (float)Ade7880ReadVerify(ADE7880_CVRMS) / 10000; // 0x0000037D
|
||||
Energy.current[2] = (float)Ade7880ReadVerify(ADE7880_CIRMS) / 1000000; // 0x00000547 = 0.001351 A
|
||||
Ade7880.nirms = Ade7880ReadVerify(ADE7880_NIRMS); // 0x000026DF = 0.009951 A ??
|
||||
Ade7880.isum = Ade7880ReadVerify(ADE7880_ISUM); // 0x00000FBE = 0.004030 A ??
|
||||
Energy.active_power[0] = (float)Ade7880ReadVerify(ADE7880_AWATT) / 100; // 0xFFFFF524 = -27.79 W (reverse connected)
|
||||
Energy.active_power[1] = (float)Ade7880ReadVerify(ADE7880_BWATT) / 100; // 0x00000000
|
||||
Energy.active_power[2] = (float)Ade7880ReadVerify(ADE7880_CWATT) / 100; // 0x00000000
|
||||
Energy.apparent_power[0] = (float)Ade7880ReadVerify(ADE7880_AVA) / 100; // 0xFFFFF50D
|
||||
Energy.apparent_power[1] = (float)Ade7880ReadVerify(ADE7880_BVA) / 100; // 0xFFFFFFFF
|
||||
Energy.apparent_power[2] = (float)Ade7880ReadVerify(ADE7880_CVA) / 100; // 0xFFFFFFFF
|
||||
// Billable
|
||||
Ade7880.active_energy[0] = Ade7880ReadVerify(ADE7880_AWATTHR); // 0xFFFFFF8F = -1.12 Whr ??
|
||||
Ade7880.active_energy[1] = Ade7880ReadVerify(ADE7880_BWATTHR); // 0x00000000
|
||||
Ade7880.active_energy[2] = Ade7880ReadVerify(ADE7880_CWATTHR); // 0x00000000
|
||||
Ade7880.apparent_energy[0] = Ade7880ReadVerify(ADE7880_AVAHR); // 0xFFFFFB9C = -11.23 VAr ??
|
||||
Ade7880.apparent_energy[1] = Ade7880ReadVerify(ADE7880_BVAHR); // 0xFFFFFFC7
|
||||
Ade7880.apparent_energy[2] = Ade7880ReadVerify(ADE7880_CVAHR); // 0xFFFFFFC6
|
||||
|
||||
uint16_t comp_mode = Ade7880ReadVerify(ADE7880_COMPMODE); // 0x01FF (or 0x41FF) = Angles between phase voltages and phase currents are measured
|
||||
uint32_t fline = (bitRead(comp_mode, 14)) ? 60 : 50; // Line frequency in Hz
|
||||
Ade7880.angle[0] = Ade7880ReadVerify(ADE7880_ANGLE0); // 0x13FD = cos(5117 * 360 * fline / 256000) = cos_phi
|
||||
Ade7880.angle[1] = Ade7880ReadVerify(ADE7880_ANGLE1); // 0x0706
|
||||
Ade7880.angle[2] = Ade7880ReadVerify(ADE7880_ANGLE2); // 0x0859
|
||||
|
||||
Energy.frequency[0] = 256000.0f / Ade7880ReadVerify(ADE7880_APERIOD); // Page 34 and based on ADE7880_COMPMODE_FREQ
|
||||
Energy.frequency[1] = 256000.0f / Ade7880ReadVerify(ADE7880_BPERIOD);
|
||||
Energy.frequency[2] = 256000.0f / Ade7880ReadVerify(ADE7880_CPERIOD);
|
||||
#ifdef ADE7880_PROFILING
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Cycle in %d ms"), millis() - start);
|
||||
#endif // ADE7880_PROFILING
|
||||
@ -608,55 +549,112 @@ void Ade7880EnergyEverySecond(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void Ade7880Defaults(void) {
|
||||
Ade7880.calib_frequency = ADE7880_FREQ_INIT;
|
||||
Ade7880.calib_current[0] = ADE7880_AIGAIN_INIT;
|
||||
Ade7880.calib_current[1] = ADE7880_BIGAIN_INIT;
|
||||
Ade7880.calib_current[2] = ADE7880_CIGAIN_INIT;
|
||||
Ade7880.calib_current[3] = ADE7880_NIGAIN_INIT;
|
||||
Ade7880.calib_voltage[0] = ADE7880_AVGAIN_INIT;
|
||||
Ade7880.calib_voltage[1] = ADE7880_BVGAIN_INIT;
|
||||
Ade7880.calib_voltage[2] = ADE7880_CVGAIN_INIT;
|
||||
Ade7880.calib_acpower[0] = ADE7880_APGAIN_INIT;
|
||||
Ade7880.calib_acpower[1] = ADE7880_BPGAIN_INIT;
|
||||
Ade7880.calib_acpower[2] = ADE7880_CPGAIN_INIT;
|
||||
Ade7880.calib_angle[0] = ADE7880_APHCAL_INIT;
|
||||
Ade7880.calib_angle[1] = ADE7880_BPHCAL_INIT;
|
||||
Ade7880.calib_angle[2] = ADE7880_CPHCAL_INIT;
|
||||
}
|
||||
|
||||
void Ade7880DrvInit(void) {
|
||||
if (PinUsed(GPIO_ADE7880_IRQ) && PinUsed(GPIO_ADE7880_IRQ, 1)) {
|
||||
if (I2cSetDevice(ADE7880_ADDR)) {
|
||||
I2cSetActiveFound(ADE7880_ADDR, "ADE7880");
|
||||
|
||||
#ifdef ADE7880_PROFILING
|
||||
uint32_t start = millis();
|
||||
#endif // ADE7880_PROFILING
|
||||
pinMode(Pin(GPIO_ADE7880_IRQ), INPUT);
|
||||
attachInterrupt(Pin(GPIO_ADE7880_IRQ), Ade7880Isr0, FALLING);
|
||||
Ade7880.irq0_state = 0;
|
||||
pinMode(Pin(GPIO_ADE7880_IRQ, 1), INPUT);
|
||||
|
||||
int reset = Pin(GPIO_RESET);
|
||||
if (-1 == reset) { reset = 16; } // Reset pin ADE7880 in Shelly 3EM
|
||||
pinMode(reset, OUTPUT);
|
||||
digitalWrite(reset, 0);
|
||||
delay(1);
|
||||
digitalWrite(reset, 1);
|
||||
pinMode(reset, INPUT);
|
||||
Ade7880Defaults();
|
||||
|
||||
pinMode(Pin(GPIO_ADE7880_IRQ), INPUT);
|
||||
attachInterrupt(Pin(GPIO_ADE7880_IRQ), Ade7880Isr0, FALLING);
|
||||
Ade7880.irq0_state = 0;
|
||||
pinMode(Pin(GPIO_ADE7880_IRQ, 1), INPUT);
|
||||
attachInterrupt(Pin(GPIO_ADE7880_IRQ, 1), Ade7880Isr1, FALLING);
|
||||
Ade7880.irq1_state = 0;
|
||||
|
||||
uint32_t timeout = millis() + 400;
|
||||
while (!TimeReached(timeout)) { // Wait up to 400 mSec
|
||||
if (1 == Ade7880.irq1_state) {
|
||||
|
||||
#ifdef ADE7880_PROFILING
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Reset in %d ms"), millis() - start);
|
||||
#endif // ADE7880_PROFILING
|
||||
|
||||
if (Ade7880Service1()) {
|
||||
if (I2cSetDevice(ADE7880_ADDR)) {
|
||||
I2cSetActiveFound(ADE7880_ADDR, "ADE7880");
|
||||
Energy.phase_count = 3; // Three phases
|
||||
// Settings->flag5.energy_phase = 1; // SetOption129 - (Energy) Show phase information
|
||||
// Energy.use_overtemp = true; // Use global temperature for overtemp detection
|
||||
TasmotaGlobal.energy_driver = XNRG_23;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (Ade7880SetCalibrate()) {
|
||||
Energy.phase_count = 3; // Three phases
|
||||
// Settings->flag5.energy_phase = 1; // SetOption129 - (Energy) Show phase information
|
||||
// Energy.use_overtemp = true; // Use global temperature for overtemp detection
|
||||
TasmotaGlobal.energy_driver = XNRG_23;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Ade7880Command(void) {
|
||||
// Investigate for need calibration of all three phases
|
||||
bool serviced = true;
|
||||
bool serviced = false;
|
||||
|
||||
if (CMND_ENERGYCONFIG == Energy.command_code) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
// {"rms":{"current_a":3166385,"current_b":3125691,"current_c":3131983,"current_s":1756557,"voltage_a":-767262,"voltage_b":-763439,"voltage_c":-749854},"angles":{"angle0":180,"angle1":176,"angle2":176},"powers":{"totactive": {"a":-1345820,"b":-1347328,"c":-1351979}},"freq":0}
|
||||
JsonParser parser(XdrvMailbox.data);
|
||||
JsonParserObject root = parser.getRootObject();
|
||||
if (root) {
|
||||
Ade7880Defaults();
|
||||
// All parameters are optional allowing for partial changes
|
||||
JsonParserToken val = root[PSTR("freq")];
|
||||
if (val) { Ade7880.calib_frequency = val.getUInt(); }
|
||||
JsonParserObject rms = root[PSTR("rms")].getObject();
|
||||
if (rms) {
|
||||
val = rms[PSTR("current_a")];
|
||||
if (val) { Ade7880.calib_current[0] = val.getInt(); }
|
||||
val = rms[PSTR("current_b")];
|
||||
if (val) { Ade7880.calib_current[1] = val.getInt(); }
|
||||
val = rms[PSTR("current_c")];
|
||||
if (val) { Ade7880.calib_current[2] = val.getInt(); }
|
||||
val = rms[PSTR("current_s")];
|
||||
if (val) { Ade7880.calib_current[3] = val.getInt(); }
|
||||
val = rms[PSTR("voltage_a")];
|
||||
if (val) { Ade7880.calib_voltage[0] = val.getInt(); }
|
||||
val = rms[PSTR("voltage_b")];
|
||||
if (val) { Ade7880.calib_voltage[1] = val.getInt(); }
|
||||
val = rms[PSTR("voltage_c")];
|
||||
if (val) { Ade7880.calib_voltage[2] = val.getInt(); }
|
||||
}
|
||||
JsonParserObject angles = root[PSTR("angles")].getObject();
|
||||
if (angles) {
|
||||
val = angles[PSTR("angle0")];
|
||||
if (val) { Ade7880.calib_angle[0] = val.getUInt(); }
|
||||
val = angles[PSTR("angle1")];
|
||||
if (val) { Ade7880.calib_angle[1] = val.getUInt(); }
|
||||
val = angles[PSTR("angle2")];
|
||||
if (val) { Ade7880.calib_angle[2] = val.getUInt(); }
|
||||
}
|
||||
JsonParserObject powers = root[PSTR("powers")].getObject();
|
||||
if (powers) {
|
||||
JsonParserObject totactive = powers[PSTR("totactive")].getObject();
|
||||
if (totactive) {
|
||||
val = totactive[PSTR("a")];
|
||||
if (val) { Ade7880.calib_acpower[0] = val.getInt(); }
|
||||
val = totactive[PSTR("b")];
|
||||
if (val) { Ade7880.calib_acpower[1] = val.getInt(); }
|
||||
val = totactive[PSTR("c")];
|
||||
if (val) { Ade7880.calib_acpower[2] = val.getInt(); }
|
||||
}
|
||||
}
|
||||
|
||||
bool status = Ade7880SetCalibrate();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("A78: Re-init status %d"), status);
|
||||
}
|
||||
}
|
||||
Response_P(PSTR("{\"%s\":{"
|
||||
"\"rms\":{\"current_a\":%d,\"current_b\":%d,\"current_c\":%d,\"current_s\":%d,\"voltage_a\":%d,\"voltage_b\":%d,\"voltage_c\":%d},"
|
||||
"\"angles\":{\"angle0\":%d,\"angle1\":%d,\"angle2\":%d},"
|
||||
"\"powers\":{\"totactive\":{\"a\":%d,\"b\":%d,\"c\":%d}},\"freq\":%d}}"),
|
||||
XdrvMailbox.command,
|
||||
Ade7880.calib_current[0], Ade7880.calib_current[1], Ade7880.calib_current[2], Ade7880.calib_current[3],
|
||||
Ade7880.calib_voltage[0], Ade7880.calib_voltage[1], Ade7880.calib_voltage[2],
|
||||
Ade7880.calib_angle[0], Ade7880.calib_angle[1], Ade7880.calib_angle[2],
|
||||
Ade7880.calib_acpower[0], Ade7880.calib_acpower[1], Ade7880.calib_acpower[2], Ade7880.calib_frequency);
|
||||
serviced = true;
|
||||
}
|
||||
|
||||
return serviced;
|
||||
}
|
||||
@ -672,8 +670,7 @@ bool Xnrg23(uint8_t function) {
|
||||
|
||||
switch (function) {
|
||||
case FUNC_LOOP:
|
||||
if (1 == Ade7880.irq0_state) { Ade7880Service0(); }
|
||||
// if (1 == Ade7880.irq1_state) { Ade7880Service1(); }
|
||||
if (Ade7880.irq0_state) { Ade7880Service0(); }
|
||||
break;
|
||||
case FUNC_ENERGY_EVERY_SECOND:
|
||||
Ade7880EnergyEverySecond();
|
||||
|
Loading…
x
Reference in New Issue
Block a user