Volt-Amp meter using AVR microcontroller

 

volt-amp-meter-avr-microcontroller

Voltage and current are two most important parameters of electricity. This project teaches you to build a simple volt-amp meter using avr microcontroller. This project may not enable you to build a high end measurement tool but will be a good diy project which gives a better understanding on A/D converter in microcontrollers. This meter is capable of measuring voltage ranging from 0 to 30V and current ranging from 0 to 5A. Care must be taken while using so that the input should not exceed the specifications.

SETTING UP THE SENSORS:

VOLTAGE MEASUREMENT:

voltage-sensor-divider
A simple potential divider is employed to measure the voltage. The above potential divider was set up in such a way it gives 5v as output when 30v input is applied to it since the input voltage given to AVR should be less than or equal to 5V.

The formula for setting the potential divider resistor is
Vout = Vin x R2 / (R1 + R2)
We knew our Vout should be <= 5V. So applying this and fixing a resistor R2 as 10k will give
5v = 30 x 10k /(R1 + 10k)
R1 = 50k.

CURRENT MEASUREMENT:

current-sensor-module-acs712 We are using a pretty straight forward approach to measure current. Here we are using a Hall effect current sensor to measure current. This sensor can measure current up to 5A. 1A of current is equivalent to 185mv of change in output voltage. There are also 20A and 30A version of this chip available. Read more about this sensor here.

CALIBRATION:

The next task is to perform the calibration to display the real values using our Microcontroller. So in order to do that we need to know the Step Size of our A/D converter in AVR microcontroller. It was given by the formula

Step size = Vref / 2^10 (Since it is a 10 bit ADC) .

= 5/1024 = 4.88mv

This is the step size of our A/D converter in AVR microcontroller that is for every 4.88mv change in input there will be a change in ADC value in the register.

TO CALCULATE VOLTAGE:

As i have previously mentioned the voltage sensing is done by using a Voltage divider which bears the formula

Vout = Vin x R2 / (R1 + R2)

Am going to use this formula to derive the real voltage from the sensed voltage. Since we obtain the sensed voltage in the form of digital numbers we need to make a conversion to obtain Vout value from it. So

Vout = Digital Value read from A/D register * Vref / 2^10

Vout = Digital Value read from A/D register * 5 / 1024 , Simplifying this we get

Vout = Digital Value * 0.00488 

This will give us exact Vout voltage from the voltage divider, now applying this Vout in the divider equation will give the real voltage given as input to the voltage divider.

Vin= Vout * (R1+R2) /R2

Vin = Vout * 60k / 10K

Vin = Vout * 6

The above final equation i have added in the 41 line of the code, This will give the real voltage that needs to be measured and displayed.

TO CALCULATE CURRENT:

The IC ACS712  5A chip gives out 185mA of voltage change in the output when there is a 1A change in the current flow. And the nominal voltage will be of 2.5 Volts so the ADC always reads 2.5 V even if there is no current through it.

Vout = Digital value read from the A/D register * 5 /1024 , simplifying we get

Vout = Digital value * 0.00488

So the real value of current can be given as

Amp = (Vout – Nominal Voltage) / 185mA (Change in output voltage of sensor)

Amp = (Vout – 2.5) / 0.185

This equation was added in the line 54  of the code. I have replaced Amp with available float variable Vin in the code to cut down the code size.

CODE:

#include<avr/io.h>
#define F_CPU 8000000UL
#include<util/delay.h>
#include<stdio.h>
double vin;
double vout;
unsigned int value;
char output[6];

void lcd_cmd(char cmd)              //Command sub routine LCD
{
   PORTC=cmd;
   PORTD&=~(1<<0);
   PORTD|=(1<<1);
   _delay_ms(5);
   PORTD&=~(1<<1);
   _delay_ms(5);
}

void lcd_data(char *txt)         //Data sub routine LCD
{
   while(*txt!='\0')
   {
   PORTC=*txt;
   PORTD|=(1<<0);
   PORTD|=(1<<1);
   _delay_ms(5);
   PORTD&=~(1<<1);
   _delay_ms(5);
   txt++;
    }
}

void voltage(void)             //Sub routine to read voltage
{
  ADMUX|=(1<<0);
  ADCSRA|=(1<<6);
  while(ADIF==0);
  value=ADCL|ADCH<<8;
  vout=value*0.00488;             //To determine output Voltage from sensor
  vin=6*vout;                    //To determine real voltage
  sprintf(output,"%.2f",vin);    
  lcd_cmd(0x86);
  lcd_data(output);
}

void current(void)
{
  ADMUX&=~(1<<0);
  ADCSRA|=(1<<6);
  while(ADIF==0);
  value=ADCL|ADCH<<8;
  vout=value*0.00488;            //To determine output voltage from sensor
  vin=(vout-2.5)/0.185;          //To determine real current
  sprintf(output,"%.2f",vin);    //Float to char conversion for printing
  lcd_cmd(0xc6);
  lcd_data(output);
}

int main(void) 
{
  DDRC=0xff;
  DDRD=0x03;
  PORTC=0x00;
  PORTD=0x00;
  lcd_cmd(0x38);
  lcd_cmd(0x01);
  lcd_cmd(0x0c);
  lcd_cmd(0x80);
  lcd_data("VOLTS:");
  lcd_cmd(0xc0);
  lcd_data("CURNT:");
  ADMUX=0x00;
  ADCSRA=0x87;                     //Initializing A/D converter
  while(1)
   {
    voltage();            //Voltage display
    _delay_ms(10);
    current();           //Current Display
   }
  return 0;
}

Volt Current Meter HEX File
Volt Current Meter HEX File
volt_current_meter.hex
Version: 1
13.0 KB
1372 Downloads
Details

NOTE:

  • Care must be taken so that the input parameters (voltage & current) should not exceed the limitations.
  • You can change the limitations by replacing the sensors and must be calibrated accordingly.

54 Comments

  1. Anonymous

    in line 4. What include ?

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Hi,
      Apologies. Post updated correctly now.

      Reply
      1. Top

        it can not work when it work it show
        Volt : ?
        current : ?
        it can’t show the value of measuring. Can you fix it ?

        Reply
  2. Govind

    Hi
    This circuit is for ac current or DC current

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Govind,
      DC.

      Reply
  3. Russell

    Hi
    Could you specify how code was compiled, does not yield a working hex. Thanks

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Russel,
      The code was compiled on AVR studio, what’s the error you got when compiling?

      Reply
      1. Russell

        No errors to speak of. Compiled with AVRDUDE and very recent GCC. There is an include in code with no define, so I added the library paths I thought necessary. I get a smaller .hex than posted .hex, but your hex gives a working numerical value for volt/amp. My hex gives nothing but a ? Mark for each, with same circuit input. Maybe AVR studio has additional library reference.

        Reply
  4. R27

    Hi Frank,
    I built this circuit using the supplied .hex, works well. Vss and Vdd are reversed in drawing for display by the way. Is there an include file or part of the code missing, compiled but only get display reading. No volt or amp input, only ? for output. Want to change some of the parameters. Thanks for the post.

    Reply
    1. Frank DonaldFrank Donald (Post author)

      R27,
      Try applying any voltages less than 5 to the analog input pin and see if you get any value in the lcd.

      Reply
  5. Anonymous

    Hi, Very nice tutorial. My question is:
    sprintf(output,”%.2f”,vin); Is this sprintf an AVR keyword, if so how it works?

    Thanks

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Hi,
      No sprintf is not an AVR keyword, it is C. It converts integer to Char. In the code i was using it to convert the integer vin to char output and then print it in the lcd.

      Reply
  6. lot of THANKS for Hex file

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Sirkit,
      Not a problem , let me know the outcome of your project.

      Reply
  7. WHERE IS HEX FILE.NOT FOUND

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Sirkit,
      My sincere apologies, the error is cleared now. You can download the file now.

      Reply
  8. Thanks for quick response sir.But sir when i trying to download the display “File volt_current_meter.hex not found!”
    NARESH JAIN

    Reply
  9. Naresh Jain

    sir can you upload hex file

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Naresh Jain,
      File uploaded as per your request.

      Reply
  10. Ivan

    Could you provide some metrics from the prototype? What is the accuracy of the volt-meter? Temperature deviations?

    Reply
    1. Frank DonaldFrank Donald (Post author)

      Ivan,
      The error is very minimal i noticed for a 30V supply 29.95 is the obtained output. Not to worry these errors will occur only at high voltages.

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *