This is a project based on Arduino board which can measure the unknown AC and DC voltages. When we connect the unknown voltage on the breadboard circuit, the 16*2 LCD displays the voltage value. The project uses an Arduino pro mini board whose ADC feature is used along with the concept of Voltage Divider circuit to develop thisVoltmeter. It is assumed that the reader has gone through the project how to get started with the arduino and interface 16×2 LCD display.

*Fig. 1: Prototype of Arduino based AC Voltmeter*

__Architecture of the project__

The entire project can be divided into three basic blocks;

1) AC/DC Voltage Sensor Unit

2) Processor Unit

3) Display Unit

*Fig. 2: Block Diagram of Arduino based AC Voltmeter*

The Sensor Unit takes two inputs, DC voltage and AC voltage. The Sensor Unit scales down the input DC and AC voltages into a DC voltage in the range of 0 to 5 V and provides the same as output.

The Processor Unit takes input voltage in the range of 0 to 5V. This unit takes the Sensor Unit’s output as input voltage and uses the ADC to read this voltage. An Algorithm is then applied tocalculate the voltage. The unit then sends a 4bit data to the Display Unit which includes the AC and DC voltage values.

The Display Unit takes the 4bit data from the Processor Unit and produces a 16×2 display for AC and DV voltages.

**1) AC/DC Voltage Sensor Unit**

A basic voltage divider circuit is used as the AC/DC Sensing Unit to scale down the input DC and AC voltages into a DC voltage in the range of 0 to 5 V. The Processor Unit can read this scaled down voltage and calculate the actual AC/DC voltages.

**Design the value of R1:**

Let us first select a maximum voltage that could be measured as 500V. When we apply 500V as ‘V’, the ‘V2’ should not be more than 5V and hence ‘V1’ will be 500 – 5 = 495V. At very high voltages like 495, the first thing to be taken care of is the power rating of the resistor We are using resistors with the power rating 0.25W, and the power consumed by the resistor ‘R1’ should be less than this, otherwise the resistors get heated up and catch fire.

The equation for power is, P = V1^{2} / R1.

Where;

P Power rating of the resistor

V Voltage across the resistor

R Resistance of the resistor

For the resistor R1 with power rating 0.25 W and 495 V across it,

0.25 = 495 * 495 / R1

Or, R1 = 980100 ohms, take 1 M ohm standard resistor.

**Design the value of R2:**

Now the value of R2 can be calculated using the previous equation, V = V2 * (1 + R1 / R2) as follows;

R2 = R1 / ((V / V2) – 1)

R2 = 1000000 / ((500 / 5) – 1)

R2 = 10101 ohms, take 10K ohm standard resistor.

**DC voltage as input:**

*Fig. 3: Circuit Diagram of a typical voltage divider network used for sensing voltage*

The voltage ‘V2’ is a fraction of the actual applied voltage ‘V’. The applied voltage ‘V’ can be calculated from the fraction of applied voltage ‘V2’ with the help of the following equation.

DC voltage, Vdc = V2 * (1 + (R1 / R2))

**AC voltage as input:**

When we are applying an AC voltage we use a rectifier diode in series with the Voltage divider circuit to prevent the negative cycles from entering the circuitry. No need for step down transformers because we are already getting a voltage ‘V2’ in the range of 0 to 5 V only, across R2.

*Fig. 4: Image showing rectified output at Voltage Divider Circuit to avoid negative cycles*

**Requirement for Range selector:**

We require multiple ranges in avoltmeter due to the error appears in readings because of Resistance Tolerance.

a) Decrease in the ratio of R1/R2 decreases the error

b) There is a limit beyond which the R1/R2 cannot decrease further:

To measure different values of V with minimum error we need different set of R1 with a common R2. The voltage V whose value need to be measured is connected with an R1 which gives the least ratio of R1/R2, taking care of the fact that V2 should not go above 5V range.

(R1 / R2) > (V / 5) – 1

For example to measure V = 500V, R1 / R2 > 99, hence we can use the set R1 = 1M and R2 = 10K which gives R1 / R2 = 100.

*Fig. 5: Circuit Diagram of Voltage Sensor used in Voltmeter*

## Processor and Display Unit

**2) Processor Unit**

The processor unit in this project is the Arduino board and it uses the ADC module to read the output voltage from the Sensor Unit. In the Arduino board we are using an 8 channel, 10 bit ADC with the reference voltage pin connected to 5 V. The ADC reads the voltage V2 and generates an equivalent value ‘Value_{ADC}‘at the ADC register.

The voltage output from the Sensor Unit V2 is calculated using the following equation;

V2 = Value_{ADC} * V_{RESOLUTION}

Where;

V_{RESOLUTION }is the ‘ADC Voltage Resolution’ or the minimum voltage that the ADC can detect for a given reference voltage and given number of output bits.

Calculating for a ‘V_{REFRENCE}’ of 5V and ‘RESOLUTION’ of 10 bits, we get the value

V_{RESOLUTION} = 5V / 1024 = 4.88 milli Volts

*Fig. 6: Overview of ADC Channels in Arduino Uno*

**Measuring DC voltage:**

The code running in the Arduino obtains the ‘Value_{ADC}’, which then used to calculate the voltage ‘V2’ with the help of following equation;

V2 = Value_{ADC} * 4.88, milli Volts

The following section of the code calculates the maximum V2 voltage from 5000 voltage samples, taking multiple samples helps in obtaining maximum voltage of sinusoidal AC waveform.

for(sample_count = 0; sample_count < 5000; sample_count ++)

{

adc_value = analogRead(A0);

if(voltage_peak_value < adc_value)

voltage_peak_value = adc_value;

else;

delayMicroseconds(10);

}

dc_voltage_V0 = voltage_peak_value * 0.00488;

Once ‘V2’ is obtained the value of appliedAC or DC voltage ‘V’ is calculated using the known values of ‘R2’, ‘V2’ and ‘R1’ with the help of previously discussed equation;

DC voltage, Vdc = V2 * (1 + (R1 / R2))

The following section of the code calculates and displays the DC voltage for (R1/R2) = 10;

lcd.print(” DCV”);

lcd.setCursor(0, 1);

lcd.print(“50 “);

lcd.print(dc_voltage_V0 * 10 * range50_cal);

**Measuring AC voltage:**

The ADC of the Arduino then measures the maximum DC voltage or the Peak voltage ‘Vp’ of the AC waveform.

Vp = Vdc_{max}

*Fig. 7: Image showing Peak Voltage on an AC Waveform*

The Voltage of the sinusoidal AC voltage is then expressed in terms of its ‘Root Mean Square’ (RMS) value. The RMS is an equivalent DC voltage value corresponding to a sinusoidal AC waveform, which can provide the same amount of Power to a device as the sinusoidal AC voltage does.

The RMS value of the AC voltage V_{RMS} can be calculated from the Peak voltage ‘Vp’ using the following equation;

AC voltage Vac = V_{RMS} = Vp * 0.7071 = Vdc_{max}* 0.7071

The voltage drop at the rectifier diode also needs to be considered, hence

AC voltage Vac = Vdc_{max}* 0.7071 + 0.7

The following section of the code calculates the maximum V2 voltage from 5000 samples to obtaining maximum voltage of sinusoidal AC waveform.

for(sample_count = 0; sample_count < 5000; sample_count ++)

{

adc_value = analogRead(A0);

if(voltage_peak_value < adc_value)

voltage_peak_value = adc_value;

else;

delayMicroseconds(10);

}

dc_voltage_V0 = voltage_peak_value * 0.00488;

ac_voltage_V0 = dc_voltage_V0 / 1.414;

The following section of the code calculates and displays the DC voltage for the ratio of R1/R2 = 10;

lcd.print(” ACV”);

lcd.setCursor(0, 1);

lcd.print(“50 “);

lcd.print(dc_voltage_V0 * 10 * range50_cal);

**3) 16×2 LCD module**

This is a standard 16*2 LCD on which the Arduino displays the resistor value. The LCD has been wired in four bit mode to reduce the number of output pins of the Arduino board to be used.

*Fig. 8: Typical Image of character LCD*

## Circuit and Code Description

__Circuit Description__

*Fig. 9: Circuit Diagram of Display Unit, Range Selector and Voltage Sensor Circuits used in making AC Voltmeter*

The complete circuit diagram of the Arduino based Voltmeter is given in which the voltage to be measured ‘V’ is connected across the Voltage Divider circuit whose ‘R1’ value can be selected using a range selector switch. In the following section let us discuss how to calculate the values of R1 and R2.

The voltage ranges are selected using the Function/Range selector switch as shown in the following table; Value 1 indicates switch closed and value 0 indicates switch open.

R0 |
R1 |
RANGE |

0 |
1 |
5V |

1 |
0 |
50V |

1 |
1 |
500V |

R2 |
FUNCTION |

0 |
DC VOLTAGE |

1 |
AC VOLTAGE |

__Code Description__

The code continuously read the ADC register for a while to get the maximum value appearing. Using this maximum value the DC and AC voltages are calculated for all the voltage ranges.The code then displays the DC voltage and then the AC voltage on the 16*2 LCD. The code identifies the function and range to display by reading the values of Function/Range selector switch.

The code running in the Arduino used the library function analogRead() to obtain the ADC value and lcd.print() to display the data on 16*2 LCD.

*Fig. 10: Flowchart representing Arduino Code used for measurement of AC voltage*

**Note :**

When measuring high voltages, please ensure your safety.

### Project Source Code

#include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); #define resistance_R50 100000 #define resistance_R500 1000000 #define resistance_V2 10000 #define caliberation_V2 1.1 #define range50_mul (resistance_R50 / resistance_V2) * caliberation_V2 #define range500_mul (resistance_R500 / resistance_V2) * caliberation_V2 #define resistance_Ri 10 #define resistance_Cr 100000 #define resistance_Rb 100000 #define resistance_Re 10 #define resistance_R2 1000 int adc_value = 0; int voltage_peak_value = 0; int discharge_voltage_V0 = 0; int discharge_voltage_V1 = 0; float voltage_average_value = 0; float dc_voltage_V0 = 0; float ac_voltage_V0 = 0; float dc_voltage_V1 = 0; float dc_voltage_V2 = 0; float ac_voltage_V1 = 0; float dc_current_I0 = 0; float dc_current_I1 = 0; float ac_current_I0 = 0; float dc_power = 0; float ac_power = 0; float npn_pnp_hfe = 0; float capacitance = 0; unsigned long resistance; unsigned long sample_count = 0; unsigned long discharge_time_T0 = 0; unsigned long discharge_time_T1 = 0; char fn0 = 6; char fn1 = 7; char fn2 = 8; char rn0 = 9; char rn1 = 10; char rn2 = 13; char function_select [4]; char range_select [4]; void setup() { lcd.begin(16, 2); lcd.print(" EG LABS "); delay(3000); pinMode(fn0, INPUT); pinMode(fn1, INPUT); pinMode(fn2, INPUT); pinMode(rn0, INPUT); pinMode(rn1, INPUT); pinMode(rn2, INPUT); } void loop() { function_select [0] = digitalRead(fn0) + '0'; function_select [1] = digitalRead(fn1) + '0'; function_select [2] = digitalRead(fn2) + '0'; function_select [3] = ''; range_select [0] = digitalRead(rn0) + '0'; range_select [1] = digitalRead(rn1) + '0'; range_select [2] = digitalRead(rn2) + '0'; range_select [3] = ''; //=============================== VOLTAGE ========================================// voltage_peak_value = 0; for(sample_count = 0; sample_count < 5000; sample_count ++) { adc_value = analogRead(A0); if(voltage_peak_value < adc_value) voltage_peak_value = adc_value; else; delayMicroseconds(10); } dc_voltage_V0 = voltage_peak_value * 0.00488; ac_voltage_V0 = dc_voltage_V0 / 1.414; if ( 0 == strncmp (range_select, "01", 2) ) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("[R] "); if (range_select [2] == '0') lcd.print(" DCV"); else lcd.print(" ACV"); lcd.setCursor(0, 1); lcd.print("0-5 "); if (range_select [2] == '0') lcd.print(dc_voltage_V0); else lcd.print(ac_voltage_V0); delay(500); } else; if ( 0 == strncmp (range_select, "10", 2) ) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("[R] "); if (range_select [2] == '0') lcd.print(" DCV"); else lcd.print(" ACV"); lcd.setCursor(0, 1); lcd.print("5-50 "); if (range_select [2] == '0') lcd.print(dc_voltage_V0 * range50_mul); else lcd.print(ac_voltage_V0 * range50_mul); delay(500); } else; if ( 0 == strncmp (range_select, "11", 2) ) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("[R] "); if (range_select [2] == '0') lcd.print(" DCV"); else lcd.print(" ACV"); lcd.setCursor(0, 1); lcd.print("50-500 "); if (range_select [2] == '0') lcd.print(dc_voltage_V0 * range500_mul); else lcd.print(ac_voltage_V0 * range500_mul); delay(500); } else; //=================================================================================// }