Calibrate and get energy readings from ADE7758 IC from Analog Devices

Fork of ADE7758 by Emma

Currently this library can be used to calibrate and get VRMS, IRMS, active, and apparent energy. I havent worked on reactive energy measurement.

Revision:
3:4fad91cf047a
Parent:
2:ea36884772ae
Child:
4:5547bb32eb32
--- a/ade7758.cpp	Fri Apr 10 10:12:27 2015 +0000
+++ b/ade7758.cpp	Mon Apr 13 02:40:41 2015 +0000
@@ -56,7 +56,7 @@
     // 1. Clear xWG, xVARG, xVAG
     write16bits(AWG, 0x0000);
     write16bits(BWG, 0x0000);
-    write16bits(CWG, 0x0000);        
+    write16bits(CWG, 0x0000);
     write16bits(AVARG, 0x0000);
     write16bits(BVARG, 0x0000);
     write16bits(CVARG, 0x0000);
@@ -94,29 +94,32 @@
     int CWATTHRTemp = getWattHR(PHASE_C);
     int CVAHRTemp = getVAHR(PHASE_C);
 
-    // 9. Write xWG and xVAG
-    // Calculate expected WattHr
-    int APCFDENVal = read16bits(APCFDEN);
-    int APCFNUMVal = read16bits(APCFNUM);
-    int WDIVVal = read8bits(WDIV);
-    int VARCFDENVal = read16bits(VARCFDEN);
-    int VARCFNUMVal = read16bits(VARCFNUM);
-    int VADIVVal = read8bits(VADIV);
+    // 9. Calculate Wh/LSB and VAh/LSB
+    float accumTime = getAccumulationTime(PHASE_A);
+    float tempEnergy = ITEST*VNOM*accumTime;
+    AWhLSB = tempEnergy/(3600*AWATTHRTemp);
+    BWhLSB = tempEnergy/(3600*BWATTHRTemp);
+    CWhLSB = tempEnergy/(3600*CWATTHRTemp);
+    AVAhLSB = tempEnergy/(3600*AVAHRTemp);
+    BVAhLSB = tempEnergy/(3600*BVAHRTemp);
+    CVAhLSB = tempEnergy/(3600*CVAHRTemp);
 
-    float AccumTime = getAccumulationTime();
-    float tempWH = ((4*3200*0.6*220*1*AccumTime)/(1000*3600));
-    float WattHRExpected = tempWH * (APCFDENVal/APCFNUMVal) * (1/WDIVVal);
-    float VAHRExpected = tempWH * (VARCFDENVal/VARCFNUMVal) * (1/VADIVVal);
-        
-    // 9a. Calculate xWG values
-    int AWGValue = ((WattHRExpected/AWATTHRTemp) - 1)*4096;
-    int BWGValue = ((WattHRExpected/BWATTHRTemp) - 1)*4096;
-    int CWGValue = ((WattHRExpected/CWATTHRTemp) - 1)*4096;
+    // 10. Wait LENERGY interrupt and read 6 energy registers
+    while ( _ADEINT != 0 ) { } // wait until INT go low
+    int AWHREXPECTED = getWattHR(PHASE_A);
+    int AVAHREXPECTED = getVAHR(PHASE_A);
+    int BWHREXPECTED = getWattHR(PHASE_B);
+    int BVAHREXPECTED = getVAHR(PHASE_B);
+    int CWHREXPECTED = getWattHR(PHASE_C);
+    int CVAHREXPECTED = getVAHR(PHASE_C);
 
-    // 9b. Calculate xVAG values
-    int AVAGValue = ((VAHRExpected/AVAHRTemp) - 1)*4096;
-    int BVAGValue = ((VAHRExpected/BVAHRTemp) - 1)*4096;
-    int CVAGValue = ((VAHRExpected/CVAHRTemp) - 1)*4096;
+    // 11. Calculate xWG and xVAG values
+    int AWGValue = ((AWHREXPECTED/AWATTHRTemp) - 1)*4096;
+    int BWGValue = ((BWHREXPECTED/BWATTHRTemp) - 1)*4096;
+    int CWGValue = ((CWHREXPECTED/CWATTHRTemp) - 1)*4096;
+    int AVAGValue = ((AVAHREXPECTED/AVAHRTemp) - 1)*4096;
+    int BVAGValue = ((BVAHREXPECTED/BVAHRTemp) - 1)*4096;
+    int CVAGValue = ((CVAHREXPECTED/CVAHRTemp) - 1)*4096;
 
     // 10. Write the values to xWG and xVAG
     write16bits(AWG, AWGValue);
@@ -127,7 +130,7 @@
     write16bits(CVAG, CVAGValue);
 }
 
-float ADE7758::getAccumulationTime() {
+float ADE7758::getAccumulationTime(char phase) {
     uint16_t frequency = lineFreq(phase);
     uint16_t LineCYC = read16bits(LINECYC);
     write8bits(LCYCMODE, 0xBF);
@@ -209,6 +212,7 @@
     else if ( phase == PHASE_C ) {
         return AvgIRMS * 0.00000958;
     }
+    else { return 0; }
 }
 
 float ADE7758::calculateVRMS(char phase) {
@@ -228,9 +232,10 @@
     else if ( phase == PHASE_C ) {
         return AvgVRMS * 0.000156;
     }
+    else { return 0; }
 }
 
-void ADE7758::calculateEnergy()
+void ADE7758::calculateEnergy(char phase)
 {
     // 1. Set phase used for line zero cross detection
     lineFreq(phase);
@@ -252,12 +257,12 @@
     
     // 6. Wait LENERGY interrupt and read 6 energy registers
     while ( _ADEINT != 0 ) { } // wait until INT go low
-    AWATTHRValue = getWattHR(PHASE_A);
-    AVAHRValue = getVAHR(PHASE_A);
-    BWATTHRValue = getWattHR(PHASE_B);
-    BVAHRValue = getVAHR(PHASE_B);
-    CWATTHRValue = getWattHR(PHASE_C);
-    CVAHRValue = getVAHR(PHASE_C);
+    int AWATTHRValue = getWattHR(PHASE_A);
+    int AVAHRValue = getVAHR(PHASE_A);
+    int BWATTHRValue = getWattHR(PHASE_B);
+    int BVAHRValue = getVAHR(PHASE_B);
+    int CWATTHRValue = getWattHR(PHASE_C);
+    int CVAHRValue = getVAHR(PHASE_C);
 }
 
 long ADE7758::waveform(char phase,char source)