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:
1:f5e8c8591449
Parent:
0:cf3dc3c5156b
Child:
2:ea36884772ae
diff -r cf3dc3c5156b -r f5e8c8591449 ade7758.cpp
--- a/ade7758.cpp	Wed Apr 08 13:25:39 2015 +0000
+++ b/ade7758.cpp	Fri Apr 10 03:58:10 2015 +0000
@@ -3,8 +3,8 @@
 #include "SWSPI.h"
 
 // public
-ADE7758::ADE7758(PinName mosi, PinName miso, PinName sclk, PinName cs):
-    _ADE7758SPI(mosi, miso, sclk), _ADESS(cs)
+ADE7758::ADE7758(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName interrupt):
+    _ADE7758SPI(mosi, miso, sclk), _ADESS(cs), _ADEINT(interrupt)
 {
     _ADESS = 1;
 }
@@ -13,8 +13,33 @@
 {
     enableChip();
     //normal mode
-    _ADE7758SPI.format(8);    
-    write8bits(OPMODE, 0x04);    
+    _ADE7758SPI.format(8, 1); // pha 0, pol 1
+    _ADE7758SPI.frequency(1000000);    
+    write8bits(OPMODE, 0x04);
+}
+
+void ADE7758::CalibrateVI(uint8_t numSamples) 
+{    
+    write8bits(LCYCMODE, 0x38);
+    write24bits(MASK, 0xE00);
+    long AVRMSBuffer = 0, BVRMSBuffer = 0, CVRMSBuffer = 0;
+    long AIRMSBuffer = 0, BIRMSBuffer = 0, CIRMSBuffer = 0;
+    for (uint8_t i=0; i<numSamples; i++) {
+        read24bits(RSTATUS);
+        while ( _ADEINT != 0 ) { } // wait until INT go low
+        AVRMSBuffer += VRMS(PHASE_A);
+        BVRMSBuffer += VRMS(PHASE_B);
+        CVRMSBuffer += VRMS(PHASE_C);
+        AIRMSBuffer += IRMS(PHASE_A);
+        BIRMSBuffer += IRMS(PHASE_B);
+        CIRMSBuffer += IRMS(PHASE_C);
+    }
+    AVRMSCalib = AVRMSBuffer/numSamples;
+    BVRMSCalib = BVRMSBuffer/numSamples;
+    CVRMSCalib = CVRMSBuffer/numSamples;
+    AIRMSCalib = AIRMSBuffer/numSamples;
+    BIRMSCalib = BIRMSBuffer/numSamples;
+    CIRMSCalib = CIRMSBuffer/numSamples;
 }
 
 int ADE7758::getWattHR(char phase)
@@ -73,6 +98,31 @@
   return current/10;
 }
 
+
+float ADE7758::CalculateIRMS(char phase) {
+    if ( phase == PHASE_A ) {
+        return IRMS(phase) * 0.00000967;
+    }
+    else if ( phase == PHASE_B ) {
+        return IRMS(phase) * 0.00000955;
+    }    
+    else if ( phase == PHASE_C ) {
+        return IRMS(phase) * 0.00000958;
+    }
+}
+
+float ADE7758::CalculateVRMS(char phase) {
+    if ( phase == PHASE_A ) {
+        return VRMS(phase) * 0.000158;
+    }
+    else if ( phase == PHASE_B ) {
+        return VRMS(phase) * 0.000157;
+    }
+    else if ( phase == PHASE_C ) {
+        return VRMS(phase) * 0.000156;
+    }        
+}
+
 void accumulateEnergy()
 {
     
@@ -162,6 +212,23 @@
     disableChip();
 }
 
+void ADE7758::write24bits(char reg, unsigned int data)
+{
+    enableChip();
+    
+    wait_ms(10);
+    _ADE7758SPI.write(REG_WRITE(reg));
+    wait_ms(2);
+    _ADE7758SPI.write((unsigned char)((data>>16)&0xFF));
+    wait_ms(2);
+    _ADE7758SPI.write((unsigned char)((data>>8)&0xFF));
+    wait_ms(2);
+    _ADE7758SPI.write((unsigned char)(data&0xFF));
+    wait_ms(1);
+
+    disableChip();
+}
+
 unsigned char ADE7758::read8bits(char reg)
 {
     enableChip();
@@ -213,7 +280,7 @@
     wait_ms(1);
     
     disableChip();
-    ret= (ret<<16)|(ret1<<8)|ret0;
+    ret= (ret<<16)|(ret1<<8)| ret0;
     return ret;
 }