# How to make a DC voltmeter using 7-segment & PIC16F73

A DC voltmeter can be used in many devices, even sometimes it becomes a must having feature for a device. In this article, we will learn how to make a DC voltmeter with Seven Segment and PIC micro-controller. So let’s make our DC voltmeter using PIC16F73 and mikroC coding.

Disclaimer: Electricity is always dangerous. Proper skill is required to work with electricity. Do work at your own risk. The author will not be responsible for any misuse or harmful act or any mistake you make. The contents of this website are unique and copyright protected. Kindly don’t do any nonsensical act copying and claiming it as yours. Most of the articles published here are kept as open-source to help you. Take the knowledge for free and use it, but if you are interested you can buy the ready resources offered here. If you need any help or guide feel free to comment below, the author will try to help you. Thanks.

## What is voltmeter?

A voltmeter is a measuring instrument that measures the voltage difference of two points of a circuit. It can be an analog or a digital one. But it doesn’t matter if it is analog or digital each one works in the same way, it measures voltage.

## Voltage sensor

For voltage sensing simple resistor voltage divider works fine. All you need to maintain a suitable ratio and good noise filtering.

As you can see, R1 and R2 are forming a voltage divider and C1 is our noise filter. By calculating the resistor voltage divider rules, we can easily find the source voltage reading of B1.

For testing, we can use a POT-VR to measure different voltages.

## Equations for voltage calculation:

To make the DC voltmeter using PIC16F73, we need to solve some calculations first. Here, we are using the PIC16F73 microcontroller. The ADC of this MCU is 8bit. That means, it measures voltage 0-5V and gives us a value 0-2^8 = 255 in correspond to the input voltage.

So the voltage at the pin of the MCU will be:

From the resistor voltage divider rule, we can find the reading of V1.

V2 = V1 x R2/(R1+R2);

If we replace V2,

If you check carefully, we have some fixed values. R1, R2, 5 & 255 all are fixed in this equation. Only ADC_reading is variable.

That means,

Now, we can easily find the supply voltage from the ADC reading value. Thus a DC voltmeter senses the input voltage.

As far we saw, a voltmeter can detect input voltage from ADC reading. But to make it more accurate, we can do some additional features.

If we take n number of samples and find the average value of them, our reading will be more accurate. More the value of ‘n’ more the accurate the value is.

Vavg = (V1 + V2 + … Vn)/n;

Now we need to make the circuit first for our voltmeter, then we’ll add the coding.

## Coding:

```/*******************************************************************************
* Program for, "Seven Segment based DC voltmeter"                              *
* Program written by_ Engr. Mithun K. Das                                      *
* MCU:PIC16F73; Xtal:8MHz; mikroC pro for PIC v7.6.0                           *
* Date: 03-04-2020                                                             *
*******************************************************************************/

// array for segment digits, 0-9; CC;
char segment_array[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//CC_non dot

//pin declearation for digits
sbit digit0 at RC0_bit;
sbit digit1 at RC1_bit;
sbit digit2 at RC2_bit;
sbit digit3 at RC3_bit;

char digits;
void display_7segment(int number)
{
digits=number/1000u;      //store 1000th digit
digits=(number/100u)%10u; //store 100th digit
digits=(number/10u)%10u;  //store 10th digit
digits=(number/1u)%10u;   //store 1st digit
}

void InitTimer0()    //intterupt for 5ms timer ISR
{
OPTION_REG     = 0x85;
TMR0           = 100;
INTCON         = 0xA0;
}

int position=0;
void Interrupt() iv 0x0004 ics ICS_AUTO
{
if (TMR0IF_bit)
{
TMR0IF_bit   = 0;
TMR0         = 100;

digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 1;
if(position>3)position=0;

PORTB = segment_array[digits[position]];
if(position==3)
{
digit0 = 0;
digit1 = 1;
digit2 = 1;
digit3 = 1;
}
else if(position==2)
{
digit0 = 1;
digit1 = 0;
digit2 = 1;
digit3 = 1;
}
else if(position==1)
{
digit0 = 1;
digit1 = 1;
digit2 = 0;
digit3 = 1;
}
else if(position==0)
{
digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 0;
}
position++;
}
}

void main()
{
TRISA=0xFF;//all input
TRISB=0x00;//all output
TRISC=0x00;//all output
PORTB=0x00;
PORTC=0x00;//clear ports
InitTimer0();//5ms timer
while(1)
{

}
}// end```

Here we have done the coding for our voltmeter. Now we need to check the result if it can detect the input voltage properly.

## Result 1:

As you see, it can detect the maximum reading. Here, we set B1 as 50V, and our voltmeter detected and displayed that 50V. But, to measure the fractions, we have to modify our code a little bit.

If we multiply the reading by 100 and add a dot (.) just after the second digit then we can make a more decent voltmeter.

To do that, we have to add some tricks.

```if(position==2) PORTB = segment_array[digits[position]]+128;
else PORTB = segment_array[digits[position]];```

If we add this code in ISR, it will show a dot point in position 2 like this:

Then just after multiplying by 100 while taking reading:

```    adc_value=0;//clear pervious value
for(k=0;k<10;k++)
{
}

Here, we must clear the previous value of adc_value, otherwise, it will keep adding the voltage reading. And keeping the multiplication inside for loop makes it more accurate.

## Final Code:

So the final code is now this:

```/*******************************************************************************
* Program for, "Seven Segment based DC voltmeter"                              *
* Program written by_ Engr. Mithun K. Das                                      *
* MCU:PIC16F73; Xtal:8MHz; mikroC pro for PIC v7.6.0                           *
* Date: 03-04-2020                                                             *
*******************************************************************************/

// array for segment digits, 0-9; CC;
char segment_array[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//CC_non dot

//pin declearation for digits
sbit digit0 at RC0_bit;
sbit digit1 at RC1_bit;
sbit digit2 at RC2_bit;
sbit digit3 at RC3_bit;

char digits;
void display_7segment(int number)
{
digits=number/1000u;      //store 1000th digit
digits=(number/100u)%10u; //store 100th digit
digits=(number/10u)%10u;  //store 10th digit
digits=(number/1u)%10u;   //store 1st digit
}

void InitTimer0()    //intterupt for 5ms timer ISR
{
OPTION_REG     = 0x85;
TMR0           = 100;
INTCON         = 0xA0;
}

int position=0;
void Interrupt() iv 0x0004 ics ICS_AUTO
{
if (TMR0IF_bit)
{
TMR0IF_bit   = 0;
TMR0         = 100;

digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 1;
if(position>3)position=0;
if(position==2) PORTB = segment_array[digits[position]]+128;
else PORTB = segment_array[digits[position]];
if(position==3)
{
digit0 = 0;
digit1 = 1;
digit2 = 1;
digit3 = 1;
}
else if(position==2)
{
digit0 = 1;
digit1 = 0;
digit2 = 1;
digit3 = 1;
}
else if(position==1)
{
digit0 = 1;
digit1 = 1;
digit2 = 0;
digit3 = 1;
}
else if(position==0)
{
digit0 = 1;
digit1 = 1;
digit2 = 1;
digit3 = 0;
}
position++;
}
}

int k=0;
void main()
{
TRISA=0xFF;//all input
TRISB=0x00;//all output
TRISC=0x00;//all output
PORTB=0x00;
PORTC=0x00;//clear ports
InitTimer0();//5ms timer
while(1)
{

for(k=0;k<10;k++)
{
}

}
}
//```

## Final Result:

Now our DC voltmeter using PIC16F73 is ready to test. Here is the test result in simulation:

Now, you have got everything to make a DC voltmeter. Although there is a little mismatch (less than 2%) this mismatch can be eliminated. For this, you need to use high accurate resistors.

I hope you enjoyed the project and will be able to make one for yourself. If you need any help, I’m here. Thanks. Enjoy!

Don’t forget to subscribe for the next update. JLCPCB – Only \$2 for PCB Prototype (Any Color)

24 Hours fast turnaround, Excellent quality & Unbeatable prices

\$18 Welcome Bonus for new registrations Now!!! https://jlcpcb.com

Check this out: 5 coolest multimeters you can buy

#### MKDas

I'm Mithun K. Das; B.Sc. in EEE from KUET, Bangladesh. Blog: https://labprojectsbd.com. "First, electronics was my passion, then it was my education, and finally, electronics is now my profession." I run my own electronics lab, M's Lab (https://mlabsbd.com). Where I work with the creation of new products from ideas to something in real life. Besides this is my personal blog where I write for hobbyists and newcomers in the electronics arena. I also have a YouTube channel where I publish other helpful videos, you can find the link inside the articles. I always try to keep it simple so that it becomes easy to understand. I hope these will help them to learn electronics and apply the knowledge in their real life.

• #### Rezaul · August 8, 2020 at 6:52 am

How can I use pic 16f676 in CA led? #### Joy · November 28, 2020 at 7:50 am

How I can use Ameter and Volt meter in one pic16f73 with one seven seg display.
Two in one output.Amp/Voltmeter DC. #### Joy · November 28, 2020 at 8:28 am

How can I make a Amp and Voltmeter pic16f73 in one Senensegment Display. Two input one output.
Dc Volt/Amper meter..