Post Go back to editing

Vrms calibration in ADE7758_SPI with Arduino

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Hi. I am using ADE7758 in my energy monitoring system project. I am able to use SPI to communicate with my Arduino and it is able to display the results. However, I am having some problem calibrating VRMS with the steps given in the ADE7758 datasheet in page 55. By following the steps, I have writen the values into LCYCMODE and MASK like below:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

In cpp. file

void ADE7758::setLineCyc(int l)

{    write16 (LINECYC, l);          }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

In Arduino Setup

void ADE7758::setMASK(long e)               

{    write24 (MASK, e);             }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    

Then, I followed step  4 by taking N=100,

In cpp file

long ADE7758::Avrms() {

        char i=0;

        long v=0;

        getAVRMS();                                                            //Ignore first reading to avoid garbage

        for(i=0;i<100;++i)    

          {    v+=getAVRMS();     }

        return v/100;

}

long ADE7758::getAVRMS(void) {

        long lastupdate = 0;

        ADE7758::getresetInterruptStatus();                          // Clear all interrupts

        lastupdate = millis();

        while( !  ( ADE7758::getInterruptStatus() & ZXA )  )      // wait Zero-Crossing

        {                                                                             // wait for the selected interrupt to occur

                if ( ( millis() - lastupdate ) > 100)

                {       wdt_reset();

                        Serial.println("\n--> getAVRMS Timeout - no AC input");

                        break; 

                }

        }        

        return read24(AVRMS);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

With this code, I am able to produce different values for different input voltage. But the changes are very small.

In order to use the AVRMSOS formula, my readings after using a 10:1 step down transformer:

V_min = 2.5,       V_nom = 24

and the values obtained are as below:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

(formula can be found in pg 55 of datasheet)

So, substituting the value into the formula:

V_in= 5.7V
V_in= 24.5V
V_in= 49V

--> before calibration

VRMS_100: 16767890.0000

--> after calibration

VRMS_100: 1341.5760498046

--> before calibration

VRMS_100: 16705047.0000

--> after calibration

VRMS_100: 1336.5480957031

--> before calibration

VRMS_100: 16693657.0000

--> after calibration

VRMS_100: 1335.6367187500

--> before calibration

VRMS_100: 16766609.0000

--> after calibration

VRMS_100: 1341.4735107421

--> before calibration

VRMS_100: 16762652.0000

--> after calibration

VRMS_100: 1341.1569824218

--> before calibration

VRMS_100: 16506393.0000

--> after calibration

VRMS_100: 1320.6540527343

--> before calibration

VRMS_100: 16771791.0000

--> after calibration

VRMS_100: 1341.8881835937

--> before calibration

VRMS_100: 16767304.0000

--> after calibration

VRMS_100: 1341.5291748046

--> before calibration

VRMS_100: 16777212.0000

--> after calibration

VRMS_100: 1342.3218994140

Hence, AVRMSOS = 0x00E (Taking only the last 3 LSB)

The readings obtained are very large. Does this have to do with the VRMSGAIN? I have not written any values into the VRMSGAIN. May I know how can I obtain the correct value of VRMSGAIN?

The connectivity for the circuit is as below:           

Much of the codes are refered from this link: https://code.google.com/p/ardugrid7753/source/browse/#svn%2Ftrunk

Thank you.

ADE7758.pdf
  • Hi jianyee92,

    First off, for step 4, there is a simpler and accurate way to read the RMS register values without having to use zero crossings. For this method, the xVRMS or xIRMS register should be read at least 50 or 60 times per second for one second depending on your line frequency and then averaged. The more readings that are taken in that one second, the better the accuracy.

    The values for VRMSvmin and VRMSvnom look to be off because the values for V_nom and V_min are 10:1 but the VRMS values do not reflect this. The VRMSvnom register should have a 10X greater value than VRMSvmin register value or around that. The ratio for you VRMS measurements is much less. Try the method I mentioned above.

    When you say you are using a step down transformer, how exactly is it connected? With the primary coil at 220V and then the secondary coil going into the resistor divider network or is the secondary coil going directly to the VAP input?  What is the reason for using the transformer rather than adjusting the resistor divider network to accomadate the line voltage?

    Best Regards,

    Dlath

  • Hi Dlath,

    First of all, appreciate your help and advices.

    " First off, for step 4, there is a simpler and accurate way to read the RMS register values without having to use zero crossings. For this method, the xVRMS or xIRMS register should be read at least 50 or 60 times per second for one second depending on your line frequency and then averaged. The more readings that are taken in that one second, the better the accuracy. "

    I changed the .cpp and ino file in arduino so that the function of reading zero-crossing in commented. The code is showed as below:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    In .cpp file

    /*

    long ADE7758::getAVRMS(void){

            long lastupdate = 0;

            ADE7758::getresetInterruptStatus();                                    // Clear all interrupts

            lastupdate = millis();

            while( !  ( ADE7758::getInterruptStatus() & ZXA )  )               // wait Zero-Crossing

            { // wait for the selected interrupt to occur

                    if ( ( millis() - lastupdate ) > 100)

                    {

                           // wdt_reset();

                            Serial.println("\n--> getAVRMS Timeout - no AC input");

                            break; 

                    }

            }        

            return read24(AVRMS);

    }

    */                                                                        //comment out the zero crossing detection function

    long ADE7758::Avrms(){

            char i=0;

            long v=0;

            //getAVRMS();                                      //double confirm to comment out the zero crossing function

            for(i=0;i<100;++i){

                    v+=getAVRMS();

            }

            return v/100;

    }                                                                 //read 100 readings.

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    However, the readings I obtained now is constant all the time, which is the approximate VRMS register values according to the pg29 datasheet.

    (from pg 29 datasheet)

    (printscreen of result from Arduino Serial Monitor)

    I am suspecting that there are also connection/ hardware problem along the way as the voltage feed in is measured by VAP with respect to VN (according to pg18 datasheet). I am leaving the connection in pin 13 unconnected ( which i think it should be connected with the neutral of 220V). The purpose of using a transformer to step down my input voltage to 24V is due to my lack of understanding of connection of live and neutral wire. Fyi, I intend to use the domestic power supply which is 240V to feed the voltage into pin 13 when I am sure with the connection.

    Original idea of energy monitoring system using a filament bulb

    Progress so far using a variable transformer-->

    Anyhow, I had adjusted the voltage divider resistor circuit to 1K and 100K resistor. My expected result is that when i change the input voltage to pin 13(VAP), the result would be be different but the output I am having now is constantly 16777215.00.

    Regards,

    jianyee92


  • Hi jianyee92,

    That VRMS value seems too consistent, there will always be some small variation in the reading, it seems like something is going wrong when reading the VRMS values. Try reading just one value at a time and display the result at an appropriate speed to verify the code. A decimal value of 16777215d is 0xFFFFFF in hex, that looks to be a communication error. Check the SPI wire connections and that the SPI communication is correctly setup in your code.

    With the voltage inputs, it is important that there is an appropriate resistor divider network before the VAP input as shown in Figure 34 of the ADE7758 Data Sheet. Then the live wire can be connected before the 1MOhm resistor as shown and the resistor divider will bring the 240V down to a 339mV PEAK wave at the input of the part. This resistor divider brings the voltage down appropriatly with the 1MOhm value adjustable as necessary. Use the recommended filtering with capacitors and resistors as in  Figure 34. The neutral needs to be connected at VN. Example 3-Phase configuration can be seen in Page 14 of the following:

    http://www.analog.com/static/imported-files/application_notes/AN-639.pdf

    With an input of 24V and resistor divider of 100K then 1K, the voltage input to pin VAP is 238mV which is an acceptable input. The fact that the reading is near the full scale (500mV) reading is odd because it should be about half that with your inputs. Do you have a schematic of your setup?

    Regards,

    Dlath

  • Hi Dlath,

    Yes, it could be the problem from the SPI connection. It may due to loose connection between the Arduino SPI port with the ADE7758 as once the voltage supplied from the transformer is switched off, the serial monitor display constant 16777215 value. For your information, the pins connection and schematic is attached as shown below:

    A doubt, where should I connected my "hanging ground"? If considering the same ground symbol, is it a must to connect to the neutral of the transformer?

    refered from http://arduino.cc/en/Reference/SPI

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    void ADE7758::setSPI(void){ 

           pinMode(CS,OUTPUT);                                //Chip select by digital output on pin nbs CS

           digitalWrite (CS,HIGH);

                                                                            //Initialize SPI

           SPI.setDataMode(SPI_MODE2);

           SPI.setClockDivider(SPI_CLOCK_DIV32);

           SPI.setBitOrder(MSBFIRST);

           SPI.begin();

           delay(10);

    }

     

    void ADE7758::closeSPI(void) {

            SPI.end();

            delay(10);

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    With this, I would also like to include the READ and WRITE function that I referred the .cpp file from this link:

    https://code.google.com/p/ardugrid7753/source/browse/#svn%2Ftrunk

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /*=== read24 ===*/

    unsigned long ADE7758::read24(char reg){

            enableChip();

            unsigned char b2,b1,b0;

            delayMicroseconds(50);

            SPI.transfer(reg);

            delayMicroseconds(50);

            b2=SPI.transfer(0x00);

            delayMicroseconds(50);

            b1=SPI.transfer(0x00);

            delayMicroseconds(50);

            b0=SPI.transfer(0x00);

            delayMicroseconds(50);

            disableChip();

            return (unsigned long)b2<<16 | (unsigned long)b1<<8 | (unsigned long)b0;

    }

    void ADE7758::write24(char reg, unsigned long data){

            enableChip();

            unsigned char data0=0,data1=0,data2=0;

            // For Write -> DB7 = 1  / For Read -> DB7 = 0

            reg |= WRITE;

            //split data

            data0 = (unsigned char)data;

            data1 = (unsigned char)(data>>8);

              data2 = (unsigned char)(data>>16);

           

            //register selection, we have to send a 1 on the 8th bit to perform a write

            delayMicroseconds(50);

            SPI.transfer((unsigned char)reg);   

            delayMicroseconds(50);   

            //data send, MSB first

              SPI.transfer((unsigned char)data2);

              delayMicroseconds(50);

            SPI.transfer((unsigned char)data1);

            delayMicroseconds(50);

            SPI.transfer((unsigned char)data0); 

            delayMicroseconds(50);

            disableChip();

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    A quick update on my progress

    So, i decided to re-run my circuit again yesterday and the result now have variation, (which i dont know why ).

    In order to do the xVRMSOS calibration to remove the noise at low freqeuncy, I input 24V and 240V into ADE7758 for Vmin and Vnom respectively. Then i select 333 readings from the output and average them and the xVRMSOS result now is 0x58F (taking the last 3 LSB)

    After writing 0x58F into the AVRMSOS register, the VRMSOS seem to be more constant at 16200000 (observed from the graph). Then, applying Real Vrms= AVRMS (reading from the register) x (240/LSB), my result now is approximately 248.5V. However, when i try to lower the 240V input voltage, the ADE7758 does not seem to decrease proportional because as the input voltage decreases, the ADE would also sense the decrease and output a lower reading.

    Thank you.

    Regards,

    jianyee92

  • One more doubt, could I use a current sensor (ACS712 from sparkfun electronic) instead of a 1800:1 current transformer?

    So to double confirm my SPI is working, I try to rewrite the whole h file, cpp file and ino file. I intend to write hex number into the avrmsos register and read it out in the same ino file to examine whether  I had successfully the SPI worked correctly. However, the serial monitor result shows 0.00000 reading, which i think now most probably, my failure so far was due to SPI. Could it be connection problem?

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    .h file

    #ifndef ADE7758_H

    #define ADE7758_H

    #define AVRMSOS 0x33

    #define CS 10                // Chip Select ADE7753 - Digital output pin nbr on Olimex Energy Shield 

    #define WRITE 0x80           // WRITE bit BT7 to write to registers

    #define CLKIN 10000000    

    class ADE7758{

    public:

              void setAVRMSOS (int avos);          //write something into AVRMS register

              int readAVRMSOS (void);                    //read something from AVRMS register

              void setSPI(void);

              void closeSPI(void);

              void enableChip(void);

              void disableChip(void);

              void write16(char reg, unsigned int data);

              unsigned int read16(char reg);

    };

    #endif

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    .cpp file

    #include <Arduino.h>

    #include <string.h>

    #include <SPI.h>

    #include "yu.h"

    void ADE7758::setSPI(void){

     

      pinMode(CS,OUTPUT);  //Chip select by digital output on pin nbs CS

      digitalWrite (CS,HIGH);

      //Initialize SPI

      SPI.setDataMode(SPI_MODE2);

      SPI.setClockDivider(SPI_CLOCK_DIV32);

      SPI.setBitOrder(MSBFIRST);

      SPI.begin();

      delay(10);

    }

    void ADE7758::closeSPI(void) {

            SPI.end();

            delay(10);

    }

    void ADE7758::enableChip(void){

            digitalWrite(CS,LOW);

    }

    void ADE7758::disableChip(void){

            digitalWrite(CS,HIGH); 

    }

    unsigned int ADE7758::read16(char reg){

            enableChip();

            unsigned char b1,b0;

            delayMicroseconds(50);

            SPI.transfer(reg);

            delayMicroseconds(50);

            b1=SPI.transfer(0x00);

            delayMicroseconds(50);

            b0=SPI.transfer(0x00);

            delayMicroseconds(50);

            disableChip();

            return (unsigned int)b1<<8 | (unsigned int)b0;

    }

    void ADE7758::write16(char reg, unsigned int data){

            enableChip();

            unsigned char data0=0,data1=0;

            // 8th bit (DB7) of the register address controls the Read/Write mode (Refer to spec page 55 table 13)

            // For Write -> DB7 = 1  / For Read -> DB7 = 0

            reg |= WRITE;

            //split data

            data0 = (unsigned char)data;

            data1 = (unsigned char)(data>>8);

           

            //register selection, we have to send a 1 on the 8th bit to perform a write

            delayMicroseconds(50);

            SPI.transfer((unsigned char)reg);   

            delayMicroseconds(50);   

            //data send, MSB first

            SPI.transfer((unsigned char)data1);

            delayMicroseconds(50);

            SPI.transfer((unsigned char)data0); 

            delayMicroseconds(50);

            disableChip();

    }

    int ADE7758::readAVRMSOS (void){

              return read16(AVRMSOS);

    }

    void ADE7758::setAVRMSOS(int avos){

              write16(AVRMSOS,avos);

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    .ino file

    #include "yu.h"

    #include <Arduino.h>

    #include "SPI.h"

    #include <avr/pgmspace.h>

    #include <avr/wdt.h>                    //watchdog timer

    unsigned long TimeStampSinceLastReboot;

    unsigned long previousWdtMillis = 0;

    unsigned long wdtInterval          = 0;

    void setup()          {

              ADE7758 meter;

    //          wdt_disable();

              Serial.begin(115200);

    //TimeStampSinceLastReboot = millis();

              //Serial.println("intitialize=============");

              meter.setSPI();

     

              //meter.setLCYCMODE(0x38);

            meter.setAVRMSOS(0x58F);

              //meter.setInterruptsMask(0xE00);

              //meter.setAVRMSOS(0x00E);

              //meter.setWAVMODEvoltage(0x04);

     

              meter.closeSPI();

     

    //          WatchdogSetup();

     

    //          wdt_reset();

    }

    void loop()          {

    //          wdt_reset();                    //reset watch dog timer to prevenet timeout

     

              ADE7758 meter;

              meter.setSPI();

              float avrms = 0;

              avrms          = meter.readAVRMSOS();

              Serial.println ( avrms, DEC );

     

           

              meter.closeSPI();

    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Any idea? Thank you


  • Hi Jianyee92,

    Be sure you are following Page 56 on the ADE7758 data sheet for serial communication. One important not is that during serial communication, CS_bar needs to be driven low. Before you try any calibration make sure a register with a default value can be read correctly as I explain below.

    As for the “hanging ground”, make sure that the neutral line is connected to ground, these need to be connected for correct operation.

    I don't see it in the schematic so I want to double check, are both AVDD and DVDD connected to 5V?

    First off, be sure that you are correctly reading registers from the ADE7758 by reading a register such as COMPMODE (default: 0x1C) or another register with a default value to see that you read the correct value (take into account the register length in this process). Then check the inputs, when you input 240V, check the voltage channel inputs of the ADE7758 with an oscilloscope to verify the amplitude of the input and do the same with 24V to make sure that the amplitude decreases by a factor of 10. When the part is working correctly, even without calibration this equations should be roughly true VRMS(@240V) = 10*VRMS(@24V).

    Do not start calibration before you have verified correct communication with the part. We do not cover arduino's and for specific information on arduino code, it would be best to go to their forums for questions. I am not familiar enough with that microcontroller to find specific syntax errors but I can help you debug the problem.

    As for the ACS712, it would be best to use the CT until we have figured out the problem in order to remove other variables, such as the performance of that part.

    Regards,

    Dlath

  • Hi Dlath,

    Appreciate your advices and guidance along the way. As you have mentioned in the previous post, I try to confirm whether the my SPI is working correctly with a brand new ADE7758 that I received few days ago. I read several registers (8 bits, 12 bits, 16 bits, and 24 bits) with default value and eventaully confirm that the SPI is correctly connected. Result shown as below for reference:

    Description:

    1. For testing purpose, read default value of COMPMODE register (0x16) = 0x1C. Result shown decimal number of 28 which is correct.

        --> confirm SPI is working properly

    2. Then, by following the step proposed in the datasheet (pg 55), set LCYCMODE register and MASK[0:24]] to 0x38 and 0xE00 respectively. To     double ensure the register is probably written, the value of register is out and display on the serial monitor. Result shown decimal of 56d (38h)     and 3584 (E00) respectively.

         --> confirm LCYCMODE and MASK is written with desired value.

    3. Calculation of AVRMSOS is done using the formula:

         Therefore, the AVRMSOS register is set to be 0x49 for calibration. To double ensure the register is probably written, the value of register is out        and display on the serial monitor. Result shown decimal of 73d (49h).

         --> confirm AVRMSOS register is written with desired value.

    4. To obtain the V(constant), the input voltage is set to 240V again and the value of AVRMS register was recorded. So, my V(constant) is     240/1074546= 2.2335x10^(-4). Setting the voltage constant (real world voltage= AVRMS register x V_constant), I was able to obtain the real     world voltage (which approximately 0.80% error ).         

    May I know is there any way to improve my voltage reading? Any suggestion of circuitry system to be added for the VAP pin?

    Also, I had open one more discussion but no one seem to reply me yet. Please help. 

    http://ez.analog.com/message/124813#124813

    Thank you very much

  • Hi Dlath,

    Yesterday when I re-tested my ADE7758 using the same code as previous one (reply posted on 28 Nov) to check whether it is working as expected. However, when I read the AVRMS register, the values output seem not correct anymore and the reading seems to increase from a small value (eg. 65.01) to a large value when I let the arduino read the register for approximately 2 min. Sometimes, the reading will also fluctuate within a certain range. I checked the other register that have default value and the serial monitor is given the correct decimal number (so i dun think is SPI problem since the arduino can read correctly the default value). In short, only when SPI is reading AVRMS register, the reading is not constant even though I did not alternate the input voltage that feed into VAP.

    Please guide. Thank you.

  • Hi Jianyee92,

    It sounds like now the communication is not a problem because you are getting reliable readings from the registers now. When you are taking the readings for xVRMS, are you just reading one single value? To get the most accurate value for the RMS registers, the register needs to be read at least 50 times (for 50Hz line) in one second (the more the better) and then the readings averaged over that one second.  There is some fluctuation in the reading but this will remove that fluctuation to have an accurate value for calibration and measurement.

    What values were you reading from the register when you said they were incorrect? Did you try completely resetting the part by removing all power, to see if that makes a difference?

    Another thing to be watchful of is that all the decoupling capacitors from Figure 34 be placed as close as possible to the pins, the closer the better.  Improvements can be made by soldering everything down to a PCB rather than using a breadboard because loose connections can add some error or inconsistencies.

    I will answer the question about the burden resistor in the given discussion.

    Best Regards,

    Dlath

  • Hi Dlath,

    Thanks a lot for the guidance all along. Appreciate it. I am able to get the calibrated AVRMS real world reading correctly with approximately 0.07% error.

    Following up, I am currently doing the section for "Calibration Using Line Accumulation" in pg48. Running through the steps stated in pg49, I would like to confirm that is my coding was correctly written?

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 0     : APCF_den calculation:

    Problem     : I still have some problem in understanding the value of I_fullscale. As far as I know, i used the value from "current range AC" in                    datasheet.

    Problem     : How do I know the meter constant, MC? Is this value assumed by ourself? For the time being, I used the value= " 3200imp/kWhr" that                    stated in example pg50.

    Source code:

    write16(APCFDEN,0X0168);     //360 in decimal= 168 in hexa

    write16(APCFNUM,0x0001);    //set APCFNUM for value 1

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 1: Clear xWG, xVARG, xVAG

    Source code:

    write16(AWG,0x0007);

    write16(BWG,0x0000);

    write16(CWG,0x0000);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 2: Select Phase A /B /C for line period measurement with the FREQSEL [1:0] bits in MMODE register (0x14).

    Problem: I leave this as default value but I saw the post from neveth that the MMODE is set to be 0x00. So, I am quite confused with this.

    Neveth's post: http://ez.analog.com/message/78486#78486

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 3: Writing 0xBF to LCYCMODE

    Source code:

    write8(LCYCMODE,0xBF);     //Writing xBF to the register would set 1 to LWATT, LVAR, LVA, ZXSEL, FREQSEL to 1 except RSTREAD to 0.

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 4: Set the number of half-line cycles for line accumulation by writing to LINECYC(0x1C)

    Source code:

    write16(LINECYC,0x1C);

    Problem: Not sure this is the correct coding though...

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 5: Set the LENERGY bit, Mask[12] (0x18), to Logic 1

    Source code:

    write24(MASK,0xFFFFFF)     //if case of all the interrupts are needed, setting all the register to 1 instead

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 6: Set the test system for I_test, V_nom and unity power factor (calibrate watt and VA simultaneously and first).

    Problem: Do not understand the instruction above. Can I use the value of I_test and V_nom that were previously used at the step 0? Also, for unity power factor load, only resistive filament bulb can be used? Because I am using two loads together: resistive filament bulb and hair dryer, as load resistance can be altered using hair dryer (kind of convenient..., haha)

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 7: Read the FREQ(0x10) register if the line frequency is unknown.

    Source code:

    float freq;

    freq= 1/(read12(FREQ)*0.0000096);          //Derived from equa(62)

    Serial.print("Freq: ");     Serial.println(freq);

    From equa(62) pg 50

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 8: Reset the interrupt status register by reading RSTATUS (0x1A)

    Source code:

    getresetInterruptStatus();

    long getresetInterruptStatus(){

            return read20(RSTATUS);

    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 9: Read all 6 xWATTHR (0x01 to 0x03) energy register after the LENERGY interrupt and store the values.

         while(!(getInterruptStatus()&001000)){

             Serial.print("waiting");

        }

        

         while(!(getInterruptStatus()&001000)){

             Serial.print("waiting");

        }

        Serial.print("WATTHR: ");     Serial.println(read16(AWATTHR));

        delay(500);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Step 9a.: Calculate the values to be written to xWG registers according to the following equation:

    Since LINECYC is set to 0x1C, the decimal for 1C is 28. No. of phase selected is selected to be 1 as I am measuring 1 phase now.


    hence, xWG register is set to be: 0x003

    Source code:

      write16 (AWG,0x003);

    Problem: I am aware that the WATTHR_measured would increase in value with longer the time it measured. Then, what value should I substituted to equarion "xWG"?

    My result displayed from Serial Monitor so far using a light bulb and a hair dryer as load:

    --> load with a 100W light bulb and a medium speed hair dryer

    --> load with a 100W light bulb and max speed of hair dryer

    The WATTHR value in second case have visible higher value. Predicting the result is correct so far. Both values with increase as time increase.

    Sincerely thanks for the help.

    Regards,

    jianyee92

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////