Tuesday, March 22, 2011

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);
}

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home