Skip to main content

PIC16F688 based Digital Voltmeter

Actually this is the another version of my older DVM project that was based on PIC12F683. The older version displays the measured voltage on a LCD that is driven serially by PIC12F683 using 3 I/O pins. The new one uses PIC16F688 microcontroller that doesn't require the serial driver as it has got enough pins to drive a LCD directly in 4-bit mode. The theory and math is just the same. You can read my PIC12F683 version of this project here.

Circuit Diagram

Circuit on breadboard

Important: You need a regulated +5V supply for accuracy of the output. The ADC uses Vdd as the reference for conversion, and all computations are done with Vdd = 5V. You can get a regulated +5V using a LM7805 linear regulator IC.
 My source for a regulated +5V using LM7805

My variable power supply source for testing the DVM

Read the detail theory and math involved in this project here.

Use mikroC compiler to compile this code. Use options Internal Clock @ 4 MHz, MCLR Enabled, and Power-Up Timer Enabled.

  Digital Voltmeter based on PIC16F688
  Rajendra Bhatt, Oct 12, 2010

// LCD module connections
sbit LCD_RS at RC4_bit;
sbit LCD_EN at RC5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC3_bit;
sbit LCD_RS_Direction at TRISC4_bit;
sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC3_bit;
// End LCD module connections

char Message1[] = "DVM Project";
unsigned int ADC_Value, DisplayVolt;
char *volt = "00.0";

void main() {
  ANSEL = 0b00000100; // RA2/AN2 is analog input
  ADCON0 = 0b00001000; // Analog channel select @ AN2
  ADCON1 = 0x00;
  CMCON0 = 0x07 ; // Disbale comparators
  TRISC = 0b00000000; // PORTC All Outputs
  TRISA = 0b00001100; // PORTA All Outputs, Except RA3 and RA2
  Lcd_Init();        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);             // CLEAR display
  Lcd_Cmd(_LCD_CURSOR_OFF);        // Cursor off

do {

   ADC_Value = ADC_Read(2);
   DisplayVolt = ADC_Value * 2;
   volt[0] = DisplayVolt/1000 + 48;
   volt[1] = (DisplayVolt/100)%10 + 48;
   volt[3] = (DisplayVolt/10)%10 + 48;
  } while(1);


The DVM has been tested with various input voltages ranging from 0-20 V and found to be very accurate. Here are some of the pictures of testing.


  1. '
    volt[0] = DisplayVolt/1000 + 48;
    volt[1] = (DisplayVolt/100)%10 + 48;
    volt[3] = (DisplayVolt/10)%10 + 48;
    You can read more? What is +48?

  2. +48 is to convert the numeric value to the equivalent character's ASCII value. The LCD is character display.

  3. I am new to MikroC but have some experiance with PIC. Can you help me by explaining the following lines ?

    DisplayVolt = ADC_Value * 2;
    volt[0] = DisplayVolt/1000 + 48;
    volt[1] = (DisplayVolt/100)%10 + 48;
    volt[3] = (DisplayVolt/10)%10 + 48;

    Measured voltage is got on DisplayVolt, then what the need for next 3 lines.Lcd_Out(2,5,volt); will display the value of volt in 2nd line 5th position of LCD Display

  4. volt[] contains the string of characters to be displayed (DisplayVolt is an integer) and you are right, it will display in the second row, 5th columns.

  5. i dont understand want means ICSP header?..and what are the connection pin from ICSP going??..

  6. I am new and I had wanted to build it but you never listed all the components u used and how you arranged them on the board so I mind it pretty Hard yo try...


Post a Comment

Popular posts from this blog

Contact less tachometer using PIC16F628A

Tachometer is a device that gives you the information about the rotational speed of any shaft or disc. It usually measures the speed in revolutions per minute (RPM). Today we are going to make a simple tachometer that could measure the rotation speed of a disk without making any physical contact (that's why it is contact less) with the rotating object. The range of this tachometer is 0 - 9999 RPM and displays the RPM on a multiplexed 4-digit seven-segment display. Of course, we are going to do this project on our usual PIC16F628A development board.

Infrared sensor
Contact-less measurement of RPM will be achieved through an IR sensor. An IR diode will send a beam of infrared towards the rotating disc, and any reflected pulse will be received by a photo diode. The resistance of a photo diode drops drastically when exposed to infrared. An infrared is reflected by a white surface and absorbed by the dark ones. The test disc for this project is shown below. You can see the …

Experiment No. 2 : Push Button and Seven Segment Display Interface

In this experiment, we will program the PIC16F628A as an UP/DOWN Decade Counter. The count value will be displayed on a Seven-Segment Display and will be incremented/decremented by two push buttons on the board.

Experimental Setup:
The board has built in interface for a multiplexed 4-digit seven segment display (HS-5461AS2 from will select only one digit by connecting a Digit Select pin to Vcc, as shown in figure below. A black jumper wire is used for this purpose. The seven segments will be driven through PORTB (already wired on the board). Connect Push Buttons (PB3 and PB4) to RA1 and RA0 female headers using jumper wires.

PIC16F628A Development Board

The development board we are going to make for our experimental microcontroller PIC16F628A will look like this. Here are the features it is going to have:
Access to all I/O pins through female header pins4 Push Buttons for Input4 LEDs for OutputAn LCD Interface PortA 4-digit Seven-Segment Display InterfaceLCD Backlight Switch and Contrast AdjustmentICSP Programming (Very Important)