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.

AC current measurement using ACS712 current module and PIC16F877A

Status
Not open for further replies.

niranjan23

Member level 5
Joined
Jan 22, 2012
Messages
94
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,288
Activity points
2,109
Hello!

Im working on AC current measurement using current sensor module ACS712 with PIC16f877a microcontroller.Thus I programmed ADC
for for Vref=vcc=5V and 8 Analog Inputs, Since i'm using AN0 port for analog input for current sensor module.
my aim is send adc data through GSM modem.but my problem is when I get message every time, I see different values from 0.25 to 1.85 when I connect 40W bulb. Im attaching my setup for measuring AC current below...since I didnt show GSM modem interface in diagram.
SSS.jpg
ActualModule.jpg

If you want my code i will Post it in next reply!!Thankyou!!!
 

What is the max rating of the sensor ? 5A, 20A or 30A ? Are you measuring AC or CD Current ?
 

I see different values from 0.25 to 1.85 when I connect 40W bulb.
What do the numbers mean, Irms A? What's the expected value? How do you calculate AC current from instantaneous sensor output voltage?
 

Bad calculations. Even for resistive load. To get accurate data advanced processing have to be used. All uncertancy data have to be filtered.
 

What is the max rating of the sensor ? 5A, 20A or 30A ? Are you measuring AC or CD Current ?

Sensor max rating is 5A and I'm measuring C current using it.

- - - Updated - - -

What do the numbers mean, Irms A? What's the expected value? How do you calculate AC current from instantaneous sensor output voltage?

those numbers are in Amperes not Irms Current.Expected value is current in ampere not mA or Irms.The calculation in embedded C is given below.
Code:
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////ADC CODE AREA///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void ADC_Init()
{
  ADCON0 = 0x81; 
  ADCON1 = 0x84;                  
}

unsigned int ADC_Read(unsigned char channel)
{
  if(channel > 7) //If Invalid channel selected 
    return 0;     //Return 0

  //ADCON0 &= 0xC5; //Clearing the Channel Selection Bits
  ADCON0 |= channel<<3; //Setting the required Bits
  __delay_ms(2); //Acquisition time to charge hold capacitor
  GODONE = 1; //Initializes A/D Conversion
  while(GODONE); //Wait for A/D Conversion to complete
  return ((ADRESH<<8)+ADRESL); //Returns Result
}

void ADC_main()
{
	process();
  
  TRISA = 0xFF; //PORTA as input
   process();
  ADC_Init(); //Initializes ADC Module
  process();
[COLOR="#FF0000"]  Factor = 264;
    ADCResult = ADC_Read(0); //Reading Analog Channel 0
    ADCResult = ADC_Read(0);
    ADCResult = ADCResult + ADC_Read(0);
    ADCResult = ADCResult + ADC_Read(0);
    ADCResult = ADCResult/3;
    A = (ADCResult-512)*Factor ;
   finalresult = (int)(A+0.5);           //////float to int conversion
   z = (char)finalresult;                 /////////int to char coversion
   x=z%10; 
   dat=(z % 1000) / 100 + 48 ;
   dat0 = '.' ;
    dat1=(z % 100) / 10 + 48 ;
    dat2=z % 10 + 48 ;[/COLOR]
    process();
   __delay_ms(10); //Delay
   flag = 1;
   process();
}

I have document file where I took reference from it. If you want it I will Post here!!
 

What is the problem you are facing ? The sensor gives 5V output for 5A. It is linear.

Show full code. What type is ADC_Result ? double ?
 


No I didnt!!

- - - Updated - - -

What is the problem you are facing ? The sensor gives 5V output for 5A. It is linear.

The problem Im facing is i'm not getting Constant reading/value at every message I receive on connecting load of 40W bulb. Values coming up are variable like 0.01,0.25,0.53...1.52.
 

Reply to my previous post. What is the crystal frequency you are using ?

I will write a code for you. You test it in hardware. Please provide the info asked below.

Crystal frequency.
LCD Connections.
LCD type - 16x2, 20x2, 20x4, 16x4 ?
 

What is the problem you are facing ? The sensor gives 5V output for 5A. It is linear.

Show full code. What type is ADC_Result ? double ?

Code:
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////*********Headers & Definations*******///////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

#include <htc.h>
#include<pic.h>
#include<string.h>
#include<stdio.h>
#define _XTAL_FREQ 20000000

//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////*********Declaration********/////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

void Uart_Initial_Tx_Rx(unsigned long baud);
void Uart_Data(unsigned char data);
void Send(const char *ptr);
void Send_Message();
void delay();
void delay1();
void process();
void process2();
void ADC_main();
float V,A;
unsigned char data1,x,z,dat0,dat,dat1,dat2,q,d1,d2,d3,d4,ADCResult,Factor,once;
int finalresult,i,j,k,m,t,flag,flag2;


////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////********MAIN CODE AREA**********////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////


void main()
{
TRISD0 = 1;
TRISD1 = 1;
TRISD2 = 0;
TRISD3 = 0;
TRISD4 = 0;
TRISD5 = 0;
TRISD6 = 0;
TRISD7 = 0;               
RD7 = 0;              ////Process LED
RD6 = 0;			////theft load indication
RD5 = 0;              
RD4 = 0;            
RD3 = 0; 				///Turn off ENERGY meter Relay
RD2 = 0;       
//RD1 = 1;        
process();
Uart_Initial_Tx_Rx(9600);
ADC_main();
once = 1;
process();
while(1)
{
		
if(RD0==0) ////////////////////Phase cut
{
  if(once==1)
     {	
       //ADC_main();
         Send_Message();
           process();
             once = 0;
            _delay(50);
     }  
}

else if(RD1==0)            ////////Mis call Input
{
   RD3 = 1;                ///Turn off ENERGY meter Relay
   process();
}


else if(dat>0x31)
{
	if(flag == 1)
	{
	   Send_Message();
    	flag = 0;
	     for(t=0;t<10000;t++)
	     {
	       process2();
	       }
	        process();
      	}
		 
     }
   }
}




 ////////////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////******GSM Modem Initilize********///////////////////////
 ////////////////////////////////////////////////////////////////////////////////////////

void Uart_Initial_Tx_Rx(unsigned long baud)
{
 process();
 TRISC6 = 0;                            
 TX..EN=1;                                
 BRGH=1;                                
 SYNC=0;                                
 SPEN.=1;                                
 if(baud == 9600 )
 SPBRG = 129;
 els.e if (baud == 19200)
 SPBRG = 64;
 else if (baud == 38400)
 SPBRG = 32;
 else if (baud == 57.600)
 SPBRG = 21;
 else if (baud == 115200)
 SPBR.G = 10;
 process();
}
 

void Uart_Data(unsigned char data)
{
 TXRE.G=data;
 while(TRMT.!=1);
}
 

void Send(const char *ptr)
{
 while(*ptr.!='\0')
 {
  TXRE.G=*ptr;
  while(TRMT!=1);
  ptr++;
 }
}

////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////*****DELAY*****////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////


void process()
{  
	RD7 = 1;
	delay();
	RD7 = 0;
	delay();
	RD7 = 1;
	delay();
	RD7 = 0;
}

void process2()
{  
	RD6 = 1;
	delay1();
	RD6 = 0;
	delay1();

}


void Delay_Ms(int ms)
{
 int i,count;
 for(i=1;i<=ms;i++)
 {
  count=498;
  while(count!=1)
  {
   count--;
  }
 }
} 

void delay()
{
  for(i=0;i<80;i++)
    for(j=0;j<80;j++);
}

void delay1()
{
  for(i=0;i<300;i++)
    for(j=0;j<255;j++);
}

    
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////*********Text Message**********/////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void Send_Message()
{
	
 process();
 Send("AT\r\n");                        
 Delay_Ms(500);                         
 Send("ATE0\r\n");                      
 Delay_Ms(500);                         /* 500ms delay                         */
 Send("AT+CMGF=1\r\n");                 
 Delay_Ms(500);                         /* 500ms delay                         */
 Send("AT+CNMI=2,1,0,0,0\r\n");         
 Delay_Ms(500); 
 process();                        /* 500ms delay                         */
 Send("AT+CMGS=\"+917507942453\"\r\n");  
 Delay_Ms(500);                         /* 500ms delay                         */
 Send("Power Theft Detected\r\n"); 
 Delay_Ms(500);
 Send("\r\nUser ID ABC12345678MH\r\n"); 
 Delay_Ms(500);
 Send("\r\nCurrent in A = ");
 Delay_Ms(500);                           
 Uart_Data(dat);
 Uart_Data(dat0);
 Uart_Data(dat1);
 Uart_Data(dat2);
 process();
 Delay_Ms(500);  
 Uart_Data(0x1A);                       
 Delay_Ms(500);
 process();
                            /* 500ms delay                         */
}

/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////ADC CODE AREA///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
void ADC_Init()
{
  ADCON0 = 0x81; 
  ADCON1 = 0x84;                  
}

unsigned int ADC_Read(unsigned char channel)
{
  if(channel > 7) //If Invalid channel selected 
    return 0;     //Return 0

  //ADCON0 &= 0xC5; //Clearing the Channel Selection Bits
  ADCON0 |= channel<<3; //Setting the required Bits
  __delay_ms(2); //Acquisition time to charge hold capacitor
  GODONE = 1; //Initializes A/D Conversion
  while(GODONE); //Wait for A/D Conversion to complete
  return ((ADRESH<<8)+ADRESL); //Returns Result
}

void ADC_main()
{
	process();
  
  TRISA = 0xFF; //PORTA as input
   process();
  ADC_Init(); //Initializes ADC Module
  process();
  Factor = 264;
    ADCResult = ADC_Read(0); //Reading Analog Channel 0
    ADCResult = ADC_Read(0);
    ADCResult = ADCResult + ADC_Read(0);
    ADCResult = ADCResult + ADC_Read(0);
    ADCResult = ADCResult/3;
    A = (ADCResult-512)*Factor ;
   finalresult = (int)(A+0.5);           //////float to int conversion
   z = (char)finalresult;                 /////////int to char coversion
   x=z%10; 
   dat=(z % 1000) / 100 + 48 ;
   dat0 = '.' ;
    dat1=(z % 100) / 10 + 48 ;
    dat2=z % 10 + 48 ;
    process();
   __delay_ms(10); //Delay
   flag = 1;
   process();
}

- - - Updated - - -

Reply to my previous post. What is the crystal frequency you are using ?

I will write a code for you. You test it in hardware. Please provide the info asked below.

Crystal frequency.
LCD Connections.
LCD type - 16x2, 20x2, 20x4, 16x4 ?

Im not using LCD im using GSM modem for sending SMS

- - - Updated - - -

as you can see the above code is completely working only problem is ADC readings!!

- - - Updated - - -

Reply to my previous post.

XTAL = 20Mhz
LCD not used.
To display values Im using SMS service Of GSM.
 

Ok. Burn this hex file to your PIC and then disconnect GSM modem and connect UART to PC and in PC set COMx port baudrate to 9600 bps.

Connect AC712 sensor to RA0. Don't connect any other thing to PIC. MCLR is enabled and so pullup MCLR to 5V using a 10k resistor. Connect sensor inputs in series with the Live wire of the load. Open Termite Serial terminal Software in PC and set COMx port and baudrate properly. See if correct current values are displayed. Also connect a Multimeter in AC Current measurement mode (10A) range and measure the current through the load. Compare the currents.

If this works properly then I will implement GSM code for you and provide you my code.

Are you using SIM900 ?
 

Attachments

  • ACS712 AC Current Measurement.rar
    3 KB · Views: 163
Ok. Burn this hex file to your PIC and then disconnect GSM modem and connect UART to PC and in PC set COMx port baudrate to 9600 bps.

Connect AC712 sensor to RA0. Don't connect any other thing to PIC. MCLR is enabled and so pullup MCLR to 5V using a 10k resistor. Connect sensor inputs in series with the Live wire of the load. Open Termite Serial terminal Software in PC and set COMx port and baudrate properly. See if correct current values are displayed. Also connect a Multimeter in AC Current measurement mode (10A) range and measure the current through the load. Compare the currents.

If this works properly then I will implement GSM code for you and provide you my code.

Are you using SIM900 ?

Yeah Im using Sim900a
And wait My Laptop doesn't have serial port and also i dont have USB to TTL!!!:sad:

- - - Updated - - -

I will let you know... it will take some time to test your code.I have to go in college for that.!!! Thank You..much appreciated.!!!God bless you!!
 

Ok. You provide me the number to which SMS has to be sent. I will write a basic code which will send the current value to that mobile number as SMS. You can test it now itself. Later I will write you pro code which checks if GSM modem is connected and powered and it will initialize the modem and then while sending AT commands it will check if \r\nOK\r\n response is received or not.

Here it is mentioned that the sensor gives 185 mV / A.

https://www.sparkfun.com/products/8882

So, if you have a 5A sensor. it gives. 185 * 5 mV for 5A. I have to change my code.

- - - Updated - - -

I am attaching a project. Please tell why it is giving wrong results. ACS712 sensor is used. I am only testing it in Proteus. ACS712 sensor gives 0.925V for 5A and so for 5V it will be 27.027 A. I have written code so that if adc RA0 input is 5V then current will be 27.027 A but for 5V adc input it is showing 5A. Is it mikroC bug or Proteus bug ?

I found from some webpage that ACS712 sensor gives 185 mV / A and so it is 27.027 A for 5V.
 

Attachments

  • ACS712 AC Current Measurement.rar
    37.2 KB · Views: 168
Last edited:
Ok. You provide me the number to which SMS has to be sent. I will write a basic code which will send the current value to that mobile number as SMS. You can test it now itself. Later I will write you pro code which checks if GSM modem is connected and powered and it will initialize the modem and then while sending AT commands it will check if \r\nOK\r\n response is received or not.

Here it is mentioned that the sensor gives 185 mV / A.

https://www.sparkfun.com/products/8882

So, if you have a 5A sensor. it gives. 185 * 5 mV for 5A. I have to change my code.

- - - Updated - - -

I am attaching a project. Please tell why it is giving wrong results. ACS712 sensor is used. I am only testing it in Proteus. ACS712 sensor gives 0.925V for 5A and so for 5V it will be 27.027 A. I have written code so that if adc RA0 input is 5V then current will be 27.027 A but for 5V adc input it is showing 5A. Is it mikroC bug or Proteus bug ?

I found from some webpage that ACS712 sensor gives 185 mV / A and so it is 27.027 A for 5V.

According to my knowledge when I tested ACS712 current sensor in lab these are the readings I got.I took only 2 readings on DMM.

Load ACS712 Output(AC)
25W Bulb 27mV

40W Bulb 37mV

This is the number 7507942453

As you are saying you simulate this On proteus someone has said to me that don't use simulation for testing analog circuit. Reason is you get false value and it leads to you at failure and wrong side, Instead of that you better do experiment(Test it by yourself).It can Proteous bug!

Thus I got to know that if you are measuring AC current using ACS712 current module you will get at the output is also AC parameter that means what the voltage is getting on DMM is AC voltage no matter how its low.

here is the PIC16F1847 View attachment Current sensor.rar project that measures AC current using ACS712 module. It might help you to understand...that couldn't help me out!!
 
Last edited:

Please provide the mobile number for which the SMS has to be sent. I will write a code and post the .hex file for testing. It was not a Proteus bug. I had set VDD at 27.027V and it was causing the problem. I deleted that entry in Configure Power Rails... dialog box and it started to work properly.

If you provide the mobile number then i will quickly provide you a .hex file for testing and it will send SMS to that number.
 

Please provide the mobile number for which the SMS has to be sent. I will write a code and post the .hex file for testing. It was not a Proteus bug. I had set VDD at 27.027V and it was causing the problem. I deleted that entry in Configure Power Rails... dialog box and it started to work properly.

If you provide the mobile number then i will quickly provide you a .hex file for testing and it will send SMS to that number.

Its 7507942453
 

Test this .hex file. If it gives correct current value then I will write more robust GSM code and post it here. Our Compilers are different. I think you are using Hi-Tech PICC. I am using mikroC PRO PIC Compiler.

The document you posted is taken from embedded-lab website and it mentions the same thing which I told that is sensor gives 185 mV / A.

Edit:

Try Rev1 file in hardware and tell if it gives correct current values.
 

Attachments

  • ACS712 AC Current Measurement.png
    ACS712 AC Current Measurement.png
    45.5 KB · Views: 293
  • ACS712 AC Current Measurement.rar
    17.9 KB · Views: 141
  • ACS712 AC Current Measurement Rev1.rar
    18.5 KB · Views: 104
Last edited:
Test this .hex file. If it gives correct current value then I will write more robust GSM code and post it here. Our Compilers are different. I think you are using Hi-Tech PICC. I am using mikroC PRO PIC Compiler.

The document you posted is taken from embedded-lab website and it mentions the same thing which I told that is sensor gives 185 mV / A.

Edit:

Try Rev1 file in hardware and tell if it gives correct current values.
I getting 13.27 A constantly with and without Load.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top