Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Measuring Current through CT

Status
Not open for further replies.

Mrunal Ahirrao

Full Member level 2
Joined
Nov 26, 2012
Messages
133
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Location
India
Activity points
2,213
Hello,
I am trying to measure current from CT and I am able to measure current accurately above 1A but when measuring the current less than 1A then error occurs. I am using PIC16F886 with LCD 2x16. When current goes less than 1A suppose its 250mA then on display ideally it should be 0.25A but it is 2.50A displayed on LCD. Compiler I am using is MikroC. Here is my code:
Code:
// LCD module connections
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB5_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB2_bit;
// End LCD module connections


float I;//to store Current value
char Current[14];

void Current_Read()
{
  int k;
 ADCON0=0b01000101;
 delay_us(20);
 ADCON0.B2=1;
 for(k=0;k<99;k++)
 {
 I=ADC_read(1); //reading ADC value
 I=I*0.0048875;      //finding voltage from ADC reading
 I=I/4.4;           //dividing by amplifying factor
 I=I/120;          //dividing by burden resistor value to get secondary current
 I=I*2500;         //multiplying secondary Current by transformer turns ratio
 }
 FloatToStr(I,Current);
 delay_us(100);
 Lcd_out(2,13,Current);
 delay_ms(100);
 }

void main()
{
 TRISA = 0xFF; // set all pins of PORT A as input
 TRISB =0x00;
 ADCON1=0b00000000;
 ADCON0=0b01000000;
 ANSEL =0b0000011;
 ANSELH=0x00;
 CM1CON0.B7=0;
 CM1CON0.B5=0;
 CM2CON0.B7=0;
 CM2CON0.B5=0;
 Delay_ms(100);
 ADCON0.B0=1;
 delay_us(20);
 ADCON0.B2=1;



 Lcd_Init();
 delay_us(100);
 Lcd_Cmd(_LCD_CLEAR);
 delay_us(100);
 Lcd_Cmd(_LCD_CURSOR_OFF);
 delay_us(100);
   Lcd_out(2,1,"Current:");
  while(1)
  {
   Current_Read();
   Lcd_Chr(2,9,'A');


  }// while
}// void main
By looking at reading it seems that the PIC is reading current correctly but not displaying correctly. Please guide me.
 

Hi, please post the signal conditioning circuit... How you convert AC current into DC voltage. I am enclosing my circuit used for some application working fine
CT.png
 

hello,


Reserve up to 17 byte to store result of floatToStr ..

Better to multiply by 2500 first, then by 0,0048, then divide by 4,4 then divide by 120
to increase accuracy of calculus !
difference of 8% !

and simplest is to use the global factor.

Code:
/*
 I=ADC_read(1); //reading ADC value
 I=I*0.0048875;      //finding voltage from ADC reading
 I=I/4.4;           //dividing by amplifying factor
 I=I/120;          //dividing by burden resistor value to get secondary current
 I=I*2500;         //multiplying secondary Current by transformer turns ratio
in this way of calculation, resulting global factor is 0,023141572

*/
 
//in this way :  2500*0.0048875 / (4*120) =>0,02545573
I=(float) ADC_read(1) * 0.02545573;

is your full scale near 26Amps ?
(1023*0.0254)
 
Last edited:
soluce for simplify the calculus and avoid use of floating point
global scaling coefficient 254 rounded to 256 gives error 2/256 =><0.8% acceptable
so use a long to contains intermediate result over the size of an int.

see Method3
or Use of Write_Word .. (replace Put8RS2 by LCD_Char)

ex:
Code:
unsigned char Texte[64];
unsigned char Entree[17];
unsigned char *txt;
float f1;

void Write_Word(unsigned int M,char Sign, char remplis)
{
unsigned int i,k,l;
unsigned long M1;
 if (Sign>1) return;
 if (Sign==0)
  {       M1=M;
        ultoa(M1,(char *)Entree);
  }
  else itoa(M,(char *)Entree);
  if (remplis>0)
 {
      k=strlen(Entree);
      for (i=0;i<k;i++) Entree[4-i]=Entree[k-i-1];
      for (i=0;i<(5-k);i++) Entree[i]=remplis;
  }
 Entree[5+Sign]=0;
}


void Print_Values(unsigned int Analog)
{
 unsigned int j;
 unsigned long w;  
 f1=(float) Analog;
 f1=f1*0.0048875;      //finding voltage from ADC reading
 f1=f1/4.40;           //dividing by amplifying factor
 f1=f1/120.0;          //dividing by burden resistor value to get secondary current
 f1=f1*2500.0;
 sprintf(txt,"Methode 1 %s Amps\r\n",fltToa(f1,CRam1,3));
 PutStr_RS2(txt);    

f1=(float) Analog;    
f1=f1*0.02545573; 
 sprintf(txt,"Methode 2 %s Amps\r\n",fltToa(f1,CRam1,3));   
 PutStr_RS2(txt); 
 
 w=(unsigned long)Analog<<8;
 j=(unsigned int)( w/10);
 k=sprintf(txt,"Methode 3  % 5u mAmps\r\n",j);   
 PutStr_RS2(txt);
 
 PutStrR_RS2("Use of Write_Word :");
 Write_Word(j,0,32);   // space for unmeanless digit
 Put_RS2(Entree[0]);
  if (j<1000) Put_RS2('0'); else Put_RS2(Entree[1]);
   Put_RS2('.');
   if (j<100) Put_RS2('0'); else Put_RS2(Entree[2]);
    Put_RS2(Entree[3]);
     Put_RS2(Entree[4]);
      Put_RS2('A');
 CRLF2();
}


void main()
{
.....


 Print_Values(1023);CRLF2();
 Print_Values(100);;CRLF2();
 Print_Values(10);;CRLF2();
 Print_Values(1);;CRLF2();
  while(1); 
  
  ....


corresponding display on a terminal

ADC read =>: 1023
Methode 1 23.674 Amps
Methode 2 26.041 Amps
Methode 3 26188 mAmps
Use of Write_Word :26.188A

ADC read =>: 100
Methode 1 2.314 Amps
Methode 2 2.546 Amps
Methode 3 2560 mAmps
Use of Write_Word : 2.560A

ADC read =>: 10
Methode 1 0.231 Amps
Methode 2 0.255 Amps
Methode 3 256 mAmps
Use of Write_Word : 0.256A

ADC read =>: 1
Methode 1 0.023 Amps
Methode 2 0.025 Amps
Methode 3 25 mAmps
Use of Write_Word : 0.025A
 

Hi, please post the signal conditioning circuit... How you convert AC current into DC voltage. I am enclosing my circuit used for some application working fine
View attachment 114839

Hi ashad That "AD736" is not available to buy locally to me.

- - - Updated - - -

hello,


Reserve up to 17 byte to store result of floatToStr ..

Better to multiply by 2500 first, then by 0,0048, then divide by 4,4 then divide by 120
to increase accuracy of calculus !
difference of 8% !

and simplest is to use the global factor.

Code:
/*
 I=ADC_read(1); //reading ADC value
 I=I*0.0048875;      //finding voltage from ADC reading
 I=I/4.4;           //dividing by amplifying factor
 I=I/120;          //dividing by burden resistor value to get secondary current
 I=I*2500;         //multiplying secondary Current by transformer turns ratio
in this way of calculation, resulting global factor is 0,023141572

*/
 
//in this way :  2500*0.0048875 / (4*120) =>0,02545573
I=(float) ADC_read(1) * 0.02545573;

is your full scale near 26Amps ?
(1023*0.0254)

Hello,
I will try by your method and change the calculation steps. and yes I am getting full scale near 26Amps. And will this solve my problem?

- - - Updated - - -

soluce for simplify the calculus and avoid use of floating point
global scaling coefficient 254 rounded to 256 gives error 2/256 =><0.8% acceptable
so use a long to contains intermediate result over the size of an int.

see Method3
or Use of Write_Word .. (replace Put8RS2 by LCD_Char)

ex:
Code:
unsigned char Texte[64];
unsigned char Entree[17];
unsigned char *txt;
float f1;

void Write_Word(unsigned int M,char Sign, char remplis)
{
unsigned int i,k,l;
unsigned long M1;
 if (Sign>1) return;
 if (Sign==0)
  {       M1=M;
        ultoa(M1,(char *)Entree);
  }
  else itoa(M,(char *)Entree);
  if (remplis>0)
 {
      k=strlen(Entree);
      for (i=0;i<k;i++) Entree[4-i]=Entree[k-i-1];
      for (i=0;i<(5-k);i++) Entree[i]=remplis;
  }
 Entree[5+Sign]=0;
}


void Print_Values(unsigned int Analog)
{
 unsigned int j;
 unsigned long w;  
 f1=(float) Analog;
 f1=f1*0.0048875;      //finding voltage from ADC reading
 f1=f1/4.40;           //dividing by amplifying factor
 f1=f1/120.0;          //dividing by burden resistor value to get secondary current
 f1=f1*2500.0;
 sprintf(txt,"Methode 1 %s Amps\r\n",fltToa(f1,CRam1,3));
 PutStr_RS2(txt);    

f1=(float) Analog;    
f1=f1*0.02545573; 
 sprintf(txt,"Methode 2 %s Amps\r\n",fltToa(f1,CRam1,3));   
 PutStr_RS2(txt); 
 
 w=(unsigned long)Analog<<8;
 j=(unsigned int)( w/10);
 k=sprintf(txt,"Methode 3  % 5u mAmps\r\n",j);   
 PutStr_RS2(txt);
 
 PutStrR_RS2("Use of Write_Word :");
 Write_Word(j,0,32);   // space for unmeanless digit
 Put_RS2(Entree[0]);
  if (j<1000) Put_RS2('0'); else Put_RS2(Entree[1]);
   Put_RS2('.');
   if (j<100) Put_RS2('0'); else Put_RS2(Entree[2]);
    Put_RS2(Entree[3]);
     Put_RS2(Entree[4]);
      Put_RS2('A');
 CRLF2();
}


void main()
{
.....


 Print_Values(1023);CRLF2();
 Print_Values(100);;CRLF2();
 Print_Values(10);;CRLF2();
 Print_Values(1);;CRLF2();
  while(1); 
  
  ....


corresponding display on a terminal

nice programming method. But the sprintF is not supported for PIC16. SO it won't work.
 

Attachments

  • Current sensor.png
    Current sensor.png
    6.7 KB · Views: 110
Last edited:

sprintf not supported by 16F....
so use fourth method :
Write_Word (also,avoid use of float)

display the raw ADC reading value to your LCD to know
where is your problem.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top