Tuesday, March 15, 2011

Ashley's Week 8 Report

This Week: I wrote the program that reads the apparent power and active power registers as seen below. I made read and write subroutines to access each size of register (1 byte, 2 byte, 3 byte). I also created readActive, readApparent, readTemp and readVRMS subroutines that read the corresponding register, converting it if necessary from Two's Compliment, and passing the value to wherever the subroutine was called. Andrew and I met up this past Saturday to test out this program and try to figure out how to calibrate and configure the registers before reading the active and apparent energies as well as the rms voltage. We were having difficulty understanding what all needed to be done and didn't have much luck. The raw values being read from the registers were not consistent--they seemed to fluctuate a bit. Since our meeting, I have read back through the ADE7763 datasheet and have begun to understand the calibration process a bit better. To read the Active Energy, one must follow this sequence of events: Watt Gain Calibration --> Watt Offset Calibration --> Phase Calibration. To read the Apparent Energy, the sequence is: Watt/VA Gain Calibration --> RMS Calibration --> Watt Offset Calibration --> Phase Calibration. There are two ways off doing these calibrations: using a reference meter, or using an accurate source. We are thinking of using the reference meter approach. Before starting these calibrations, the CFDEN and CFNUM registers must be calibrated. Once these two registers are set, you can move on to the active and apparent energy calibrations. All of these calibrations have examples of how to do the calculations and the registers that will need to be set. This calibration will occur the next time Andrew and I meet.

I also spent a little bit of time looking at the ethernet communication. Below you can see a test program to communicate with a terminal on the computer via ethernet. I think the only changed that I may need to make to it are the IP / MAC addresses. I also purchased a simple RS232 to Ethernet adapter cable as a possible alternative if we cannot get the development board working. I haven't found much information on how it works, but from what I have seen, you send the data as if you are using RS232 communication and it converts it to LAN (ethernet) and vice versa. The cable is compatible with most routers that use the RJ45 ethernet port. I'm not sure whether this device will work or not, but figured it would be worth a shot to have on hand.

Next Week: I will continue to look through the calibration information for the ADE7763 until Andrew and I can meet again. When we meet, we will go step by step through the calibration process so that we can hopefully start getting the desired energy values. If necessary, we will contact the company to ask questions about the process. I will also get the ethernet development board to Andrew so that we can get it connected and test my program for communication on a terminal on my computer. That way I will know it's working and can meet up with Kevin to make sure he is able to read the data.

----------------------------------------------
ADE7763 Read Power Code
----------------------------------------------

int main(void){

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

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

                usart_init();
                sei();

                while(1){
                                char str1[25];
char str2[25];
char str3[25];
char str4[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);

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_putc(temp);

                                                }
                                }
}
}





//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,uint32_t 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 & 0b111111110000000000000000) >> 16;

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

                // Start Data Middle Bytes transmission
                SPDR = (data & 0b000000001111111100000000) >> 8;

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

                // Start Data Low Bytes transmission
                SPDR = data & 0b000000000000000011111111;

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

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

void write16bits(unsigned int addr,uint16_t 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 & 0xFF00) >> 8;

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

                // Start Data Low Bytes transmission
                SPDR = data & 0x00FF;

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

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


void write8bits(unsigned int addr,int 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 = (16<<v1)|(8<<v2)|v3;
 

                return value;
}

uint32_t read16bit(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);
               
setBitPortB(2);
                uint32_t value = (8<<v1)|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);
//data = SPDR;

                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

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)
{
write16bits(0x09, 0x2C);
int temp = read8bit(0x26);
int thi = (temp>>4)&0b00001111;
int tlo = (temp&0b00001111);
int temperature = thi*10 + tlo;

return temperature;

}
 
 
----------------------------------------------
ETHERNET CODE
----------------------------------------------
 
#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <util/delay.h>
 
#define BAUD_RATE 19200
// AVRJazz Mega168/328 SPI I/O
#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_CS   PORTB2
// Wiznet W5100 Op Code
#define WIZNET_WRITE_OPCODE 0xF0
#define WIZNET_READ_OPCODE 0x0F
// Wiznet W5100 Register Addresses
#define MR   0x0000   // Mode Register
#define GAR  0x0001   // Gateway Address: 0x0001 to 0x0004
#define SUBR 0x0005   // Subnet mask Address: 0x0005 to 0x0008
#define SAR  0x0009   // Source Hardware Address (MAC): 0x0009 to 0x000E
#define SIPR 0x000F   // Source IP Address: 0x000F to 0x0012
#define RMSR 0x001A   // RX Memory Size Register
#define TMSR 0x001B   // TX Memory Size Register
void uart_init(void)
{
  UBRR0H = (((F_CPU/BAUD_RATE)/16)-1)>>8;            // set baud rate
  UBRR0L = (((F_CPU/BAUD_RATE)/16)-1);
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);                             // enable Rx & Tx
  UCSR0C=  (1<<UCSZ01)|(1<<UCSZ00);            // config USART; 8N1
}
void uart_flush(void)
{
  unsigned char dummy;
  while (UCSR0A & (1<<RXC0)) dummy = UDR0;
}
int uart_putch(char ch,FILE *stream)
{
   if (ch == '\n')
    uart_putch('\r', stream);
   while (!(UCSR0A & (1<<UDRE0)));
   UDR0=ch;
   return 0;
}
int uart_getch(FILE *stream)
{
   unsigned char ch;
   while (!(UCSR0A & (1<<RXC0)));
   ch=UDR0;  
 
   /* Echo the Output Back to terminal */
   uart_putch(ch,stream);       
 
   return ch;
}
void ansi_cl(void)
{
  // ANSI clear screen: cl=\E[H\E[J
  putchar(27);
  putchar('[');
  putchar('H');
  putchar(27);
  putchar('[');
  putchar('J');
}
void ansi_me(void)
{
  // ANSI turn off all attribute: me=\E[0m
  putchar(27);
  putchar('[');
  putchar('0');
  putchar('m');
}
void SPI_Write(unsigned int addr,unsigned char data)
{
  // Activate the CS pin
  SPI_PORT &= ~(1<<SPI_CS);
  // Start Wiznet W5100 Write OpCode transmission
  SPDR = WIZNET_WRITE_OPCODE;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));
  // Start Wiznet W5100 Address High Bytes transmission
  SPDR = (addr & 0xFF00) >> 8;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));
  // Start Wiznet W5100 Address Low Bytes transmission
  SPDR = addr & 0x00FF;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));   
 
  // Start Data transmission
  SPDR = data;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));
  // CS pin is not active
  SPI_PORT |= (1<<SPI_CS);
}
unsigned char SPI_Read(unsigned int addr)
{
  // Activate the CS pin
  SPI_PORT &= ~(1<<SPI_CS);
  // Start Wiznet W5100 Read OpCode transmission
  SPDR = WIZNET_READ_OPCODE;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));
  // Start Wiznet W5100 Address High Bytes transmission
  SPDR = (addr & 0xFF00) >> 8;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));
  // Start Wiznet W5100 Address Low Bytes transmission
  SPDR = addr & 0x00FF;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));   
 
  // Send Dummy transmission for reading the data
  SPDR = 0x00;
  // Wait for transmission complete
  while(!(SPSR & (1<<SPIF)));  
 
  // CS pin is not active
  SPI_PORT |= (1<<SPI_CS);
  return(SPDR);
}
void W5100_Init(void)
{
  // Ethernet Setup
  unsigned char mac_addr[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
  unsigned char ip_addr[] = {192,168,2,10};
  unsigned char sub_mask[] = {255,255,255,0};
  unsigned char gtw_addr[] = {192,168,2,1};
  // Setting the Wiznet W5100 Mode Register: 0x0000
  SPI_Write(MR,0x80);            // MR = 0b10000000;
  _delay_ms(1);
  printf("Reading MR: %d\n\n",SPI_Read(MR));
  // Setting the Wiznet W5100 Gateway Address (GAR): 0x0001 to 0x0004
  printf("Setting Gateway Address %d.%d.%d.%d\n",gtw_addr[0],gtw_addr[1],\
          gtw_addr[2],gtw_addr[3]);
  SPI_Write(GAR + 0,gtw_addr[0]);
  SPI_Write(GAR + 1,gtw_addr[1]);
  SPI_Write(GAR + 2,gtw_addr[2]);
  SPI_Write(GAR + 3,gtw_addr[3]);
  _delay_ms(1);
  printf("Reading GAR: %d.%d.%d.%d\n\n",SPI_Read(GAR + 0),SPI_Read(GAR + 1),\
          SPI_Read(GAR + 2),SPI_Read(GAR + 3));
  // Setting the Wiznet W5100 Source Address Register (SAR): 0x0009 to 0x000E
  printf("Setting Source Address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",mac_addr[0],mac_addr[1],\
          mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
  SPI_Write(SAR + 0,mac_addr[0]);
  SPI_Write(SAR + 1,mac_addr[1]);
  SPI_Write(SAR + 2,mac_addr[2]);
  SPI_Write(SAR + 3,mac_addr[3]);
  SPI_Write(SAR + 4,mac_addr[4]);
  SPI_Write(SAR + 5,mac_addr[5]);
  _delay_ms(1);
  printf("Reading SAR: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n\n",SPI_Read(SAR + 0),SPI_Read(SAR + 1),\
          SPI_Read(SAR + 2),SPI_Read(SAR + 3),SPI_Read(SAR + 4),SPI_Read(SAR + 5));
  // Setting the Wiznet W5100 Sub Mask Address (SUBR): 0x0005 to 0x0008
  printf("Setting Sub Mask Address %d.%d.%d.%d\n",sub_mask[0],sub_mask[1],\
          sub_mask[2],sub_mask[3]);
  SPI_Write(SUBR + 0,sub_mask[0]);
  SPI_Write(SUBR + 1,sub_mask[1]);
  SPI_Write(SUBR + 2,sub_mask[2]);
  SPI_Write(SUBR + 3,sub_mask[3]);
  _delay_ms(1);
  printf("Reading SUBR: %d.%d.%d.%d\n\n",SPI_Read(SUBR + 0),SPI_Read(SUBR + 1),\
          SPI_Read(SUBR + 2),SPI_Read(SUBR + 3));
  // Setting the Wiznet W5100 IP Address (SIPR): 0x000F to 0x0012
  printf("Setting IP Address %d.%d.%d.%d\n",ip_addr[0],ip_addr[1],\
          ip_addr[2],ip_addr[3]);
  SPI_Write(SIPR + 0,ip_addr[0]);
  SPI_Write(SIPR + 1,ip_addr[1]);
  SPI_Write(SIPR + 2,ip_addr[2]);
  SPI_Write(SIPR + 3,ip_addr[3]);
  _delay_ms(1);
  printf("Reading SIPR: %d.%d.%d.%d\n\n",SPI_Read(SIPR + 0),SPI_Read(SIPR + 1),\
          SPI_Read(SIPR + 2),SPI_Read(SIPR + 3));
 
  // Setting the Wiznet W5100 RX and TX Memory Size, we use 2KB for Rx/Tx 4 channels
  printf("Setting Wiznet RMSR and TMSR\n\n");
  SPI_Write(RMSR,0x55);
  SPI_Write(TMSR,0x55);
  printf("Done Wiznet W5100 Initialized!\n");
}
// Assign I/O stream to UART
FILE uart_str = FDEV_SETUP_STREAM(uart_putch, uart_getch, _FDEV_SETUP_RW);
int main(void){
  // Set the PORTD as Output:
  DDRD=0xFF;
  PORTD=0x00;
   // Define Output/Input Stream
  stdout = stdin = &uart_str;
  // Initial UART Peripheral
  uart_init();
  // Clear Screen
  ansi_me();
  ansi_cl();
  ansi_me();
  ansi_cl();
  uart_flush();
  // Initial the AVR ATMega168/328 SPI Peripheral
  // Set MOSI (PORTB3),SCK (PORTB5) and PORTB2 (SS) as output, others as input
  SPI_DDR = (1<<PORTB3)|(1<<PORTB5)|(1<<PORTB2);
  // CS pin is not active
  SPI_PORT |= (1<<SPI_CS);
  // Enable SPI, Master Mode 0, set the clock rate fck/2
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR |= (1<<SPI2X);
  // Initial the Wiznet W5100
  printf("Wiznet W5100 Init\n\n");
  W5100_Init();
  // Loop forever
  for(;;){
  }
  return 0;
}

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home