Wednesday, March 30, 2011

Kevin's Week 9 Report- Part 2

Below are screenshots of the browsing section for the webpage.  To get data for multiple days, I just created a program to simulate random data in the range of 30-50 starting at Jan. 1, 2010.
Starts out in Year Selection- click on see months

Goes to select month- click see days

Goes to select day- select Jan. 2
Goes to select Hour- select 4AM

Goes to data for 4AM hour- click next button

Goes to data for 5AM hour

Tuesday, March 29, 2011

Ashley's Week 9 Report

This Week:  Andrew and I met a couple times to test the "wiznetping.c" program on this site: http://www.ermicro.com/blog/?p=1773.  We changed some of the pin definitions and settings so that it would match our circuit.  We tried to ping the IP address in the "cmd" terminal on my computer, but it kept saying that it was timing out.  We tried changing a few different things but kept getting the same message.  Later I noticed that there was output in my secureCRT terminal.  The output was similar to the output in the image titled "Displaying the Wiznet W5100 Initialization with Serial Terminal" on that website.  Basically everything printed was hardcoded and the important part was seeing that the lines such as "Reading GAR:  xxx.xxx.x.x" matched the value that we were setting it to and it was not. 

We met up on Sunday with Kevin to quickly try this test program again.  I wanted to unplug the max232 /rs232 connection to see if the data was getting lost when I tried to "ping" because it was being sent to the secureCRT terminal, but this was not the case.  We tried using some of the libraries written in C++ on the arduino website, but had even less luck with that.  We couldn't even get it to compile.  We thought that this was because we weren't using the actual arduino that should be connected to our ethernet board and missing some of the libraries that they "included" in their code. 

We decided just to communicate with Kevin's server program via RS232 just to make sure that things were still working since it had been awhile.  At first we had some issues, but resolved them and were able to send him values less than 255 (one byte).  We wanted to try to send him the RMS Voltage to make sure that he could get those values correctly from the chip, so we scaled this value accordingly.  When there was no power applied to the chip, the average RMS voltage was 72,000.  When power was applied, it read about 2,900,000.  Using the concept of y = mx + b, we subtracted 72,000 from the RMS voltage value that we read in, and then divided by 23,333 so that our average output was 120V when power was applied.  When power wasn't applied, the output should've read 0.  A few times it did read 0 or 1, but other times it was quite large.  We found that this issue was because the variables were unsigned.  I had to leave for work, so we decided to come back to this progress later.

Next Week:  Andrew and I plan on working on the RMS current callibration, as well as making any changes to our scaling of the RMS voltage now that he has added isolators to the board.  We will need to make sure things are still functioning correctly now that the circuit has been altered. 


-----------------------
Main Program
-----------------------

int main(void){
  setBitPortB(2); //ADE7763 SS line on PB2; Set to high.
 setBitPortB(1);
  InitSPI();
 ADE_Cal();
  usart_init();
  sei();


  while(1){
 
    while(!uart_buffer_empty()){
  
      char c = usart_getc();  
      if(c == '1'){
    //unsigned char bla = 6;
    //usart_putc(bla);
  
   printRegValues();      
      

      }
    }
 }
}
void printRegValues(void)
{
     char str1[25];
  char str2[25];
  char str3[25];
  char str4[25];
  char str5[25];

  uint32_t apparent;
 uint32_t active;
 int temperature;
 uint32_t vRMS;
 uint32_t wave;

   active = readActive(0x03);
   _delay_us(4);
   apparent = readApparent(0x06);
   _delay_us(4);
   vRMS = readVRMS(0x17);
   _delay_us(4);  
   temperature = readTemp();
   _delay_us(4);
   wave = readWave(0x01);
   _delay_us(4);

  //RMS voltage scaling
   uint32_t rms = vRMS - 72000;
   rms = rms/23333;

    usart_prints("\r---------------------------------\n");
       usart_prints("\r");
       usart_prints("The Active Energy is: ");
       sprintf(str1, "%ld\n",active);
       usart_prints(str1);
       usart_prints("\r");
       usart_prints("The Apparent Energy is: ");
       sprintf(str2, "%ld\n",apparent);
       usart_prints(str2);
    usart_prints("\r");
       usart_prints("The RMS Voltage is: ");
       sprintf(str3, "%ld\n",rms);
       usart_prints(str3);
    usart_prints("\r");
       usart_prints("The Temperature is: ");
       sprintf(str4, "%d\n",temperature);
       usart_prints(str4);
    usart_prints("\r");
       usart_prints("The Wave is: ");
       sprintf(str5, "%ld\n",wave);
       usart_prints(str5);
}

Andrew's Week 9 Progress Report

This week I continued to work with Ashley to callibrate the VRMS reading from the ADE7763.  I also began to work on the IRMS callibration.  First I determined the maximum current present in our circuit which should be no greater than a 60A spike.  Next I used this value times the shunt resistance (.2mOhm) to determine maximum signal level which is .12mV.  Now that the maximum signal level is determine using the ADE7763 datasheet we set the gain for channel 1 to 16 in the gain register since this is the largest gain available and does not push us over the maximum limit of 500mV. 
To verify the operation of the shunt resistor I built an inverting amplifier with gain of -100 using an LT1013 op amp.  Next I used the 200W lightbulb (known source) to examine the waveform at the output of the amplifier when the light is on and off.  Shown below are waveforms at the output of the amplifier.
Output with no load connected.




Output of amplifier with 200W lightbulb connected.



Waveform immediately after closing switch turning on the lightbulb.


Ashley and I also continued to work on the Ethernet trying to connect between the board and her computer using a crossover cable.  We were unsuccessful in all our attempts to "ping" the ethernet chip before the connection timed out.  Shown below is a picture of the overall circuit.


This week Ashley and I plan to continue callibrating the IRMS reading as well as the Active Energy.  Now that we have been able to callibrate RMS voltage we are feeling more confident about continuing to callibrate these more complicated measurements.

Kevin's Week 9 Report

This week I worked on redesigning the webpage and testing some communications with Andrew and Ashley.  In redesigning the webpage, I decided to do away with the drop down button list as I could not find a way to obtain current available year, month, day, and hour data to appear in the dropdown list when the user loaded the page.  I instead decided to make a setup where the user will click a “Browse” tab.  This page starts out in the yearly data selection.  It starts out with a list of all available years that have data.  Next to each year the user can select either to view data for the year or view the months available with data for that year.  If they select to view the data, a graph of yearly data will show up.  If they select to view the months available within that year, a list of all the months that have data appears.  These months have the same options as the year did.  This continues until we get to the hourly data page.  This page has a link to view the data.  When the user clicks data for that hour will be shown.  I have gotten this test webpage up and working over the previous days, however, I must have made a small change that I need to find, as right now it is not showing data for the year at the start, so I cannot move past that page.  I am going to get this up in the next day and post some screenshots of the website.  For the meantime, I posted the new code I have for the browser tab in the site below.

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
using MySql.Data.MySqlClient;

namespace EnergyViewHPM
{
    public partial class Browse : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Page.Title = "Browse - EnergyView HPM";

            if (Request.QueryString["Type"] != null)
            {
                string mode = Request.QueryString["Type"].ToString().ToLower();
                switch (mode)
                {
                    case "month":
                        butBack.Text = "Back to Years";
                        if (Request.QueryString["Year"] != null)
                        {
                            monthHandler(Request.QueryString["Year"].ToString());
                        }
                        else
                        {
                            Response.Redirect("/browse.aspx");
                        }
                        break;
                    case "day":
                        butBack.Text = "Back to Months";
                        if ((Request.QueryString["Year"] != null)
                            && (Request.QueryString["Month"] != null))
                        {
                            dayHandler(Request.QueryString["Year"].ToString(),
                                Request.QueryString["Month"].ToString());
                        }
                        else
                        {
                            Response.Redirect("/browse.aspx");
                        }
                        break;
                    case "hour":
                        butBack.Text = "Back to Days";
                        if ((Request.QueryString["Year"] != null)
                            && (Request.QueryString["Month"] != null)
                            && (Request.QueryString["Day"] != null))
                        {
                            hourHandler(Request.QueryString["Year"].ToString(),
                                Request.QueryString["Month"].ToString(),
                                Request.QueryString["Day"].ToString());
                        }
                        else
                        {
                            Response.Redirect("/browse.aspx");
                        }
                        break;
                    default:
                        Response.Redirect("/browse.aspx");
                        break;
                }
            }
            else
            {
                butBack.Visible = false;
                yearHandler();
            }
        }

        protected ArrayList dbQuery(string query)
        {
            ArrayList results = new ArrayList();
            MySqlConnection dbCon = new MySqlConnection(ConfigurationManager.ConnectionStrings["DataDB"].ToString());
            dbCon.Open();

            MySqlCommand dbCmd = new MySqlCommand(query, dbCon);
            MySqlDataReader dbDr = dbCmd.ExecuteReader();

            while (dbDr.Read())
            {
                results.Add(dbDr.GetDateTime(0));
            }

            dbCon.Close();
            return results;
        }

        protected string viewLinkConstruct(string destination, string year, string month,
            string day, string hour)
        {
            string result = "<a href='/" + destination + ".aspx";

            result += (year != null ? ("?Year=" + year) : "");
            result += (month != null ? ("&Month=" + month) : "");
            result += (day != null ? ("&Day=" + day) : "");
            result += (hour != null ? ("&Hour=" + hour) : "");

            result += "'>View " + destination + " Data</a>";

            return result;
        }

        protected string moreLinkConstruct(string type, string year, string month, string day)
        {
            string result = "<a href='/browse.aspx?Type=" + type;

            result += (year != null ? ("&Year=" + year) : "");
            result += (month != null ? ("&Month=" + month) : "");
            result += (day != null ? ("&Day=" + day) : "");

            result += "'>See " + type + "s</a>";
           
            return result;
        }

        protected void yearHandler()
        {
            string query = "SELECT timest FROM day_data GROUP BY YEAR(timest)";
            ArrayList results = dbQuery(query);

            string elements = "";
            foreach (DateTime dt in results)
            {
                elements += "<li>" + dt.Year + "&nbsp;-&nbsp;"
                    + viewLinkConstruct("Year", dt.Year.ToString(), null, null, null)
                    + "&nbsp;-&nbsp;" + moreLinkConstruct("Month", dt.Year.ToString(), null, null)
                    + "</li>";
            }

            lblTitle.Text = "Select Year";
            lblElements.Text = elements;
        }

        protected void monthHandler(string year)
        {
            string query = "SELECT timest FROM day_data WHERE YEAR(timest)='" + year + "' GROUP BY MONTH(timest)";
            ArrayList results = dbQuery(query);

            string elements = "";
            foreach (DateTime dt in results)
            {
                elements += "<li>" + dt.ToString("MMM, yyyy") + "&nbsp;-&nbsp;"
                    + viewLinkConstruct("Month", dt.Year.ToString(), dt.Month.ToString(), null, null)
                    + "&nbsp;-&nbsp;" + moreLinkConstruct("Day", dt.Year.ToString(), dt.Month.ToString(), null)
                    + "</li>";
            }

            lblTitle.Text = "Select Month";
            lblElements.Text = elements;
        }

        protected void dayHandler(string year, string month)
        {
            string query = "SELECT timest FROM day_data WHERE YEAR(timest)='" + year
                + "' AND MONTH(timest)='" + month + "' GROUP BY DAY(timest)";
            ArrayList results = dbQuery(query);

            string elements = "";
            foreach (DateTime dt in results)
            {
                elements += "<li>" + dt.ToString("ddd, MMM dd, yyyy") + "&nbsp;-&nbsp;"
                    + viewLinkConstruct("Day", dt.Year.ToString(), dt.Month.ToString(), dt.Day.ToString(), null)
                    + "&nbsp;-&nbsp;" + moreLinkConstruct("Hour", dt.Year.ToString(), dt.Month.ToString(), dt.Day.ToString())
                    + "</li>";
            }

            lblTitle.Text = "Select Day";
            lblElements.Text = elements;
        }

        protected void hourHandler(string year, string month, string day)
        {
            string query = "SELECT timest FROM minute_data WHERE YEAR(timest)='" + year
                + "' AND MONTH(timest)='" + month + "' AND DAY(timest)='" + day
                + "' GROUP BY HOUR(timest)";
            ArrayList results = dbQuery(query);

            string elements = "";
            foreach (DateTime dt in results)
            {
                elements += "<li>" + dt.ToString("ddd, MMM dd, yyyy hh tt") + "&nbsp;-&nbsp;"
                    + viewLinkConstruct("Hour", dt.Year.ToString(), dt.Month.ToString(), dt.Day.ToString(), dt.Hour.ToString())
                    + "</li>";
            }

            lblTitle.Text = "Select Hour";
            lblElements.Text = elements;
        }

        protected void butBack_Click(object sender, EventArgs e)
        {
            string addon = "";
            switch(Request.QueryString["Type"].ToString().ToLower())
            {
                case "month":
                    break;
                case "day":
                    addon = "?Type=Month&Year=" + Request.QueryString["Year"];
                    break;
                case "hour":
                    addon = "?Type=Day&Year=" + Request.QueryString["Year"] + "&Month="
                        + Request.QueryString["Month"];
                    break;
            }
            Response.Redirect("/Browse.aspx" + addon);
        }
    }
}


Over the weekend and this morning, Andrew, Ashley, and I met up to work on communications for the system.  We were able to calibrate the RMS Voltage on the ADE7763 chip and output the right value of 120V.  Using our test serial connection, we were able to read the correct value from the ATMega328P.  We worked on trying to initialize the W5100 chip using a test program from http://www.ermicro.com/blog/?p=1773 to ping the pc for communication.  However, it was not getting the correct address information.  Over the next week I plan to finish up the website and work on helping to calibrate the W5100 and ADE7763 f

Tuesday, March 22, 2011

Andrew Week 8 Progress Report

Over the past two weeks Ashley and I have been working on callibrating the ADE7763 chip's measurement for RMS voltage.  We began by studying the datasheet's steps for callibration.  Initially we had minimal success but after correcting some code we are now obtaining stable consistent voltage measurements.  Ashley and I plan to continue working with the RMS voltage measurements on Thursday.

To help our callibration efforts I built an accurate current source using a 200W lightbulb.  By using an industry built clamp meter I have verified that the source draws 1.79amps.  This source will help us in our callibration efforts of the rms current using the accurate source method described in the ADE7763 datasheet.

Finally I began constructing the ethernet portion of the circuit.  I used the Ethernet Arduino shield which utilizes the W5100 chip.  To provide the required voltages I also had to install a 3.3voltage regulator (MCP1827S-3302E.)  Also in my design I am not using the regular Arduino device so with the help of Prof. Curry I matched schematics of the Arduino Ethernet Shield and regular arduino to determine necessary connections and any compatability issues.  Shown below is a schematic of the circuit as designed thus far.


Currently I am leaving the SPI portion of the ethernet disconnected because connecting it without modifying the micro controller code will cause an error in communication between the ADE7763 and Atmega 328P.  The ethernet can be connected if the chip selects for both the W5100 and the SD Card located on the board are set high.  So far these two pins are designed to be PB1 and PB0.  Shown below is a picture of the circuit as currently constructed.




Before Thursday I plan to use a signal transformer so that we can very the AC voltage to determine how accurate our VRMS measurements are over a wide range of values.  I also plan to begin looking into the power supply design because three seperate sources will be needed.  These sources will mainly supply a voltage of 5V except the ethernet board which requires 3.3V.  The three sources are required because of isolation between the SPI bus and the ADE7763.  There also needs to be seperate analog and digital sources provided to the ADE7763 for higher accuracy and less noise.  The schematic has been updated to reflect these changes.  There are three different ground symbols.  One looks like an upside down T, one is the standard parallel line upside down cone and the third is an upside down arrow.

Ashley's Week 8 (Part 2) Report

This Week:  Since our last visit, Andrew and I were able to get in contact with a gentleman who has done some programming with the ADE7763.  He gave us some insight on the steps that need to be taken to calibrate the ADE7763 for the RMS stuff.  That is one of the calibrations that needs to be done for our energy measurements.  Andrew and I met up Saturday and began writing the subroutine containing all of these calibrations and you can see this below under ADE_Cal().  After doing this calibration, things weren't looking correct, so I began wondering if the registers were getting set correctly.  I realized that I was sending the wrong type of variable to the read/write functions so corrected that and still had problems.  I did a test procedure in the main loop where I set the mode register to 0b0100001100011111 and then read the value of the mode register.  I was only reading 0b0000000000011111.  I was able to write to and read from 8 bit registers though so I knew it was a problem for registers with that extra byte or two.

We met back up on Tuesday (today) to solve our register setting problems.  We checked the clock and MISO/MOSI lines one the oscilloscope so saw that data was transferring correctly.  After printing off the high and low bytes individually from the mode register, we saw that both bytes were correct and this lead to the discovery of my line of code appending the two bytes together was wrong.  I was accidentally shifting 8 to the right by the value of the high byte as opposed to shifting the high byte over 8 bits like I needed.  Finally we were able to successfully set multibyte registers and read their values correctly.

We went back to our RMS calibration work.  We made sure we had the calibration how we wanted it and then began reading the RMS voltage.  Things seem to be looking up for us.  Below you will see some of our output readings from the computer terminal.  The first few values are from when the board was powered.. as you can see the RMS Voltage is around 1,000,000.  When we removed power, the RMS Volatage was around 10,000.

We haven't done the other calibration steps for energy yet, but it is at least comforting to see that the Active and Apparent energy values read 0 when no power is applied.

Next Week:  We will continue working on the other calibration steps and finish up the RMS calibration by fixing any offset and scaling the values (i.e. scaling the RMS voltage down to 120V).  I will begin working with Kevin today to go over our ethernet communication and hopefully have some test code ready for next week.

-----------------------------------------------
SecureCRT Output
-----------------------------------------------

---------------------------------
The Active Energy is: 1507326
The Apparent Energy is: 29
The RMS Voltage is: 1075537
---------------------------------
The Active Energy is: 0
The Apparent Energy is: 26
The RMS Voltage is: 1078285
---------------------------------
The Active Energy is: 1507326
The Apparent Energy is: 28
The RMS Voltage is: 1079095
---------------------------------
The Active Energy is: 0
The Apparent Energy is: 1
The RMS Voltage is: 11263
---------------------------------
The Active Energy is: 0
The Apparent Energy is: 0
The RMS Voltage is: 11008
---------------------------------
The Active Energy is: 0
The Apparent Energy is: 0
The RMS Voltage is: 10993
---------------------------------



-----------------------------------------------
ADE CODE
-----------------------------------------------

int main(void){

  setBitPortB(2); //ADE7763 SS line on PB2; Set to high.
  InitSPI();
ADE_Cal();


  uint32_t apparent;
uint32_t active;
int temperature;
uint32_t vRMS;
uint32_t wave;

  usart_init();
  sei();

  while(1){
   char str1[25];
char str2[25];
char str3[25];
char str4[25];
char str5[25];

   while(!uart_buffer_empty()){

   char c = usart_getc();

   if(c == 'p'){

active = readActive(0x03);
_delay_us(4);
apparent = readApparent(0x06);
_delay_us(4);
vRMS = readVRMS(0x17);
_delay_us(4);
temperature = readTemp();
_delay_us(4);
wave = readWave(0x01);
_delay_us(4);
usart_prints("\r---------------------------------\n");
     usart_prints("\r");
     usart_prints("The Active Energy is: ");
     sprintf(str1, "%ld\n",active);
     usart_prints(str1);

     usart_prints("\r");
     usart_prints("The Apparent Energy is: ");
     sprintf(str2, "%ld\n",apparent);
     usart_prints(str2);

usart_prints("\r");
     usart_prints("The RMS Voltage is: ");
     sprintf(str3, "%ld\n",vRMS);
     usart_prints(str3);

usart_prints("\r");
     usart_prints("The Temperature is: ");
     sprintf(str4, "%d\n",temperature);
     usart_prints(str4);

usart_prints("\r");
     usart_prints("The Wave is: ");
     sprintf(str5, "%ld\n",wave);
     usart_prints(str5);


//usart_putc(temp);

   }
   }
}
}


void setBitPortB(int bit)  //sets bit to 1
{
PORTB = PINB | (1<<bit);
}

void clearBitPortB(int bit)  //sets bit to 0
{
PORTB = PINB & (~(1<<bit));
}



//SPI STUFF


void InitSPI(void)
{
   DDRB = (1<<PB2)|(1<<PB3) | (1<<PB5);  // Set MOSI (PB3) , SCK (PB5), and SS(PB2) output

   /* Enable SPI, Master, set clock rate fck/8 */
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPHA);
   SPSR = (1<<SPI2X);
   //idle clock is low. want CPOL = 0, CPHA = 1;
}

void write24bits(unsigned int addr,unsigned char data1, unsigned char data2, unsigned char data3)
{
   // Activate the CS pin
   clearBitPortB(2);

   unsigned int communication = ADE7763_WRITE_OPCODE | addr;

   // Start ADE7763 Communication Write transmission
   SPDR = communication; //ADE7763_WRITE_OPCODE;

// Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));


   // Start Data High Bytes transmission
   SPDR = data1;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));

  // Start Data Middle Bytes transmission
   SPDR = data2;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));

   // Start Data Low Bytes transmission
   SPDR = data3;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));

   // CS pin is not active
   setBitPortB(2);
}

void write16bits(unsigned int addr,unsigned char data1, unsigned char data2)
{
   // Activate the CS pin
   clearBitPortB(2);
_delay_us(1);

   unsigned int communication = ADE7763_WRITE_OPCODE | addr;

   // Start ADE7763 Communication Write transmission
   SPDR = communication; //ADE7763_WRITE_OPCODE;

// Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));
//_delay_ms(4);


   // Start Data High Bytes transmission
   SPDR = data1;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));
//_delay_ms(4);

   // Start Data Low Bytes transmission
   SPDR = data2;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));
//_delay_ms(4);

   // CS pin is not active
   setBitPortB(2);
}


void write8bits(unsigned int addr,unsigned char data)
{
   // Activate the CS pin
   clearBitPortB(2);

   unsigned int communication = ADE7763_WRITE_OPCODE | addr;

   // Start ADE7763 Communication Write transmission
   SPDR = communication; //ADE7763_WRITE_OPCODE;

// Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));


   // Start Data High Bytes transmission
   SPDR = data;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));

   // CS pin is not active
   setBitPortB(2);
}


uint32_t read24bit(unsigned int addr)
{


   // Activate the CS pin
   clearBitPortB(2);

   unsigned int communication = ADE7763_READ_OPCODE | addr;

   // Start ADE7763 Communication Read transmission
   SPDR = communication; //ADE7763_READ_OPCODE;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));
  _delay_us(4);

SPDR = 0b00000000;
   while(!(SPSR & (1<<SPIF)));
   uint32_t v1 = SPDR;
   _delay_us(1);

   SPDR = 0b00000000;
  while(!(SPSR & (1<<SPIF)));
   uint32_t v2 = SPDR;
   _delay_us(1);

   SPDR = 0b00000000;
   while(!(SPSR & (1<<SPIF)));
   uint32_t v3 = SPDR;
   _delay_us(1);

setBitPortB(2);//SPI_PORT |= (1<<SPI_CS);
   uint32_t value = (v1<<16)|(v2<<8)|v3;
 

   return value;
}

uint32_t read16bit(unsigned int addr)
{


   // Activate the CS pin
   clearBitPortB(2);
_delay_us(1);

   unsigned int communication = ADE7763_READ_OPCODE | addr;

   // Start ADE7763 Communication Read transmission
   SPDR = communication; //ADE7763_READ_OPCODE;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));

SPDR = 0b00000000;
   while(!(SPSR & (1<<SPIF)));
   uint32_t v1 = SPDR;
   //_delay_us(1);

   SPDR = 0b00000000;
  while(!(SPSR & (1<<SPIF)));
   uint32_t v2 = SPDR;

setBitPortB(2);
   uint32_t value = (v1<<8)|v2;

   return value;
}



int read8bit(unsigned int addr)
{
   // Activate the CS pin
   clearBitPortB(2); //SPI_PORT &= ~(1<<SPI_CS);

   unsigned int communication = ADE7763_READ_OPCODE | addr;

   // Start ADE7763 Communication Read transmission
   SPDR = communication; //ADE7763_READ_OPCODE;

   // Wait for transmission complete
   while(!(SPSR & (1<<SPIF)));
 
   _delay_us(4);

   SPDR = 0b00000000;
   while(!(SPSR & (1<<SPIF)));
   int temp = SPDR;
   _delay_us(1);

setBitPortB(2);//SPI_PORT |= (1<<SPI_CS);

return temp;
}


uint32_t readActive(unsigned int addr){

//signed two's complement -- 6 digits

//add set up / calibration steps
//ADE_Config();

uint32_t active = read24bit(addr);

//least sig to most sig digit
uint32_t d1 =   active & (0b000000000000000000001111);
uint32_t d2 = ((active & (0b000000000000000011110000))>>4)*10;
uint32_t d3 = ((active & (0b000000000000111100000000))>>8)*100;
uint32_t d4 = ((active & (0b000000001111000000000000))>>12)*1000;
uint32_t d5 = ((active & (0b000011110000000000000000))>>16)*10000;
uint32_t d6 = ((active & (0b111100000000000000000000))>>20)*100000;

uint32_t act = d6|d5|d4|d3|d2|d1;

return act;

}

uint32_t readVRMS(unsigned int addr){

//unsigned

//add set up / calibration steps

uint32_t vrms = read24bit(addr);

return vrms;

}

uint32_t readApparent(unsigned int addr){

//unsigned

//add set up / calibration steps

uint32_t apparent = read24bit(addr);

return apparent;

}


int readTemp(void)
{

int temp = read8bit(0x26);
int thi = (temp>>4)&0b00001111;
int tlo = (temp&0b00001111);

int temperature = thi*10 + tlo;

return temperature;

}


uint32_t readWave(unsigned int addr)
{

uint32_t wave = read24bit(addr);

uint32_t d1 =   wave & (0b000000000000000000001111);
uint32_t d2 = ((wave & (0b000000000000000011110000))>>4)*10;
uint32_t d3 = ((wave & (0b000000000000111100000000))>>8)*100;
uint32_t d4 = ((wave & (0b000000001111000000000000))>>12)*1000;
uint32_t d5 = ((wave & (0b000011110000000000000000))>>16)*10000;
uint32_t d6 = ((wave & (0b111100000000000000000000))>>20)*100000;

uint32_t w = d6|d5|d4|d3|d2|d1;
return w;

}

void ADE_Cal(void)
{
//RMS Calibration
write8bits(0x0F, 0b00000100);  //sets voltage and current gain to 1.
write16bits(0x09, 0b01100000, 0b00101000); //set bits 3 and 5 to 1. (temp conversion and disabling sag detection) & 13/14 to 1 for voltage
write8bits(0x13, 0xB0); //sets watt divider to 176
write8bits(0x0E, 0x0A);  //want -10 offset
write16bits(0x14, 0x00, 0x01);  // set to 1
write16bits(0x19, 0x00, 0x00);
}