Calibrate and get energy readings from ADE7758 IC from Analog Devices
Fork of ADE7758 by
Currently this library can be used to calibrate and get VRMS, IRMS, active, and apparent energy. I havent worked on reactive energy measurement.
Diff: ade7758.cpp
- Revision:
- 3:4fad91cf047a
- Parent:
- 2:ea36884772ae
- Child:
- 4:5547bb32eb32
diff -r ea36884772ae -r 4fad91cf047a ade7758.cpp --- 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)