innoverse2023 / AC-Load-Current-Sensing

0 stars 0 forks source link

Load Current Sensing #1

Open innoverse2023 opened 10 months ago

innoverse2023 commented 10 months ago

Image

Image

MrSawHtunAung commented 10 months ago

image

#include <16F677.h>
#include <stdint.h>
#device ADC = 10
#fuses  NOMCLR,NOBROWNOUT,PUT
#use delay(internal = 8MHz)
#use rs232(xmit = PIN_A4, rcv = PIN_A5, baud = 9600)
#define n 10 // number of samples
#define w 3  // number of windows
#define F 14.14  // Factor

volatile uint8_t m, window, data;
int16_t _array[n];
volatile uint16_t  Aavg;
volatile uint32_t A_win, A_RMS;

#INT_TIMER0
void Timer0_ISR(void) {
  set_timer0(6);
}

#INT_TIMER1
void Timer1_ISR(void) {
  set_timer1(64913); //311.50us @ DIV_4
  read_adc(ADC_START_ONLY);
}

#INT_AD 
void ADC_ISR(void) {
  _array[m] = read_adc(ADC_READ_ONLY);
  m++;  

  if(m>=2){
     if(_array[0] != 0 | _array[1] == 0){
       memset(_array, 0, sizeof(_array));
       m = 0;
     }
  }
}

uint16_t map(uint16_t value, uint16_t x_min, uint16_t x_max, uint16_t y_min, uint16_t y_max);
uint16_t map(uint16_t value, uint16_t x_min, uint16_t x_max, uint16_t y_min, uint16_t y_max)   
{                   
    return (y_min + ((((float)y_max - y_min)/(x_max - x_min)) * (value - x_min)));
}

void Calculation_RMS() {
   for ( uint8_t i = 0; i < n; i++ ) {
      if(_array[i] != 0) { 
     Aavg += _array[i]; 
     data++;
      }
   }
   A_win = F * (Aavg / data);
   A_win = A_win;
   data = 0;
}

void main(void) {
  setup_adc(ADC_CLOCK_DIV_16);
  setup_adc_ports(sAN10 | VSS_VDD);
  set_adc_channel(11);

  enable_interrupts(GLOBAL);

  setup_timer_0(T0_INTERNAl |  T0_8_BIT | T0_DIV_32 );  // Timer 0 setup: prescaler = 32, period = 6 (for 1ms @ 8 MHz MCU clock)
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);  // Timer 1 setup: prescaler = 4, period = 64913 (for 311.50us @ 8 MHz MCU clock)

  clear_interrupt(INT_TIMER0);
  enable_interrupts(INT_TIMER0);

  while (TRUE) {
    Aavg = 0;

    clear_interrupt(INT_TIMER1);
    enable_interrupts(INT_TIMER1);
    clear_interrupt(INT_AD);
    enable_interrupts(INT_AD);

    while (m < n) ;     // wait for adc samples to complete
    m = 0;
    disable_interrupts(INT_AD);
    disable_interrupts(INT_TIMER1);

    Calculation_RMS();

    A_RMS += A_win; 
    window++;
    if(window >= w) {  // wait for (w) windows to complete
       A_RMS = A_RMS / w;
       A_RMS = map(A_RMS, 0, 796, 0, 210) / 10;
       printf( "Voltage = %Lu A \n\r", A_RMS );    
       window = 0;     A_RMS = 0;    A_win = 0;    
       delay_ms(10);
    }
  }
}