You are on page 1of 38

Digital voltmeter using pic microcontroller

In this project, a digital voltmeter using pic microcontroller is designed. Digital


voltmeter using a pic can read the voltage from 0-40 volt. This voltmeter can
read-only DC voltage. Digital AC voltmeter can also be designed using
microcontrollers.
DC Voltmeter Introduction
Digital DC voltmeter is designed to measure DC voltage using the PIC16F877A
microcontroller. A voltage divider circuit is used to divide voltage into two parts.
To prevent more than 5 volts appearing across the pic microcontroller. Because
the microcontroller can not read voltage more than 5 volts directly.

In this project, we used two types of displays namely 16×2 LCD and 4-digit
seven-segment display. In the first first section, we will see how to display a
value on LCD and in the second section, we will see how to display measured
voltage value on a 4-digit seven-segment display.
DC voltmeter with LCD display
Liquid crystal display is interfaced with the microcontroller to display measured
voltage value. Built-in analog to digital converter of pic microcontroller is used to
a measured analog voltage.
Recommended Reading
Before going further in this article about digital voltmeter using pic controller, you
should know how to interface LCD with pic16f877A microcontroller and how to
use analog to digital converter module of pic microcontroller. If you don’t know
read the following articles first:
 LCD interfacing with PIC16F877A microcontroller
 How to use ADC module of Pic Microcontroller
 Analog voltage measurement using PIC16F877A microcontroller

Digital Voltmeter with LCD display Circuit Diagram


Circuit diagram of digital voltmeter using pic microcontroller and 16×2 LCD is
given below. A 40-volt battery is used as a voltage source whose voltage you
want to measure. PIC16F877A microcontroller cannot directly read 40 volts. The
voltage divider circuit using a resistor is used to step down dc
voltage appearing across analog to digital converter pin of PIC16F877A
microcontroller.
How to Measure Dc Voltage?
Resistor R1=18k and R2=2k are used as voltage dividers. According to voltage
division formula, voltage less than 5 volts appears across pic microcontroller in
the case of maximum input voltage 40 volts.

Vout = (R2 / R1+R2 ) * Vinput


Vout = ( 2 / 18+2) * 40 = 4 volt
Hence when we apply a maximum input voltage of 40 volts, only 4 volts appear
across the pic microcontroller which is less than 5 volt. PIC16F877A
microcontroller has seven analogs to digital converter channels. It means it can
be interfaced with seven analog channels or it can measure seven analog
quantities.

ADC Channel
In this project, AN0/RA0 channel of the pic16F877A microcontroller is used. ADC
module of pic microcontroller converts an analog signal into binary numbers.
PIC16F877A microcontroller has a 10 bit ADC. So it converts an analog signal to
a 10-bit digital number which can be back converted into voltage using the
following calculation in the programming of digital voltmeter.

Resolution = (Vrer+ - Vref-) / (1024 -1);


ADC resolution is an important concept to discuss here. Resolution means
minimum value of the analog signal for which ADC counter increment by one. For
example, pic16f877A microcontroller has 10-bit ADC and it counts binary from
0-1023 for every minimum analog value of the input signal. This minimum analog
value is called resolution ADC increment by one. For example, pic16f877A
microcontroller has 10-bit ADC and it counts binary from 0-1023 for every
minimum analog value of the input signal. This minimum analog value is called
resolution.
In this project, we are taking Verf+= 5 volts and Vref- = 0 volt. Hence by using
these values in the above formula, this minimum voltage will be:

Resolution = (5 - 0)/ (1023) = 4.8876 mV;


It means for every analog signal of 4.87mV, ADC value increments by one.

Simulation Result
Liquid crystal display is used to display values of voltage. As shown in the
figure below. The below diagram shows the result of the digital voltmeter using
the pic microcontroller and LCD display.

Digital voltmeter Code MikroC


Now, let’s discuss how to write a program for digital dc voltmeter using a pic
microcontroller. Above I have discussed the function of each component and its
working in dc voltage measurement with pic microcontroller. The code for digital
voltmeter is written using the MikroC Pro compiler. Voltage measured by the
ADC module of PIC16F877A microcontroller can be calculated by following
programming commands:

voltage = ADC_Read(0); // ADC channel zero stores value in variable voltage


voltage = (voltage * 5 * 10)/ (1024); // resolution factor and voltage divider factor
Statement one is used to reading ADC value and stores its value in variable
“voltage” and in second statement voltage value is multiplied with resolution
factor and voltage divider factor to convert it into actual input voltage value.
Digital Voltmeter Code with LCD Display
This code is written using MikroC for Pic compiler. Create a new project with
MikroC compiler by selecting PIC16F877A microcontroller and set frequency to
8MHz. If you don’t know how create new project in mikroC, we suggest you read
this post:

 Write your first program in MikroC for PIC Compiler


sbit LCD_RS at RB4_bit;

sbit LCD_EN at RB5_bit;

sbit LCD_D4 at RB0_bit;

sbit LCD_D5 at RB1_bit;

sbit LCD_D6 at RB2_bit;

sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;

sbit LCD_EN_Direction at TRISB5_bit;

sbit LCD_D4_Direction at TRISB0_bit;

sbit LCD_D5_Direction at TRISB1_bit;

sbit LCD_D6_Direction at TRISB2_bit;

sbit LCD_D7_Direction at TRISB3_bit;

int Adread;

float voltage;

char volt[4];

void main() {

PORTA = 0;

TRISA = 0X01;

PORTB = 0;

TRISB = 0;

LCD_Init();
ADC_Init();

LCD_Cmd(_LCD_CURSOR_OFF);

LCD_Cmd(_LCD_CLEAR);

LCD_Out(1, 1, "Digital voltmeter");

delay_ms(1000);

while (1)

voltage = ADC_Read(0);

voltage = (voltage * 5 * 10)/ (1024);

inttostr(voltage,volt); // it converts integer value into string

Lcd_Out(2,1,"Voltage = ");

Lcd_Out(2,11,Ltrim(volt));

Lcd_Out(2,13,"Volt");

Code Working

Now let’s understand the working of code. First, we used ‘sbit’ to define pins connection with LCD and
PIC16F877A. These lines are used to define pic microcontroller pins that will be used with 16×2 LCD.

sbit LCD_RS at RB4_bit;

sbit LCD_EN at RB5_bit;

sbit LCD_D4 at RB0_bit;

sbit LCD_D5 at RB1_bit;

sbit LCD_D6 at RB2_bit;

sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;

sbit LCD_EN_Direction at TRISB5_bit;

sbit LCD_D4_Direction at TRISB0_bit;


sbit LCD_D5_Direction at TRISB1_bit;

sbit LCD_D6_Direction at TRISB2_bit;

sbit LCD_D7_Direction at TRISB3_bit;

These code lines initialize built-in library of ADC module and liquid crystal dislpay.

LCD_Init(); // intialize LCD library

ADC_Init(); // initialize ADC library

LCD_Cmd(_LCD_CURSOR_OFF); // turn off LCD cursor

LCD_Cmd(_LCD_CLEAR); // Clear whatever is written on LCD

LCD_Out(1, 1, "Digital voltmeter"); // print "Digital voltmeter"on first line and first row

delay_ms(1000); // add a delay of one second

This code is placed inside the while(1) loop function and it keeps executing. Inside this loop,
ADC_Read(0) reads analog input signal value from AN0/RA0 pins and store this value into a variable
“voltage”. Second line converts measured digital value back into analog voltage by multiplying voltage
variable with resolution factor and voltage divider scale down factor. After that we display voltage value
on LCD second line.

Before printing value on LCD, we first convert integer variable “voltage” into string by using inttostr()
routine.

voltage = ADC_Read(0);

voltage = (voltage * 5 * 10)/ (1024);

inttostr(voltage,volt);

Lcd_Out(2,1,"Voltage = ");

Lcd_Out(2,11,Ltrim(volt));

Lcd_Out(2,13,"Volt");

This digital voltmeter using a pic can read voltage only between 0-40 volt. High voltage measurement
voltmeter can also be designed using pic microcontroller and difference amplifier. The difference
amplifier will be used to step down dc voltage instead of a voltage divider.
Digital DC Voltmeter using 7-Segment
Display and Pic Microcontroller
In this tutorial, we will design a digital voltmeter using a 7-segment display and
pic microcontroller. Usually, we use LCDs to display sensor data. In the last
tutorial, we designed a DC digital voltmeter with a 16×2 Liquid crystal display. But
in this post, instead of using LCD, we will use a four-digit 7-segment display to
print voltage value. We will use the ADC module of PIC16F877a microcontroller
to measure DC voltage.
Components Required
1. PIC16F877A Microcontroller
2. 4-digital Seven Segment Display
3. Resistors
4. Crystal Oscillator
5. Capacitors
6. NPN transistors
Digital Voltmeter with 7-segment display
circuit diagram
A picture below shows the circuit diagram of DC voltmeter with four digit seven-
segment display and voltage divider circuits interfacing with PIC16F877A
microcontroller. But you can use any other pic microcontroller also.
How to measure DC voltage?
Firstly, lets discuss do we need to use a voltage divider circuit. The simple and
basic reason to use voltage divider circuit is that pic microcontroller operating
voltage is between 0-5 volts. Hence, built-in ADC module of PIC16F877A
microcontroller can read analog signal in the range 0 to 5 volts only. Therefore, in
order to measure dc voltages higher than this level, we need come up with a
solution to step down input voltage. This is the reason a voltage divider circuit is
required in this project.

A voltage divider circuit as its name suggests divides the voltage between across
two resistors. As you can see from the above circuit of dc voltmeter, we used two
resistors
R9 = 180K

R7 =20k

The formula of voltage divider is very simple that is

VOUT = (R7/(R7+R9) x VIN)

For example, if input voltage is 19 volts, the output voltage will be:

VOUT = (20k/(20k+180k) x 19) = 1.9 volts

1.9 volts is less than 5 volts. Therefore, we can measure this voltage with ADC of PIC16F877A
microcontroller. If you see from the voltage divider formula, the voltage step down or reduction factor is
20/200 = 1/10
Step down factor = 1/10

We can use this reduction factor in our programming to get actual voltage by measuring only the output
voltage of voltage divider. We will measure step -down voltage that is the output of voltage divider
circuit. But, inside our program, we will multiply measured voltage value with the reduction factor to get
actual value of input voltage.

We used analog channel AN0/RA0 of PIC16F877A microcontroller. We have already post a guide on how
to use analog digital module of Pic Microcontroller, you can read this post:

 How to use ADC of PIC Microcontroller

Connection with 4-digital seven-segment device

As you know that there are two types of 7-segment displays: namely common anode and common
cathode type. We will use a common cathode type 4-digit device to display measure voltage value.

Connect PORTD with A-g pins of 4-digital seven-segment display using 330ohm current limiting resistors.
Also connect RB0-RB3 pins of PORTB with control pins 1-4 of display device. Same data lines are used to
send binary pattern to each digit of display device, but control lines select that at which place (7-
segment) we want to display a digit.

To explore further on 7-segment displays interfacing with pic microcontrollers, go through these in-
depth guides:

 Seven-Segment displays interfacing with pic microcontroller

 How to print ADC value on 7-segment using pic microcontroller

Digital voltmeter with 7-segment display Simulation

This circuit is simulated with proteus. As you can see, we connect a 50 volts DC source with a voltage
divider circuit through a variable resistor. We use this variable resistor to apply a variable voltage to the
circuit.

We can observe the same voltage on a 4-digit seven-segment device according to the input voltage
variation.

MikroC Code

This code is written using MikroC for Pic compiler. Create a new project with MikroC compiler by
selecting PIC16F877A microcontroller and set frequency to 8MHz. If you don’t know how create new
project in mikroC, we suggest you read this post:

 Write your first program in MikroC for PIC Compiler

After creating a new project with MikroC, set configuration bits to these values:

CONFIG : $2007 : 0x2F4A

After that copy this code and compile it with MikroC for Pic compiler.

// define name to each control signal for 7-segment


sbit digit1 at PORTB.B0;

sbit digit2 at PORTB.B1;

sbit digit3 at PORTB.B2;

sbit digit4 at PORTB.B3;

// This array stores binary bit pattern that will be send to PORTD

unsigned char binary_pattern[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // without Dp


turn

unsigned char display1[10]= {0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7}; // with dp turn


on

// variables to store digits, digital value and output voltage

unsigned int a1,a2,a3,a4; // temporary variables to store data of adc

int adc_value; //store output value from Analog Read functoion

unsigned int number;

long tlong;

unsigned int voltage;

// this function retrive each digita that will displayed on device

void get_digits()

a1 = voltage / 1000u; // holds 1000's digit

a2 = ((voltage/100u)%10u); // holds 100's digit

a3 = ((voltage/10u)%10u); // holds 10th digit

a4 = (voltage%10u); // holds unit digit value

// this function displays measured voltage on seven-segments

void display_voltage()

{
PORTD = binary_pattern[a2]; // send 1000's place data to fourth digit

digit1 = 0; // turn on forth display unit

delay_ms(3);

digit1 = 1; // turn off forth display unit

PORTD = display1[a3]; // send 100's place data to 3rd digit

digit2 = 0; // turn on 3rd display unit

delay_ms(3);

digit2 = 1; // turn off 3rd display unit

PORTD = binary_pattern[a4]; // send 10th place data to 2nd digit

digit3 = 0; // turn on 2nd display unit

delay_ms(3);

digit3 = 1; // turn off 2nd display unit

PORTD=binary_pattern[a1]; // send unit place data to 1st digit

digit4 = 0; // turn on 1st display unit

delay_ms(3);

digit4 = 1; // turn off 1st display unit

void interrupt()

get_digits(); // call function to split data

display_voltage(); //call display_data() function to output value to seven segment

T0IF_bit = 0; // clear source of timer0 interrupt

void main(void)

TMR0 = 0; // timer0 reset bit

OPTION_REG = 0x83; // select prescalar value 1:16 for timer0


INTCON = 0xA0; // turn on global interrupt and timer0 overflow interrupt

TRISD = 0x00; //define PORTD as a output pin

PORTD=0x00; // initialize PORTD pins to active low

TRISB=0x00;// Set PORTB as a output port

// set control pins pins initially active high

digit1 = 1;

digit2 = 1;

digit3 = 1;

digit4 = 1;

while(1)

adc_value = ADC_Read(0); // read data from channel 0

tlong = (float)adc_value*0.488768555;

voltage = tlong;

//delay_ms(100); // wait 100 milliseconds

MPAB XC8 Code

This code is for MPLAB XC8 Compiler. If you don’t know how to use MPLAB and XC8 compiler, you can
read this complete in-depth guide:

 How to create your first project with MPLAB XC8 Compiler?

After creating a new project, set configuration bits by generating configuration bit file with MPLAB XC8.
While generating this file, select the HS crystal option and leave the remaining setting as to default
settings.

#include <xc.h>

#define _XTAL_FREQ 20000000 //define crystal frequency to 20MHz


#define digit1 PORTBbits.RB0

#define digit2 PORTBbits.RB1

#define digit3 PORTBbits.RB2

#define digit4 PORTBbits.RB3

// This array stores binary bit pattern that will be send to PORTD

unsigned char binary_pattern[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

unsigned char display1[10]= {0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7}; // with dp turn


on

unsigned int a1,a2,a3,a4;

unsigned int counter = 0;

int adc_value; //store output value from Analog Read functoion

unsigned int number;

long tlong;

unsigned int voltage;

void Analog_setting(){

ADCON0 = 0x81;

ADCON1 = 0x02;

unsigned int Analog_read(unsigned char channel){

int aadc,bbdc, ccdc;

if(channel>7)return 0;

ADCON0 = ADCON0 & 0xC5;

ADCON0 = ADCON0 | (channel << 3);

__delay_ms(2);

ADCON0bits.GO_DONE = 1;

while(ADCON0bits.GO_DONE);

aadc = ADRESH;

aadc = aadc<<2;
bbdc = ADRESL;

bbdc = bbdc >>6;

ccdc = aadc|bbdc;

return ccdc;

void main(void)

Analog_setting();

TRISD = 0x00; //define PORTD as a output pin

PORTD=0X00; // initialize PORTD pins to active low

TRISB=0X00;

digit1 = 1;

digit2 = 1;

digit3 = 1;

digit4 = 1;

while(1)

adc_value = Analog_read(0); // read data from channel 0

tlong = (float)adc_value*0.488768555;

voltage = tlong;

a1 = voltage / 1000; // holds 1000's digit

a2 = ((voltage/100)%10); // holds 100's digit

a3 = ((voltage/10)%10); // holds 10th digit

a4 = (voltage%10); // holds unit digit value

PORTD=binary_pattern[a2]; // send 1000's place data to fourth digit


digit1=0; // turn on forth display unit

__delay_ms(3);

digit1=1; // turn off forth display unit

PORTD=display1[a3]; // send 100's place data to 3rd digit

digit2=0; // turn on 3rd display unit

__delay_ms(3);

digit2=1; // turn off 3rd display unit

PORTD=binary_pattern[a4]; // send 10th place data to 2nd digit

digit3 = 0; // turn on 2nd display unit

__delay_ms(3);

digit3 = 1; // turn off 2nd display unit

PORTD=binary_pattern[a1]; // send unit place data to 1st digit

digit4 = 0; // turn on 1st display unit

__delay_ms(3);

digit4 = 1; // turn off 1st display unit

return ;

AC Voltage measurement using PIC16F877A


microcontroller
In this tutorial, we will learn to measure AC voltage using a pic microcontroller with two methods. One is
using a potential transformer and the second one is using an op-amp as a difference amplifier. That
means, in the first method, we will use a voltage transformer to step down 220V AC and in the second
method, we will use an operational amplifier as a difference amplifier to step down high AC voltage. But
for both methods, we will use pic microcontroller ADC to take AC voltage samples. For this tutorial, we
will use the PIC16F877A microcontroller. However, the logic used in this tutorial can be used with other
microcontrollers such as 8051, AVR, Arduino, Raspberry Pi, Beaglebone, etc.

You have come across many online tutorials on various websites about voltage measurement using
different microcontrollers. But all these tutorials are about measurement of low DC voltage. In this
project, you will learn how to measure high AC voltage using PIC16f877A micrcontroller.

In this tutorial, We will discuss ac voltage sensing with two methods:

1. Using the difference amplifier method.

2. Using the potential transformer method.

Alternating Voltage Measurement using Difference Amplifier Method and Pic Microcontroller

To measure 220V AC, it is necessary to step down the voltage as microcontrollers are unable to measure
voltages greater than 5V. Applying a voltage higher than 5V to the analog input of a microcontroller can
result in permanent damage. Thus, in order to protect the microcontroller, it is crucial to step down the
220V AC voltage to an AC voltage with a peak value lower than 5V. For instance, 220V AC represents the
RMS voltage, with a corresponding peak value of 311 volts. Therefore, it is essential to reduce the high
AC voltage to a level where its peak value does not exceed 5 volts.

There are two methods to step down 220 alternating voltage into low alternating voltage whose peak
value should not be greater than 5 volts.

 Potential Transformer ( All Electrical Engineering students must know about P.T and its use)

 Difference amplifier ( We will discuss the difference amplifier method in this project.)

The Potential Transformer is capable of stepping down 220 Alternating current voltage. However, why
would you want to spend more money when you can achieve this using inexpensive operational
amplifiers and just a few resistors? The difference amplifier method proves to be more economical than
using a Potential Transformer when stepping down voltages below 400 volts AC.

NOTE: Difference amplifier method is economical for voltage measurement less than 400 volt. Because
above 400 volt, this method become expensive than potential Transformer. There are reasons behind
it. I am not going to discuss reasons here.This method is suitable for final year students who want to
measure Alternating voltage and current.

Difference Amplifier circuit

The difference amplifier is a circuit used to amplify voltage between two different voltage levels. When
dealing with alternating voltage, there are two distinct voltage levels: one is positive relative to neutral,
and the other is negative relative to neutral. For more detailed information on the difference amplifier
and its applications, I would suggest conducting a search on Google.

You can adjust the gain of the difference amplifier according to your requirements by selecting the
proper values of resistors. In this project, the gain is equal to:

Gain= R8/(R1+ R2+ R3) ;


In the case of alternating voltage, the second voltage level is zero. This is because during the positive
and negative cycles, the other side is considered to be zero or neutral. As a result, the output voltage
will be zero during these cycles.

vout = gain * Vinput;

Difference amplifier to step down voltage

In the above picture, resistors R1, R2, R3, R4, and R5 have high values, which prevent high voltage from
appearing across the op-amp. The use of high input resistors ensures that the current is in the
microampere range, resulting in low power loss in the milliwatt range. According to the difference
amplifier gain formula, the gain can be calculated as follows:

gain= (22K)/( 1.2M + 1.2M + 2.2K) = 0.0091

NOTE: Please make sure to calculate the peak value of the sine wave, as the peak voltage is the
maximum voltage input to the microcontroller’s analog pin. Therefore, with a gain of 0.0091 in respect
to the peak voltage of the sine wave, the output voltage from the op-amp is:

Vout = .0091 * 311 = 2.8301 volt (peak output voltage)

In the figure above, we can observe that the other terminal of R7 is connected to the 5-volt supply
instead of the ground, which is typically done when using a differential amplifier in various applications.
The purpose of the R7 resistor is to raise the DC voltage level at the output of the op-amp. Since a sine
wave has a zero DC voltage level and negative voltage cycle, it becomes important to increase the DC
level of the sine wave by 5 volts. By doing so, we prevent any negative voltage from appearing across
the microcontroller. Consequently, the output peak voltage from the op-amp becomes 5 volts plus
2.8301 volts, resulting in a total of 7.8301 volts. However, it is important to note that microcontrollers
are unable to measure voltages greater than 5 volts. To address this, as illustrated in the figure above, a
voltage divider is employed to divide the output voltage by 2. This ensures that the output voltage level
is within the microcontroller’s measurement range.

Vout = 7.8301/2 = 3.90155;

Capacitors C1, C2, and C3 are used to filter harmonics from the input voltage and to provide protection
to the microcontroller from harmonics. Now, the AN pin can be connected to the microcontroller analog
pin to measure voltage easily.

Video lecture on AC voltmeter design

To know about how to measure analog voltage using the analog module of the PIC16F877A
microcontroller, go through the PIC microcontrollers tutorials.

 PIC MICROCONTROLLERS TUTORIALS

Circuit Diagram

To know about LCD interfacing with PIC microcontrollers, go through PIC microcontrollers tutorials.

 PIC MICROCONTROLLERS TUTORIALS

LCD displaying voltage value..

Complete circuit diagram:


Alternating voltage measurement circuit diagram

AC Voltage Measurement Code Pic Microcontroller

Code for this project is written using MikroC. To download code for AC voltage measurement click on
the link below:

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;

sbit LCD_D5 at RB5_bit;

sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;

sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

float v;

char txt[5];

char txt1[5];

void voltage_READ(void)

{
float max;

int i;

int t[40];

ADCON0.ADON=1;

for(i=0; i<=39; i++)

v= ADC_Read(0); //Digital value convert

v =v*(10.0/1023.0);

v=(v-5.0);

t[i]=v*110.1909091;

ADCON0.ADON=0;

max=t[0];

for(i=0; i<=39; i++)

if(max<t[i])

max=t[i];

max=max*.707106781;

intToStr(max, txt);

Lcd_out(1,9,txt);

delay_ms(1000);

void main()

Lcd_Init(); // Initialize LCD

ADCON0.ADCS1=1;
ADCON0.ADCS1=0;

ADCON0.ADON=0;

while(1)

Lcd_out(1,1, "Voltage:");

voltage_READ();

AC Voltage Measurement using PT and Pic Microcontroller

In this section, we will see how to measure AC voltage using a potential transformer and Pic
Microcontroller. In the last section, we have seen how to use an operational amplifier as a difference
amplifier to step down AC voltage level from 220 volts AC to less than 5 volts AC. Here, we will delve
further into the process of measuring AC voltage with the help of a potential transformer and a Pic
Microcontroller. Understanding the intricacies and the practical applications of this setup is essential for
accurate voltage measurements. By following the steps mentioned in the previous section, we can
ensure that the AC voltage is accurately measured with the help of the potential transformer and Pic
Microcontroller.

How to measure ac voltage?

Ac voltage can be measure with following methods:

 AC voltage measurement using digital millimeter

 AC voltage measurement using analog voltmeter

 AC voltage measurement using microcontroller

 AC voltage measurement using potential transformer and digital display (I will discuss this
method in this tutorial)

 AC voltage measurement using difference amplifier and pic microcontroller

As I have already discussed in this project, I will be using potential transformer to step down 220volt ac
voltage to less than 5 volt ac. I will discuss it later why we need to step down ac voltage to measure it
with the help of pic microcontroller.

Components required

Followings are the main components of ac voltage measurement project. Brief descriptions of all
components are also given below:
 Potential transformer

 Bridge rectifier

 voltage divider circuit

 Liquid crystal display

 PIC16F877A pic microcontroller

What is a potential transformer (PT)?

A potential transformer, also known as a voltage transformer, is a specific type of transformer that is
used to decrease or “step down” the magnitude of AC voltage. Its primary purpose is to measure high
voltage levels by transforming them into lower, more manageable values.

In this project, the potential transformer plays a crucial role in reducing the voltage from 220 volts AC to
12 volts AC. By utilizing a carefully calculated turns ratio, the secondary winding of the potential
transformer consists of fewer turns than its primary winding, resulting in a significant decrease in
voltage.

The turning ratio formula serves as a fundamental guideline for determining the appropriate number of
winding turns, allowing the potential transformer to effectively step down the alternating current
voltage and facilitate safe and accurate voltage measurement.

Ns/Np = Vs/Vp

What is bridge rectifier?

The bridge rectifier is an electronic circuit used to convert AC voltage into pulsating DC voltage.
Essentially, it transforms the negative cycle of AC voltage into a positive cycle. So why do we need a
bridge rectifier in this project? It’s because microcontrollers are unable to read negative voltage.
Consequently, we must convert the negative half cycle of AC voltage into a positive cycle. The bridge
rectifier is constructed by connecting rectifier diodes in a specific arrangement to form a bridge. For this
purpose, we employ 1N4007 rectifier diodes to create an H Bridge.

Voltage Divider Circuit

The voltage divider circuit, as the name suggests, is used to divide voltage. It employs two resistors to
achieve this. In this setup, a potential transformer steps down the 220V AC voltage to 12V AC. To
convert the 12V AC into pulsating DC, a bridge rectifier is used. However, it is important to note that
microcontrollers can only read voltages up to 5V. Therefore, the voltage divider circuit further divides
the voltage into two parts, ensuring that less than 5V appears across the analog-to-digital converter pin
of the PIC microcontroller. We will discuss the analog-to-digital converter in more detail later.

Liquid crystal display

Liquid crystal display or LCD is used to used to display value of measured ac voltage. 16X2 LCD is used in
this project. LCD is interfaced with pic16f877a microcontroller. IF you don’t know how to interface LCD
with PIC16F877A microcontroller, check following article:
 LCD interfacing with pic16f877a microcontroller

PIC16F877A microcontroller

PIC16F877A microcontroller is used in this project. PIC16F877A microcontroller is belongs to 16F family
of pic microcontrollers. It have built in analog to digital converters module. Some of basic features of
PIC16F877A microcontroller is given below:

 Built in analog to digital converters

 Comparator modules

 Digital input and output pins

 Serial communication

 UART communication

 I2C communication and many others.

For more information about pic16f877a microcontroller features and if you are new to microcontroller’s
worlds, check following article.

Getting started with PIC16F877A microcontrollers

Circuit diagram of how to measure ac voltage using microcontroller

The circuit diagram for measuring AC voltage is presented below. In this section, we have discussed all
the components of this project.

How to measure ac voltage using microcontroller

The input to the circuit is a 220-volt AC voltage. A potential transformer is used to step down the voltage
from 220 volts AC to 12 volts AC. After that, a bridge rectifier converts the stepped-down AC voltage into
pulsating DC voltage. A voltage divider is then used to further divide the voltage into two parts.
The voltage of less than 5 volts appears across the analog-to-digital converter pin of the PIC16F877A
microcontroller. Microcontrollers are essentially small microcomputers that only understand digital
values. The built-in analog-to-digital converter module of the PIC16F877A microcontroller converts the
analog values of the AC voltage into digital values. These digital values are then used in processing the
data within the microcontroller.

Instructions written in the form of code instruct the microcontroller on what to do. The microcontroller
itself does not perform any tasks on its own. You need to provide it with instructions by writing a
program that outlines what you want it to do.

Proteus Simulation

The diagram below shows the simulation results of an AC voltage measurement project. The LCD
displays a reading of 220 volts AC, which is measured using a microcontroller and the necessary
components connected to it, including a potential transformer.

How to measure ac voltage using pic microcontroller

Code AC voltage Measurment using PT

The program given below is written using MikroC compiler.

// LCD module connections

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;

sbit LCD_D5 at RB5_bit;


sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;

sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

// End LCD module connections

float maxpoint = 0;

int i;

unsigned int temp=0;

char ch[5];

void main()

TRISA = 0XFF;// All input

TRISB0_bit = 1;//set as input

TRISB1_bit = 1;//set as input

ADC_Init();

// Initialize LCD configuration...

Lcd_Init();

Lcd_Cmd(_LCD_CLEAR); // Clear display

Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off


while(1)

Lcd_Out(1,1,"AC voltage");

for(i=0;i<500;i++)

if(temp = ADC_Read(0),temp>maxpoint)

maxpoint = temp;

maxpoint = ( maxpoint * 5 )/ (1023) ;

maxpoint = maxpoint * 4;

maxpoint = maxpoint + 1.4;

maxpoint = maxpoint * 18;

maxpoint = maxpoint * ( 1 / sqrt(2) );

intToStr(maxpoint, ch);

lcd_out(2,1, Ltrim(ch));

maxpoint = 0;

}// while

}// void mai

These lines define the connections of the LCD module to the microcontroller’s pins. sbit stands for
“single bit” and is used to specify the pin connections for the LCD control and data lines.

// LCD module connections

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;


sbit LCD_D5 at RB5_bit;

sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

These lines define the direction of the LCD pins. TRISBx_bit are used to configure the corresponding pins
as input (1) or output (0). These lines specify that RB2 (LCD_RS), RB3 (LCD_EN), RB4 (LCD_D4), RB5
(LCD_D5), RB6 (LCD_D6), and RB7 (LCD_D7) are configured as outputs, so they will be used to control
the LCD.

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;

sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

These lines declare some variables used in the main function. maxpoint is a floating-point variable to
store the maximum voltage value measured. i is an integer variable used as a loop counter. temp is an
unsigned integer variable used to store the ADC reading. ch is an array of characters used to store the
string representation of the voltage value.

float maxpoint = 0;

int i;

unsigned int temp = 0;

char ch[5];

In the main function, after initializing the LCD, it enters an infinite loop (while(1)). The loop does the
following:

 Displays “AC voltage” on the first line of the LCD using Lcd_Out.

 It then starts a for loop that runs 500 times (from i = 0 to i < 500).

 Inside the loop, it reads an analog voltage value from channel 0 of the ADC using ADC_Read(0)
and stores it in the variable temp.

 It then compares temp with the current maxpoint value, and if temp is greater, it updates
maxpoint with the new value. This is done to find the maximum voltage value among the 500
readings.

 After the loop, it processes the maxpoint value to convert it into an AC voltage value. The exact
formula used for conversion is defined above.
 The converted voltage value is then converted into a string using intToStr and stored in the ch
array.

 The voltage value is displayed on the second line of the LCD using lcd_out.

In summary, in this tutorial, we have learned how to measure AC voltage using two different methods
and a PIC microcontroller.

You may also like to read:

 AC current measurement using PIC16F877A

 AC power measurement using PIC16F877A

 Three phase ac power measurement

 Three phase ac voltage measurement

Alternating Current Measurement using Pic


Microcontroller
In this article, we will learn alternating current (AC) measurement using a PIC microcontroller.
Specifically, we will explore the utilization of a current transformer (CT), and the PIC16F877A
microcontroller to design an AC ammeter. AC current measurement is a crucial aspect of PIC
microcontroller projects, and by the end of this article, you will possess the knowledge to create your
own AC ammeter. We will cover everything from the basics of a current transformer to interfacing the
CT with the PIC16F877A and writing the code to measure AC current.

After reading this, you will be able to design AC Ammeter using PIC16F877A microcontroller. It is a very
important task in pic microcontroller projects. I have already posted a dc current measurement
circuit with code. you can also read it.

What You Will Learn in This Tutorial

 How to use a current transformer to measure AC current

 What is the best way to interface a CT with a PIC16F877A microcontroller

 Writing your first code to measure AC current

In the first section, we will provide details of the current transformer. In the next section, we will talk
about measuring voltage from the secondary side of the CT. After that, the working of the code will be
explained.

How to Use a Current Transformer for AC Current Measurement

Current transformers (CTs) measure an alternating high current of the order of thousands of Amperes.
They step down AC current to a lower value, making it easily readable with the help of a microcontroller.
The ability to step down current depends on the rating and current step-down ratio of the current
transformer.

Suppose you have a current transformer with a current ratio of 100:10 Amperes. Its mean primary
current of the transformer is 100 Amperes, and the secondary current is 10 Amperes. You cannot use
this current transformer to measure current higher than 100 Amperes.

By measuring the low current on the secondary side, we can easily convert it into the primary current
value by using the current ratio formula. I will discuss in the latter part of this discussion how to use this
step-down ratio in the programming part.

How to Convert Current into Voltage?

We cannot measure current directly. Firstly, we convert the secondary side current into voltage. We can
use a known value of a resistor load. We measure the voltage across this known resistor. After that, we
can convert this measured voltage into the current. We can use Ohm’s Law formula to convert the
voltage into the current.

V=IR

I = V/R

As you can see in this circuit diagram, we use an R1 load resistor to convert current into voltage. In this
circuit, a voltage divider is used, but we can also use an operational amplifier to step down the voltage
across the load resistor.

How to Measure the Secondary Side Current of a CT


Now we will see how to sense AC current with the secondary side. There are many methods to measure
low alternating current. You can also measure it using an AC ammeter. But if you want to perform some
control operations and want to send the measured current value to another place, you have to use
some kind of intelligent system.

For example, let’s say you want to create a current protection circuit and the circuit specifications are as
follows:

If the current flowing through a line is greater than 100 Ampere, a control action should be performed
to operate a relay.

Current > 100 Amplere , Relay = open

Otherwise if current < 100 Ampere , Relay = close

To create such an intelligent system, we can use analog and digital electronics, but it is better to opt for
digital electronics considering cost constraints. In this tutorial, we will be utilizing a PIC microcontroller,
specifically the PIC16F877A, to measure alternating current.

You can check about the PIC16F877A pinout and its features on this link.

Hardware components

1. PIC16f877A

2. CT

3. An operational amplifier as a Difference amplifier

AC Current Measurement Circuit Using PIC Microcontroller

The operational amplifier acts as a voltage level-shifting circuit or difference amplifier. You can go
through this guide on AC voltage measurement to understand its workings.

 AC Voltage measurement using PIC16F877A microcontroller

Difference Amplifier Circuit

To measure AC current with a PIC microcontroller, we have to use the ADC module of the PIC
microcontroller. To use the ADC module, we will convert current into voltage form by using a 0.1-ohm
shunt resistor across CT, and we will measure the voltage drop across the shunt resistor. This voltage
drop can then be easily converted back into current. For example, the voltage drop across a 0.1-ohm
shunt resistor is 8V.

Then, according to Ohm’s law.

V=IR

I=V/R
I=8/.1=8A

However, the problem is the ADC of the PIC microcontroller can never measure a voltage greater than 5
volts. Therefore, to solve this problem, we can use difference amplifiers. Because by adjusting the gain
of the difference amplifier, we can reduce the voltage lower than 5 volts. The following diagram shows
the circuit of CT and difference amplifier interfacing. You can use any op-amp such as LM741, TL074.

Circuit Diagram with PIC Microcontroller

This is a circuit diagram of interfacing the current sensor with a PIC microcontroller. Connect the
secondary side of CT to the points shown on the schematic. After that, connect the shunt resistor in
parallel with the current sensor. The difference amplifier circuit converts voltage below a 5-volt
magnitude. It also shifts the level of AC voltage from the negative side to the positive side. Connect the
output of the difference amplifier with RA1 or analog channel one of the PIC16F877A.
The liquid crystal display shows the values of the current. We use PORTB to connect LCD. You can go
through this LCD interfacing guide.

 LCD INTERFACING WITH PIC16F877A MICROCONTROLLER


Pic Microcontroller AC Current Measurement Code

This code is for a PIC microcontroller to measure and display the current using an analog current
measurement circuit.

The code for this project is written in the MIKROC compiler. If you do not know how to use MikroC for
Pic, you can refer to these tutorials:

 How to Use “MikroC PRO for PIC” to Program PIC Microcontrollers

 Pic microcontroller programming in c using Mikroc Pro for PIC

// Define LCD connections to PORTB pins

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;

sbit LCD_D5 at RB5_bit;

sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

// Set the direction of PORTB pins as digital output

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;

sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

float v; // Variable to store results

// Function to read the maximum voltage across the shunt resistor

// and find the peak of AC voltage across the shunt resistor

void current_READ(void)

{
float max;

int i, current;

int t[40];

ADCON0.ADON = 1; // Enable ADC

for(i = 0; i <= 39; i++)

v = ADC_Read(1);

v = v * (10.0 / 1023.0);

v = (v - 5.0);

t[i] = v * 10;

ADCON0.ADON = 0; // Disable ADC

max = t[0];

for(i = 0; i <= 39; i++)

if(max < t[i])

max = t[i];

max = max * 0.707106781; // Convert peak into RMS

intToStr(max, txt1); // Convert integer value into a string

Lcd_out(2, 8, txt1); // Display measured current on LCD

delay_ms(1000);

void main()

Lcd_Init(); // Initialize the LCD library included in MikroC for PIC


ADCON0.ADCS0 = 1;

ADCON0.ADCS1 = 1;

ADCON1.ADCS2 = 1;

ADCON0.ADON = 0;

while(1)

Lcd_out(2, 1, "Current:"); // Display "Current" on the second line of the LCD

current_READ(); // Call the current_READ() function to measure current

delay_ms(1000);

How Does Code Work?

Here is an explanation of the code line by line:

This section defines the connections between the LCD display and the microcontroller’s PORTB pins. The
code configures the connections between the LCD display and the PIC microcontroller’s PORTB pins (RB2
to RB7) for data and control signals. It also sets the direction of these pins as digital outputs.

// Define LCD connections to PORTB pins

sbit LCD_RS at RB2_bit;

sbit LCD_EN at RB3_bit;

sbit LCD_D4 at RB4_bit;

sbit LCD_D5 at RB5_bit;

sbit LCD_D6 at RB6_bit;

sbit LCD_D7 at RB7_bit;

This section sets the direction of the PORTB pins as output, which allows them to communicate with the
LCD display.

// Set the direction of PORTB pins as digital output

sbit LCD_RS_Direction at TRISB2_bit;

sbit LCD_EN_Direction at TRISB3_bit;

sbit LCD_D4_Direction at TRISB4_bit;


sbit LCD_D5_Direction at TRISB5_bit;

sbit LCD_D6_Direction at TRISB6_bit;

sbit LCD_D7_Direction at TRISB7_bit;

It declares two global variables: float v to store measurement results, and char txt1[] (not shown in the
provided code) to store text for display on the LCD.

float v; // Variable to store results

This function current_READ() is responsible for reading the voltage values from the ADC and calculating
the peak and RMS currents. It uses a loop to read the ADC values 40 times and stores them in an
array t[]. The maximum value from the array is then taken as the peak value and converted to RMS by
multiplying it with 0.707106781. Finally, the measured current value is converted to a string and
displayed on the LCD.

// Function to read the maximum voltage across the shunt resistor

// and find the peak of AC voltage across the shunt resistor

void current_READ(void)

float max;

int i, current;

int t[40];

ADCON0.ADON = 1; // Enable ADC

for(i = 0; i <= 39; i++)

v = ADC_Read(1);

v = v * (10.0 / 1023.0);

v = (v - 5.0);

t[i] = v * 10;

ADCON0.ADON = 0; // Disable ADC

max = t[0];
for(i = 0; i <= 39; i++)

if(max < t[i])

max = t[i];

max = max * 0.707106781; // Convert peak into RMS

intToStr(max, txt1); // Convert integer value into a string

Lcd_out(2, 8, txt1); // Display measured current on LCD

delay_ms(1000);

The main() function is the entry point of the code. It initializes the LCD display using Lcd_Init() a function.
The ADC conversion clock is set and the ADC module is disabled initially. Inside the infinite while loop,
the text “Current:” is displayed on the LCD, and the current_READ() function is called to measure and
display the current value. There is a delay of 1 second before each iteration of the loop.

void main()

Lcd_Init(); // Initialize the LCD library included in MikroC for PIC

ADCON0.ADCS0 = 1;

ADCON0.ADCS1 = 1;

ADCON1.ADCS2 = 1;

ADCON0.ADON = 0;

while(1)

Lcd_out(2, 1, "Current:"); // Display "Current" on the second line of the LCD

current_READ(); // Call the current_READ() function to measure current

delay_ms(1000);

}
The code continuously measures and displays the RMS current value on an LCD screen. It assumes that
an external circuit with a shunt resistor and appropriate signal conditioning provides an AC voltage
signal to be measured by the PIC microcontroller’s ADC. The code displays the measured current value
on the LCD for monitoring purposes.

Video demo:

Conclusion

In conclusion, this article has provided a comprehensive guide to designing an AC ammeter using a PIC
microcontroller. The tutorial covered the fundamentals of current transformers, the process of
interfacing a current transformer with the PIC16F877A microcontroller, and writing the necessary code
for AC current measurement. By following the instructions and understanding the concepts presented,
readers now have the knowledge and skills to create their own AC ammeter for their PIC microcontroller
projects.

 AC voltage measurement using PIC microcontroller

 AC power measurement using PIC microcontroller

 Three-phase voltage measurement

 Three-phase power measurement using PIC16F877A

You might also like