//# defined(__PCH__)
#include <18F452.h>

#DEVICE ADC=10
#include <math.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#include <flex_lcd.c>
//#endif

unsigned int16 adc_value_volt,adc_value_current;
float Volts,max_volts,current,max_current,phase_angle,pf;
unsigned int8 frquency,one_second,frquency_timer_start;

float volt_array[30],current_array[30],time_difference;
unsigned int16 volt_array_pointer,current_array_pointer,i,j,max_volt_pointer,max_current_pointer;
int max_volt_reached;

 
 #int_EXT
void  EXT_isr(void)
{
enable_interrupts(INT_TIMER2);
if(frquency_timer_start == 0 ) enable_interrupts(INT_TIMER1);
frquency++;
} 

#INT_TIMER1                        // This function is called every time
void frequency_isr() {
frquency_timer_start = 1;
one_second++;
if(one_second ==19)
 {
 disable_interrupts(INT_TIMER2);
disable_interrupts(INT_EXT);
 printf("%fV %fA %fDeg P.F=%f %u Hz\n\r", max_volts,max_current,phase_angle,pf,frquency);
// printf("%u Hz\n\r",frquency);
frquency_timer_start = 0;
 disable_interrupts(INT_TIMER1);
 one_second = 0;
 frquency = 0;
 setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );  
 volt_array_pointer = 0;
 max_volt_reached = 0;
 current_array_pointer = 0;
 enable_interrupts(INT_EXT);
 }
}


#INT_TIMER2                        // This function is called every time
void clock_isr() {                 // timer 2 overflows (250->0), which is


disable_interrupts(INT_TIMER2);
disable_interrupts(INT_EXT);

output_high(PIN_D1);
output_high(PIN_D0);
set_adc_channel(0);                          // Select channel 0 (AN0)
adc_value_volt=read_adc();                    //Read A/D value  
set_adc_channel(1);                          // Select channel 0 (AN0)
adc_value_current=read_adc();                    //Read A/D value 
Volts=(float)adc_value_volt*50/1024;
volts = volts * 18.2 / 1.41421356;   //Multiplying by transformer ratio & / by root 2 for Vrms     
current=(float)adc_value_current*5/1024;
current = current*current*1.38;


volt_array[volt_array_pointer] = Volts;
if(volt_array_pointer > 0 && max_volt_reached == 0)
 {
 if(volt_array[volt_array_pointer-1] > volt_array[volt_array_pointer])
  {
  max_volts = volt_array[volt_array_pointer-1];
  //printf("%f Vrms     ",volt_array[volt_array_pointer-1]);  // send to RS232  
  for(i = 0 ; i<30 ; i++) volt_array[i] = 0;
  max_volt_pointer = volt_array_pointer;
  volt_array_pointer = 0;
  max_volt_reached = 1;
  }
 }
 if(max_volt_reached == 0 ) volt_array_pointer++;
 if(volt_array_pointer >29) printf("Overloaded volt\n\r");


 
 current_array[current_array_pointer] = current;
 
 if(current_array_pointer > 0 )
 {
 if(current_array[current_array_pointer-1] > current_array[current_array_pointer])
  {
  max_current = current_array[current_array_pointer-1];
  for(j = 0 ; j<30 ; j++) current_array[j] = 0;
  max_current_pointer = current_array_pointer;  
  time_difference =  (max_current_pointer - max_volt_pointer) * (0.000004+ 0.0004185);
  phase_angle = ((float)(time_difference/0.02))*360;
  pf = cos(phase_angle*(2*3.142/360)); 
  //printf("%fV %fA %fDeg %fP.F\n\r", max_volts,max_current,phase_angle,pf);
 //printf("%fV %fA %eSec %fDeg\n\r", max_volts,current,time_difference,phase_angle);
 // printf("%e  Time Difference %lu   %lu  \n\r",time_difference,max_current_pointer,max_volt_pointer);
  
  current_array_pointer = 0;
  max_volt_reached = 0;
  max_volt_pointer = 0;
  output_low(PIN_D0);
  clear_interrupt(INT_EXT);  
  clear_interrupt(INT_TIMER2); 
  enable_interrupts(INT_EXT);
  }
  else enable_interrupts(INT_TIMER2);
 }
 else enable_interrupts(INT_TIMER2);
 current_array_pointer++;
 if(current_array_pointer >30) printf("Overloaded cur\n\r");

output_low(PIN_D1); 
}


 void main() 
 {
  setup_adc_ports(ALL_ANALOG );                 // A/D Ports
  setup_adc(ADC_CLOCK_DIV_2);                 // A/D Clock    
  setup_timer_2( T2_DIV_BY_4, 10, 1); //((1/Clock)*4)* 16 * 125 * 5 = Time
  setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); //((1/Clock)*4)* 8 * 65,536  = Time = 52.4288e-3
  enable_interrupts(INT_EXT);               //INTE=1
  ext_int_edge(L_TO_H);
  enable_interrupts(GLOBAL);

  do
   {
   } while (TRUE);
  
    
    
 }

