Post Go back to editing

ADE9000 THD

I'm testing the ADE9000 using the evaluation board.  I'm connecting to the board using an Arduino.  I have successfully retrieved waveform data, 10cycle RMS voltage, 1/2 cycle RMS voltage.  I don't get a valid value for AVTHD, BVTHD or CVTHD.  I'm connecting to a 120V single phase circuit on phase A, B and C.  I found the app note AN-1483 to get THD.  I believe I'm following the steps correctly.  So far it doesn't matter what I do, values returned are 400% if the voltage is applied and 0 if there is no voltage. 

I found the answer to set ENERGY_PWR_EN, this value is set to EP_CFG 0x0011

Is there something else that I need to do?

Thanks

Parents
  • Hi swoods,

      What is the frequency of your input signal? Have you configured ACCMODE register? Please calculate THD with another equation in ADE9000 user guide 1098, which uses total rms and fundamental rms. Check the calculated value either. Thank you very much.

    Best regards,

    Gary

  • Thanks, It seems to be working now.  I found two issues,  the ACCMODE register was not set at 60Hz, the note in the ADE9000API.h said "/*60Hz operation, 3P4W Wye configuration, signed accumulation*/"  but the bits were set for 50 Hz when I checked the manual.  After setting to 60Hz, it still didn't give me correct THD or Fundamental values.

    In the Fundamental Measurements section of the ADE9000 guide 1098 there is a sentence "The SELFREQ must be made prior to writing the RUN register to 1."  So after loading the default configuration in the ADE9000API, I set the RUN to 0, changed the ACCMODE to 0x0100 (60 Hz) then set RUN back to 1. 

    The Fundamental voltage matched the RMS voltage and VTHD is giving me values that look correct for an office outlet.

    Thanks

  • Hi swoods

    i am not getting actual power register values, can you post your arduino sketch?  

Reply Children
  • I don't have a CT connected yet, so I don't know if the Power part is working.  Below is the code that I got voltage THD and 1/2 cycle RMS voltage to work.  I'm also working on retrieving the temperature value from the chip.

    </


    #include <SPI.h>
    #include  <ADE9000RegMap.h>
    #include <ADE9000API.h>

    /*Basic initializations*/
    ADE9000Class ade9000;
    #define SPI_SPEED 5000000     //SPI Speed
    #define CS_PIN 0 //8-->Arduino Zero. 16-->ESP8266 //*changed to 0 for mkr1000
    #define ADE9000_RESET_PIN 5 //Reset Pin on HW
    #define PM_1 4              //PM1 Pin: 4-->Arduino Zero. 15-->ESP8266

    /*Structure decleration */
    struct ActivePowerRegs powerRegs;     // Declare powerRegs of type ActivePowerRegs to store Active Power Register data
    struct CurrentRMSRegs curntRMSRegs;   //Current RMS
    struct VoltageRMSRegs vltgRMSRegs;    //Voltage RMS
    struct VoltageTHDRegs voltageTHDRegsnValues; //Voltage THD
    struct ResampledWfbData resampledData; // Resampled Data
    struct TemperatureRegnValue temperatureRegsnValues;

    /*Function Decleration*/
    void readRegisterData(void);
    void readResampledData(void);
    void resetADE9000(void);

    double AVRMS1012 =0;
    double AVRMS1 =0;
    double BVRMS1 =0;
    double CVRMS1 =0;
    double AVTHD=0;
    int second =1000;
    int second_60=60000;
    double temp_offset=0;
    double temp_gain=0;
    double temp_f=0;
    unsigned long PrevMill=0;
    unsigned long PrevMill_60=0;
    void setup()
    {
      Serial.begin(115200);
      pinMode(PM_1, OUTPUT);    //Set PM1 pin as output
      digitalWrite(PM_1, LOW);   //Set PM1 select pin low for PSM0 mode
      pinMode(ADE9000_RESET_PIN, OUTPUT);
      digitalWrite(ADE9000_RESET_PIN, HIGH);
      void resetADE9000();
      delay(1000);
      ade9000.SPI_Init(SPI_SPEED,CS_PIN); //Initialize SPI
      ade9000.SetupADE9000();             //Initialize ADE9000 registers according to values in ADE9000API.h

      ade9000.SPI_Write_16(ADDR_RUN,0x0);
      Serial.print("RUN Register: ");
      Serial.println(ade9000.SPI_Read_16(ADDR_RUN),BIN);
     
     
    Serial.print("ACCMODE");
    Serial.println(ade9000.SPI_Read_16(ADDR_ACCMODE),BIN); //set to 60hz and restart
    ade9000.SPI_Write_16(ADDR_ACCMODE,0x0100);
    Serial.print("ACCMODE");
    Serial.println(ade9000.SPI_Read_16(ADDR_ACCMODE),BIN);

    ade9000.SPI_Write_16(ADDR_RUN,0x1);  // Turn on DSP
      Serial.print("RUN Register: ");
      Serial.println(ade9000.SPI_Read_16(ADDR_RUN),BIN);

      //ade9000.SPI_Write_16(ADDR_RUN,0x1); //Set RUN=1 to turn on DSP. Uncomment if SetupADE9000 function is not used
     // Serial.print("RUN Register: ");
    //  Serial.println(ade9000.SPI_Read_16(ADDR_RUN),HEX);
    //ADE9000.SPI_Write_32(uint16_t Address , uint32_t Data );
     ade9000.SPI_Write_32(ADDR_AVGAIN,0xA71775);
     Serial.print("AVGAIN: ");
    Serial.println(ade9000.SPI_Read_32(ADDR_AVGAIN),HEX); // AVGAIN
    Serial.print("ADDR_RUN: ");
    Serial.println(ade9000.SPI_Read_16(ADDR_RUN),BIN); // AVGAIN
    //Serial.print("WFB_CFG:");
    //Serial.println(ade9000.SPI_Read_32(ADDR_WFB_CFG),HEX);
    //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x3F0);
    Serial.println("Energy Power Reg");
    Serial.println(ade9000.SPI_Read_16(ADDR_EP_CFG),HEX);  //Energy Power REG
    Serial.println("Temp Config Reg");
    Serial.println(ade9000.SPI_Read_16(ADDR_TEMP_CFG),HEX);  //Temp config Reg
    Serial.print("TempTrim: ");
    Serial.println(ade9000.SPI_Read_32(ADDR_TEMP_TRIM),BIN);
    temp_offset=ade9000.SPI_Read_32(ADDR_TEMP_TRIM)>>16;
    temp_offset=temp_offset/32;
    temp_gain=ade9000.SPI_Read_32(ADDR_TEMP_TRIM)&0x0000FFFF;
    temp_gain=temp_gain/65536;
    Serial.print("Temp_Offset: ");
    Serial.println(temp_offset,BIN);
    Serial.print("Temp_Gain: ");
    Serial.println(temp_gain,BIN);
    Serial.print("ACCMODE");
    Serial.println(ade9000.SPI_Read_16(ADDR_ACCMODE),BIN);
    ade9000.SPI_Write_16(ADDR_ACCMODE,0x0100);
    Serial.print("ACCMODE");
    Serial.println(ade9000.SPI_Read_16(ADDR_ACCMODE),BIN);

    }

    void loop() {
      unsigned long currentmills = millis();
      if ((unsigned long)(currentmills - PrevMill) >= second)
      {
        PrevMill=currentmills;
       // ade9000.SPI_Write_16(ADDR_WFB_CFG,0x3F0);
        //delay(2000);
         readRegisterData();
         //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x1000);
      }
      if ((unsigned long)(currentmills -PrevMill_60) >=second_60)
      {
        PrevMill_60=currentmills;

        //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x1000);
      //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x3F0);
     // delay(100);
         //readResampledData();
      }
     
     // delay(1000);
    }

    void readRegisterData()
    {
     /*Read and Print Specific Register using ADE9000 SPI Library */
    //  Serial.print("AIRMS: ");
    //  Serial.println(ade9000.SPI_Read_32(ADDR_AIRMS),HEX); // AIRMS
    //AVRMSONE
    /*
     * Phase A current fast rms½ calculation, one cycle rms updated every half cycle.
     */

     AVRMS1=(ade9000.SPI_Read_32(ADDR_AVRMS));//*1.1/100000;
        Serial.print("A_VRMSONE: ");
      //Serial.println((ade9000.SPI_Read_32(ADDR_AVRMSONE)),HEX); // A VRMS ONE  ADDR_AVFRMS
      AVRMS1=AVRMS1/100000;
      Serial.println(AVRMS1,DEC); // A VRMS ONE
     
    /*
     *
     *
      BVRMS1=(ade9000.SPI_Read_32(ADDR_BVRMSONE)); // *1.1/100000;
        Serial.print("B_VRMSONE: ");
      //Serial.println((ade9000.SPI_Read_32(ADDR_BVRMSONE)),HEX); // B VRMS ONE
      BVRMS1=BVRMS1/100000;
      Serial.println(BVRMS1,DEC); // B VRMS ONE

      CVRMS1=(ade9000.SPI_Read_32(ADDR_CVRMSONE)); // *1.1/100000;
        Serial.print("C_VRMSONE: ");
      //Serial.println((ade9000.SPI_Read_32(ADDR_CVRMSONE)),HEX); // C VRMS ONE
      CVRMS1=CVRMS1/100000;
      Serial.println(CVRMS1,DEC); // C VRMS ONE
    */
     
     AVRMS1012=(ade9000.SPI_Read_32(ADDR_AVRMS1012));
     Serial.print("AVRM1012: ");
      AVRMS1012=AVRMS1012/100000;
      Serial.println(AVRMS1012,DEC); // AVRMS1012
    // ADDR_AVTHD

    Serial.print("ADDR_AVFRMS: ");
    //Serial.println(ade9000.SPI_Read_32(ADDR_AVFRMS),DEC);
    AVRMS1012=ade9000.SPI_Read_32(ADDR_AVFRMS);
    AVRMS1012=AVRMS1012/100000;
    Serial.println(AVRMS1012,DEC);
    /*
    Serial.print("Temp Result: ");
    Serial.println(ade9000.SPI_Read_16(ADDR_TEMP_RSLT),DEC);
    Serial.print("Temp_Gain: ");
    Serial.println(temp_gain,DEC);
    Serial.print("Temp_OFFSET: ");
    Serial.println(temp_offset);
    */

    //Serial.print("Temp_CFG: ");
    //Serial.println(ade9000.SPI_Read_16(ADDR_TEMP_CFG),BIN);
    Serial.print("ADDR_MASK0: ");
    Serial.println(ade9000.SPI_Read_32(ADDR_MASK0),BIN);

    temp_f=ade9000.SPI_Read_16(ADDR_TEMP_RSLT);
    temp_f=temp_f*(-temp_gain)+(temp_offset);
    temp_f=(float)temp_f*(9.0/5.0)+32.0;
    //temp_f=(float)temp_f +32.0;
    Serial.print("Temp F:");
    Serial.println(temp_f,DEC);

    ade9000.ReadTempRegnValue(&temperatureRegsnValues);
    Serial.print("TEMPREGNVALUE: ");       
    Serial.println(temperatureRegsnValues.Temperature); //Print AVRMS register

    ade9000.SPI_Write_16(ADDR_TEMP_CFG,0x000D);  //start new temp measurement D=256 smpls, need to check Status0[25] to see if temp_rdy set for more than one smpl
    //Serial.print("Temp_CFG: ");
    //Serial.println(ade9000.SPI_Read_16(ADDR_TEMP_CFG),BIN);
    Serial.print("ADDR_STATUS0: ");
    Serial.println(ade9000.SPI_Read_32(ADDR_STATUS0),BIN);


    //Serial.println("Energy Power Reg");
    //Serial.println(ade9000.SPI_Read_16(ADDR_EP_CFG),HEX);  //Energy Power REG

     //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x1000);
      //ade9000.SPI_Write_16(ADDR_WFB_CFG,0x3F0);
      //delay(100); //approximate time to fill the waveform buffer with 4 line cycles
    //Serial.print("WFB_CFG:");
    //Serial.println(ade9000.SPI_Read_16(ADDR_WFB_CFG),HEX);
    AVTHD=(ade9000.SPI_Read_32(ADDR_AVTHD))*pow(2,-27)*100;
    //ADDR_VPEAK//ADDR_AVTHD
    Serial.print("AVTHD:     ");
      //AVTHD=AVTHD*pow(2,-27)*100;
      Serial.println(AVTHD); // ADDR_AVTHD

    /*
      AVTHD=(ade9000.SPI_Read_32(ADDR_BVTHD))*pow(2,-27)*100;
      Serial.print("BVTHD:     ");
      Serial.println(AVTHD); // ADDR_AVTHD

      AVTHD=(ade9000.SPI_Read_32(ADDR_CVTHD))*pow(2,-27)*100;
      Serial.print("CVTHD:     ");
      Serial.println(AVTHD); // ADDR_AVTHD

      */

    //AVRMS
    /*-Phase A voltage fast 10 cycle rms/12 cycle rms calculation. The calculation is
     *performed over 10 cycles if SELFREQ = 0 for a 50 Hz network or over 12 cycles if
     *SELFREQ = 1 for a 60 Hz network, in the ACCMODE register.
     */

     /*
      * AVRMSONEOS
      * Phase A voltage rms offset for the fast rms½ AVRMSONE calculation.
      */
     /*Read and Print RMS & WATT Register using ADE9000 Read Library*/
     //struct VoltageTHDRegs voltageTHDRegsnValues; //Voltage THD
     //struct VoltageRMSRegs vltgRMSRegs;    //Voltage RMS
     
     ade9000.ReadVoltageTHDRegsnValues(&voltageTHDRegsnValues);
      Serial.print("ATHDREG:");       
      Serial.println(voltageTHDRegsnValues.VoltageTHDValue_A); //Print AVRMS register
     
     // ade9000.ReadVoltageRMSRegs(&vltgRMSRegs);    //Template to read Power registers from ADE9000 and store data in Arduino MCU
    //  ade9000.ReadActivePowerRegs(&powerRegs);
    //  Serial.print("AVRMS:");
    //  AVRMS1012=vltgRMSRegs.VoltageRMSReg_A;
      //AVRMS1012=(AVRMS1012*1.1)/100000;  
    //  AVRMS1012=(AVRMS1012);  
    //  Serial.println(AVRMS1012); //Print AVRMS register
     // delay(100);
    //  Serial.print("BVRMS:");       
    //  Serial.println(powerRegs.VoltageRMSReg_B); //Print AWATT register
    //  delay(100);
    //  Serial.print("CVRMS:");       
    //  Serial.println(powerRegs.VoltageRMSReg_C); //Print AWATT register
    }

    void readResampledData()
    {
      uint32_t temp;
    /*Read and Print Resampled data*/
      /*Start the Resampling engine to acquire 4 cycles of resampled data*/
      ade9000.SPI_Write_16(ADDR_WFB_CFG,0x1000);
      ade9000.SPI_Write_16(ADDR_WFB_CFG,0x1010);
      delay(100); //approximate time to fill the waveform buffer with 4 line cycles 
      /*Read Resampled data into Arduino Memory*/
      ade9000.SPI_Burst_Read_Resampled_Wfb(0x800,WFB_ELEMENT_ARRAY_SIZE,&resampledData);   // Burst read function
     
      for(temp=0;temp<WFB_ELEMENT_ARRAY_SIZE;temp++)
        {
          Serial.print("VA: ");
          Serial.println(resampledData.VA_Resampled[temp],DEC);
          //Serial.print("IA: ");
         // Serial.println(resampledData.IA_Resampled[temp],HEX);
         // Serial.print("VB: ");
         // Serial.println(resampledData.VB_Resampled[temp],HEX);
        //  Serial.print("IB: ");
        //  Serial.println(resampledData.IB_Resampled[temp],HEX);
        //  Serial.print("VC: ");
       //   Serial.println(resampledData.VC_Resampled[temp],HEX);
        //  Serial.print("IC: ");
       //   Serial.println(resampledData.IC_Resampled[temp],HEX);
       //   Serial.print("IN: ");
       //   Serial.println(resampledData.IN_Resampled[temp],HEX);
       }

    }

    void resetADE9000(void)
    {
     digitalWrite(ADE9000_RESET_PIN, LOW);
     delay(50);
     digitalWrite(ADE9000_RESET_PIN, HIGH);
     delay(1000);
     Serial.println("Reset Done");
    }

    >

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.