# Digital Voltmeter using Arduino

## Introduction

7-segment displays are most popular in panel meters, It can show direct numerical value on display, It’s cost is low and display size bigger than LCD’s. Lets interface four digit display, most of the time four digits are enough to display data.

#### Problem Statement

We are making a Voltmeter using four digit 7-segment display, for this IC 74HC595 shift register is used instead of 7448 decoder, use of shift register gives few advantages such as you can display sign, few alphabets and control decimal point location.

## 7-Segment display types and its pin out

Based on the number we want to show on display prepare decoding table

Those segments we want to keep on make 1 and remaining 0.

 Number dp G F E D C B A Hex Value 0 0 0 1 1 1 1 1 1 3F 1 0 0 0 0 0 1 1 0 06 2 0 1 0 1 1 0 1 1 5B 3 0 1 0 0 1 1 1 1 4F 4 0 1 1 0 0 1 1 0 66 5 0 1 1 0 1 1 0 1 6D 6 0 1 1 1 1 1 0 1 7D 7 0 0 0 0 0 1 1 1 07 8 0 1 1 1 1 1 1 1 7F 9 0 1 1 0 1 1 1 1 6F

## Arduino Connection with 7-Segment Display

To drive 7-segment display we used 74HC595 as Segment driver, you can use ULN2003 for driving common terminal, If the LED current is more, as we have used 1K Ohm resistor current stays in limit. We used three lines for driving segments and four for common terminal. At a time only one display is in on state.

## Arduino Code for Voltmeter using 4-Digit 7-Segment Display

In program we have used TimerOne Library for Display scanning.

```/*
Digital Voltmeter using 4-Digit 7-segment Display
www.circuits4you.com
*/

#include <TimerOne.h>

//Define 74HC595 Connections with arduino
const int Data=7;
const int Clock=8;
const int Latch=6;

const int SEG0=5;
const int SEG1=4;
const int SEG2=3;
const int SEG3=2;

int cc=0;
char Value[4];

//Refer Table 4.1 7-Segment Decoding
const char SegData[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

//=============================================================
//                Setup
//=============================================================
void setup() {
// initialize the digital pin as an output.
Serial.begin(9600);
pinMode(Data, OUTPUT);
pinMode(Clock, OUTPUT);
pinMode(Latch, OUTPUT);
pinMode(SEG0, OUTPUT);
pinMode(SEG1, OUTPUT);
pinMode(SEG2, OUTPUT);
pinMode(SEG3, OUTPUT);

//Initialize Display Scanner
cc=0;
Timer1.initialize(50000); // set a timer of length 100000 microseconds (or 0.1 sec - or 10Hz => the led will blink 5 times, 5 cycles of on-and-off, per second)
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
//=============================================================
//               Loop
//=============================================================
void loop() {
char Volt[4];
//To get fixed point decimal point we multiply it by 100
Voltage = (500/1024.0) * Voltage;  //Scaling of 0 to 5V i.e. 0 to 1023 to 0 to 10 (in 10 steps)

//Display Voltage on Segments
sprintf(Volt,"%04d",Voltage);    //We get ASCII array in Volt
Serial.println(Volt);

Value[0]=Volt[0] & 0x0F;    //Anding with 0x0F to remove upper nibble
Value[1]=Volt[1] & 0x0F;    //Ex. number 2 in ASCII is 0x32 we want only 2
Value[2]=Volt[2] & 0x0F;
Value[3]=Volt[3] & 0x0F;
delay(200);
}

//=============================================================
//             Generates Bargraph
//=============================================================
void DisplayDigit(char d)
{
int i;

for(i=0;i<8;i++)    //Shift bit by bit data in shift register
{
if((d & 0x80)==0x80)
{
digitalWrite(Data,HIGH);
}
else
{
digitalWrite(Data,LOW);
}
d=d<<1;

//Give Clock pulse
digitalWrite(Clock,LOW);
digitalWrite(Clock,HIGH);
}
//Latch the data
digitalWrite(Latch,LOW);
digitalWrite(Latch,HIGH);
}
//===================================================================
//			TIMER 1 OVERFLOW INTTERRUPT FOR DISPALY
//===================================================================
void timerIsr()
{
cc++;
if(cc==5)  //We have only 4 digits
{cc=1;}
Scanner();
TCNT0=0xCC;
}

//===================================================================
//		SCAN DISPLAY FUNCTION
//===================================================================
void Scanner()
{
switch (cc)    //Depending on which digit is selcted give output
{
case 1:
digitalWrite(SEG3,HIGH);
DisplayDigit(SegData[Value[0]]);
digitalWrite(SEG0,LOW);
break;
case 2:
digitalWrite(SEG0,HIGH);
DisplayDigit(SegData[Value[1]] | 0x80); //0x80 to turn on decimal point
digitalWrite(SEG1,LOW);
break;
case 3:
digitalWrite(SEG1,HIGH);
DisplayDigit(SegData[Value[2]]);
digitalWrite(SEG2,LOW);
break;
case 4:
digitalWrite(SEG2,HIGH);
DisplayDigit(SegData[Value[3]]);
digitalWrite(SEG3,LOW);
break;
}
}
//===================================================================
```

## Result

You can observe its output on serial terminal also, the display will show the voltage reading, apply voltage at ADC A0 pin using potentiometer. This code demonstrates how to multiplex multiple displays and concept of 7-segment display.