Project

Make a Digital Voltmeter Using an Arduino

4 years ago by Tim Youngblood

It's easy to make a simple digital voltmeter using an Arduino and 16x2 liquid crystal display (LCD).

It's easy to make a simple digital voltmeter using an Arduino and 16x2 liquid crystal display (LCD).

It's relatively simple to use an Arduino to measure voltages. The Arduino has several analog input pins that connect to an analog-to-digital converter (ADC) inside the Arduino. The Arduino ADC is a ten-bit converter, meaning that the output value will range from 0 to 1023. We will obtain this value by using the analogRead() function. If you know the reference voltage--in this case we will use 5 V--you can easily calculate the voltage present at the analog input. 

To display the measured voltage, we will use a liquid crystal display (LCD) that has two lines of 16 characters. LCDs are widely used to display data by devices such as calculators, microwave ovens, and many other electrical appliances.

This project will also show you how to measure voltages above the reference voltage by using a voltage divider. 


Experiment 1

In this experiment, we will make digital voltmeter capable of measuring up to 5V using an Arduino board and a 16x2 LCD. 


Hardware Required

  • 1 x Arduino Mega2560
  • 1x LCD (Liquid Crystal Display)
  • 1x 5 kohm potentiometer
  • 1x breadboard
  • female connectors
  • jumper wires


Wiring Diagram 

The 16x2 LCD used in this experiment has a total of 16 pins. As shown in the table below, eight of the pins are data lines (pins 7-14), two are for power and ground (pins 1 and 16), three are used to control the operation of LCD (pins 4-6), and one is used to adjust the LCD screen brightness (pin 3). The remaining two pins (15 and 16) power the backlight.

Terminal 1GND
Terminal 2+5V
Terminal 3Mid terminal of Potentiometer (for brightness control)
Terminal 4Resistor Select (RS)
Terminal 5Read/Write (RW)
Terminal 6Enable(EN)
Terminal 7DB0
Terminal 8DB1
Terminal 9DB2
Terminal 10DB3
Terminal 11DB4
Terminal 12DB5
Terminal 13DB6
Terminal 14DB7
Terminal 15+4.2-5V
Terminal 16GND

Refer to the diagram below to see how to connect the LCD to the Arduino. Note that the potentiometer is connected to the 5V source and GND and the middle terminal is connected to pin 3 of LCD. Rotating this pot changes the brightness of the LCD. The four data pins DB4-DB7 are connected to the Arduino pins 4-7. Enable is connected to pin 9 of the Arduino and RS is connected to pin 8 of the Arduino. RW is connected to ground. The backlight LED is connected to 5V and ground. The following table shows the pin connections:

DB4 ----->pin4

DB5 ----->pin5

DB6 ----->pin6

DB7 ----->pin7

RS   ----->pin8

EN   ----->pin9



Code

The program below uses the LiquidCrystal library. This library contains all of the functions needed to write to the LCD.

The loop reads the analog value from the the analog input, and because the reference voltage is 5 V, it multiples that value by 5, then divides by 1024 to calculate the actual voltage value. Once the voltage has been calculated, the value is written to the LCD. 

The photo below shows a typical display.

#include "LiquidCrystal.h"

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

float input_voltage = 0.0;
float temp=0.0;


void setup()
{
   Serial.begin(9600);     //  opens serial port, sets data rate to 9600 bps
   lcd.begin(16, 2);       //// set up the LCD's number of columns and rows: 
   lcd.print("DIGITAL VOLTMETER");
}
void loop()
{

//Conversion formula for voltage
   
   int analog_value = analogRead(A0);
   input_voltage = (analog_value * 5.0) / 1024.0; 

   
   if (input_voltage < 0.1) 
   {
     input_voltage=0.0;
   } 
    Serial.print("v= ");
    Serial.println(input_voltage);
    lcd.setCursor(0, 1);
    lcd.print("Voltage= ");
    lcd.print(input_voltage);
    delay(300);
}

Make_A_Digital_Voltmeter.zip

Experiment 2

In order to measure voltages greater than the 5 V reference voltage, you need to divide the input voltage so that the voltage actually input to the Arduino is 5 V or less. in this experiment, we will use a 90.9 kohm resistor and a 10 kohm resistor to create a 10:1 divider. This will allow us to measure voltages up to 50 V.


Hardware Required

  • 1x Arduino Mega2560
  • 1x 90.9 kohm resistor
  • 1x 10 kohm resistor
  • 1x LCD (Liquid Crystal Display)
  • 1x 5k potentiometer
  • 1x breadboard
  • female connector
  • jumper wires


Wiring Diagram

The circuit for this experiment is exactly the same as Experiment #1, except that we now have a voltage divider, made up of a 90.9 kohm resistor and a 10 kohm resistor connected to the input. See the diagram below.

Program

The program for this experiment is nearly the same as for Experiment #1. The only difference is that now we have to divide the calculated voltage by the ratio R2/(R1 + R2), which in this case is 10,000/(90,900 + 10,000) ≈ 0.1.


Code

#include "LiquidCrystal.h"

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

float input_voltage = 0.0;
float temp=0.0;
float r1=90900.0;
float r2=10000.0;


void setup()
{
   Serial.begin(9600);     //  opens serial port, sets data rate to 9600 bps
   lcd.begin(16, 2);       //// set up the LCD's number of columns and rows: 
   lcd.print("DIGITAL VOLTMETER");
}
void loop()
{
   
//Conversion formula

   int analog_value = analogRead(A0);
    temp = (analog_value * 5.0) / 1024.0; 
   input_voltage = temp / (r2/(r1+r2));
   
   if (input_voltage < 0.1) 
   {
     input_voltage=0.0;
   } 
    Serial.print("v= ");
    Serial.println(input_voltage);
    lcd.setCursor(0, 1);
    lcd.print("Voltage= ");
    lcd.print(input_voltage);
    delay(300);
}

digital_voltmeter_with_arduino_1.ino.zip

Videos

Give this project a try for yourself! Get the BOM.

27 Comments
  • sophiap August 23, 2015

    I am currently doing this project and am currently confused. What the video shows doesn’t match up to the given diagram. The LCD is connected to the breadboard, how was this done?

    Like. Reply
  • Laszlo Lebrun October 03, 2015

    “in this experiment, we will use a 100 kohm and a 10 kohm resistor to create a 10:1 divider.”
    Sorry: Your voltage divider formula isn’t correct.
    The correct formula is R1+R2/R2

    You should use a 90,9KΩ and a 10,0KΩ resistor pair.

    Like. Reply
  • SeSandoval March 31, 2016

    I just burn 3 POTS. Is it right the second diagram?.

    Like. Reply
  • magicChristian November 21, 2016

    The ATMEGA internal ADC has 3 valuable possibilies for this project:
    first it has in internal reference of 2.56 V and this makes your meter not depending on the 5 V supply.
    second it allows for differntial ADC conversion which allows for measuring also negativ voltages
    third it has a build in amplifier x10 which could be used for low voltages.
    For voltages higher than the reference voltage you can use any voltage divider, with R2 being 10 kohm (because this is best for the internal ADC). The reading is the multiplication of ADC result by a cal constant, which have to fixed of a one time calibration with a second voltage meter.
    I would recomend a capacitor on the input of ADC to filter AC voltages to achieve more stable readings.

    Like. Reply
    • mcutin January 26, 2018
      Hi, there. Could you explain how can I calculate the value of this capacitor you’re recommending? I’m planning to measure voltages from 0 to 55V dc using a circuit like this in an Arduino Uno analog input. Thanks!
      Like. Reply
  • AllMyCircuits December 23, 2016

    Shouldn’t you divide by 1023 instead of 1024?
    That would also explain why you only get the reading 4.99 V and not 5.00 V.

    And if you use I2C instead of 4 Data-Lines for the Display-Data, you will save 2 Output-Pins (i am using a 20x4 display with I2C with full satisfaction).

    Like. Reply
    • RK37 January 20, 2017
      There seems to be some disagreement about the proper equation for converting an ADC code to voltage, but the one used in the article is the more correct version. You use 2^N instead of (2^N - 1) because you want to multiply the ADC code by the LSbit step size, and you obtain the LSbit step size by dividing the reference voltage by the number of possible ADC codes. With a 10-bit ADC, there are 2^10 = 1024 possible codes (i.e., from 0 to 1023). You can read more here: https://e2e.ti.com/blogs_/b/precisionhub/archive/2016/04/01/it-s-in-the-math-how-to-convert-adc-code-to-a-voltage-part-1
      Like. Reply
  • Ladislav M. March 20, 2017

    I was working on a UPS project and i was looking for voltmeter code for tft lcd display. And than I found this project. I just edited it a little bit and it worked! Thanks you for posting this project.

    This is my edited code:
    #include <A>
    #include <MCUFRIEND_kbv.h>
    float input_voltage = 0.0;
    float temp=0.0;
    MCUFRIEND_kbv tft;

    #define BLACK   0x0000
    #define BLUE   0x001F
    #define RED   0xF800
    #define GREEN   0x07E0
    #define CYAN   0x07FF
    #define MAGENTA 0xF81F
    #define YELLOW 0xFFE0
    #define WHITE   0xFFFF
    #define GREY   0x7BEF

    #include <stdio.h>

    void setup()
    {


    Serial.begin(9600);
    tft.reset();
    uint16_t identifier = tft.readID();
    Serial.print("ID = 0x");
    Serial.println(identifier, HEX);
    if (identifier == 0xEFEF) identifier = 0x9486;
    tft.begin(identifier);

    tft.setTextColor(WHITE);
    tft.fillScreen(0x0000);
    tft.setRotation(1);
    tft.setCursor(0, 0);
    tft.setTextSize(8);
    tft.fillScreen(BLACK);



    }

    void loop()
    {

    int analog_value = analogRead(A5);
    input_voltage = (analog_value * 5.0) / 1024.0;

    if (input_voltage < 0.1)
    {
    input_voltage=0.0;
    }
       
     
      Serial.print(“v= “);
      Serial.println(input_voltage);
     
      tft.print(input_voltage);
      tft.println(” V”);
      delay(300);
      tft.setTextColor(WHITE);
      tft.fillScreen(0x0000);
      tft.setCursor(0, 0);
      tft.setTextSize(8);
      tft.fillScreen(BLACK);
        }

    Like. Reply
    • PaulMx117 October 17, 2018
      Hi, I'm trying to measure voltage but, instead have a numeric value, what I want to do is plot the value of voltage in the tft, just like you visualize in the arduino's Serial Plotter, actually I use the same code like you, I use MCUFIREND for my 3.5 TFT, but it's hard to get a code that makaes the graph of the voltage, do you know how could I solve this?
      Like. Reply
  • JBee May 11, 2017

    Can it do amperage?

    Like. Reply
    • RK37 May 11, 2017
      No, only voltage. Measuring current requires a fundamentally different circuit arrangement. https://www.allaboutcircuits.com/textbook/experiments/chpt-2/ammeter-usage/
      Like. Reply
  • Islam Abo Hassan June 08, 2017

    can read output voltage in serial monitor without lcd

    Like. Reply
  • KeithWalker July 19, 2017

    There is an error in the wiring diagrams. As show, pins 8 and 9 of the arduino are connected to supply+ and supply- respectively.  On the display, this will tie the VEE line to ground and R/W line high.and could damage the output pins of the arduino.

    Like. Reply
  • SACHIN KUMAR V C October 27, 2017

    I’m totally confused of that wiring diagram, can you please provide me the actual circuit diagram how all the components are connected…

    Like. Reply
  • SACHIN KUMAR V C October 27, 2017

    I’m totally confused of that wiring diagram,  can you please send me the actual circuit diagram….

    Like. Reply
  • zoya khan January 02, 2018

    sir i have a problem in analog reading . when control read analog value and then i have to operate a relay on that value . the analog value fluctuate with (ON/Off) relay ..

    Like. Reply
    • zoya khan January 02, 2018
      when arduino controller** read analog value.
      Like. Reply
    • RK37 January 02, 2018
      If you have a question related to your own circuit, please post it in the forum. It's a great resource, and there are probably many users who could help you to understand and fix your problem.
      Like. Reply
  • robert towne January 06, 2018

    I am trying the experiment #2 because I have a solar panel that can go up to 6v.
    Are there other configurations for resistors using this mega setup - because I cannot find a 90.9 k ohm resistor but I have several others (e.g., 1k, 10k, 220, 330).  Thanks!

    Like. Reply
    • RK37 January 10, 2018
      You can use different resistor values, as long as the ratio between the two resistors is the same, because the goal is to create a 10:1 divider.
      Like. Reply
  • Joe_M July 11, 2018

    In order to read higher voltages, try a voltage divider circuit using 1% tolerance resistors. You can use some extra circuitry to switch from one voltage divider to another to change ranges on reading from low to higher voltages.  If you use some shunt resistors you can measure current as well. How about using a Arduino nano, and making a full fledged multimeter.

    Like. Reply
  • Krishna Bhagat March 02, 2019

    sir can we design it by using Arduino nano

    Like. Reply