Make a Two Range Voltmeter (DVM) With Auto / Manual Range Select Using the Arduino
by Rick-ecircuit in Circuits > Arduino
564 Views, 5 Favorites, 0 Comments
Make a Two Range Voltmeter (DVM) With Auto / Manual Range Select Using the Arduino

Create a Multi-Range Voltmeter (4V, 20V) using a Resistor Divider and a pair of Solid-State Relays (opto-isolated). A Low-Pass Filter removes unwanted noise. The Arduino's ADC converts the input voltage to a digital number. The C Code drives the Solid-State Relays via Digital Outputs, converts the ADC's digital value to an equivalent input voltage and sends the result to the serial monitor.
Run one of two C programs for either Manual (pushbutton) or Auto Range Selection. You can customize the hardware / software for a higher voltage range with the included Design Equations and Excel Calculator.
Specifications
- Voltage ranges: +4V and +20V.
- Input R: 1M both ranges
- Display update: 0.25s
- Low-Pass Filter: fc = 6Hz
- Pushbutton for manual range select
- Accuracy
- 4V Range: Verror = ±15mV ±1.5% of Reading
- 20V Range: Verror = ±75mV ±1.5% of Reading
- Measurement overange: 25%
- 4V Range: +5V
- 20V Range: +25V
Schematic and Circuit Overview

Input Attenuator
For input voltages > 5V, a Resistor Divider is needed to scale down the input to less than 5V (ADC's max input range). Two MOSFET based Solid-State Relays (SSR) select either a direct unity-gain connection (SW1) or the tap on a resistor divider (SW2). Driving digital outputs D12 or D13 to 0V will pull current through the SSR's LED, turning on the switch.
The R Divider scales down the input voltage by a 5:1 ratio or 0.2 (ideally). Given the actual available resistor values we get.
K = v1/vin = R2/(R1+R2)
= 200k/(825k+200k)
= 0.195
The input resistance for both ranges can be calculated by
Rtot = R1+R2
= 200k+825k
= 1.025 M
Low-Pass Filter
A filter reduces external noise sources (60 Hz mains, system clocks, radio frequencies, etc.) that can be picked up by the circuit causing unwanted fluctuations on the signal being digitized by the ADC.
The filter passes the measured input signal below the cutoff frequency, fc.
fc = 1/(2*pi*RP1*CP1)
= 1/(2*pi*200k*0.15uF)
= 5.3 Hz
10-Bit ADC
The ADC converts the Analog input voltage (0 to 5 V) to a Digital output value (0 to 1023 counts). For the Lower Voltage Range (<5V), signals are passed directly to the ADC. For the Upper Voltage Range (>5V) the Resistor Divider Scales down input signal to less then 5V. The Arduino code then futher converts the Digital Value to an equivalent Input Voltage before the resistor divider (see Code section below).
The ADC produces an ouput based on the input voltage (Vadc) and a Refrence Voltage (Vref) which is the Aurduino's 5V Power Supply Level. For example, an ADC input of 2.5V produces an output code of
ADCword = Vadc / Vref * 210
= 2.5V/5.0V*1024
= 512 counts
Push Button
For manual selection of the Voltage Range, a push button creates one of two voltages connected to the Arduino's Digital input D11.
- OPEN - 5V through D11's internal pull-up resistor (logic 1)
- CLOSED - 0V through the closed switch (logic 0)
The Code will monitor the pushbutton's signal and toggle the Voltage Range when the button is pressed causing a 1 to 0 logic transition.
Arduino Interface
- 5V,GND - Power for Opto-Relays
- A0 - Analog input voltage representing input voltage.
- D12,D13 - Digital outputs to drive 2 Opto-Relays SW1 and SW2.
- D11 - Digital input to read state of the pushbutton SW3.
- USB - PC Interface and Power from the PC.
Parts List
Feel free to select alternate components for preference / availability / cost. The critical components required to meet the Accuracy Spec are the 0.1% resistors R1=825k and R2=200k. However, you can use 1% resistors with a relaxed accuracy. Also, you can also alternate resistors values close to those specified, just ensure you enter the R1 and R2 values in the code (see below).
Arduino
- 1 Arduino Uno Rev3 Microcontroller Board A000066
- 1 USB Cable Type A/B (generic)
ProtoBoard
- 1 Solderless Breadboard, SparkFun Electronics PRT-12002
- 1 Pkg Jumper Wires, Various Lengths, M to M, Adafruit Industries
- 2 Test Leads, Gator to Gator, BLK, RED (generic)
Components
- 2 (SW1,2) SSR RELAY SPST-NO 500MA 0-60V "TLP592A(F)
- 1 (R1) RES 825K OHM 0.1%, ≥1/10W
- 1 (R2) RES 200K OHM 0.1%, ≥1/10W
- 1 (RP1) RES 200K OHM ≤5%, ≥1/10W
- 1 (CP1) CAP CER 0.15UF ≥50V, ≤10% X7R
- 2 (R3,R4) RES 1K OHM ≤5%, ≥1/10W
- 1 (SW3) SparkFun Electronics COM-00097 Push Button
Build It - Arduino UNO + Protoboard

With the Solderless Protoboards, you can easily test, modify and experiment with your design. (Wiring diagram created at www.cirkitstudio.com/)
Please note, the diagram above is only a suggestion. Arrange parts and wire the circuit anyway you prefer!
Code 1 - Manual Range Select

The Arduino's C Code follows the flow chart above.
Convert ADC Word to Input Voltage
For best accuracy, the resistor divider values are entered into the R1 and R2 variables.
float R1 = 825000; // Rdivider
float R2 = 200000; // Rdivider
The input divider gain is calculated according to voltage range
If Vrange=0 (LOW Range), then Kdiv = 1.0
If Vrange=1 (HIGH Range), then Kdiv = R2/(R1+R2)
Lastly, the Digital ADCword is converted to an Analog value by the factor Vref/2^10 and scaled to the equivalent input voltage by 1/Kdiv.
// Vinput = ADCword * Vref/2^N * 1/Kdiv
Vinput = ADCword * (5.0 / 1024.0) * 1/Kdiv ;
Solid-State Relay Control
Driving D12 or D13 low, turns ON SW1 or SW2.
If Vrange=0, then SW1=ON, SW2=OFF for direct connection.
If Vrange=1, then SW1=OFF, SW2=ON for connection to R Divider.
Manual Range Selection (Pushbutton)
You can configure D11's digital input to enable an internal pull-up resistor. This handy feature saves you a resistor and a couple of wires.
pinMode(buttonPin, INPUT_PULLUP);
The code checks for a 1 to 0 state transition of the pushbutton to toggle the Voltage Range between LOW and HIGH.
if (lastButtonState == 1 && buttonState == 0) {
TOGGLE RANGE code
}
Sample / Display Time
A delay of 0.25s is added at the end of the Main Loop for an approximate sample / display rate of 4 per second.
delay(250);
This means that the pushbutton must be held down for 0.25s max to read the 1 to 0 transition.
Downloads
Code 2 - Auto Range Select
The Auto Range code is identical to the Manual Select except the PushButton code is replaced with a Range Select based on input level.
During each program loop, the code simply checks the input level and sets the Voltage Range accordingly.
If Vinput > 4.90V, then set HIGH Range
If Vinput < 4.85V, then set LOW Range
Notice the LOW threshold is 50mV less than the HIGH threshold! This difference (hysteresis) avoids continuously toggling between the HIGH/LOW ranges if both thresholds are at 4.9V and Vinput is at 4.9V with some noise fluctuations.
Downloads
Try It!
It's easy to try, just grab a couple of household batteries!
- 1.5V Battery Health: 1.1 to 1.6V typical
- 9V Battery Health: 7.0 to 9.0V typical
Manual Range Select
Run the code: DVM1_basic_voltmeter1.ino
- The Serial Monitor will display: Vinput, ADCword, pushButton, Vrange
- Default values: pushButton = 1 (open), Vrange = 0 (LO Range)
Press the Push Button
- Does the pushButton transition from 1 to 0?
- Does the Vrange change from 0 (LOW RANGE) to 1 (HIGH RANGE)?
- Push the button again, does Vrange toggle back LOW?
Battery Health Check
- Connect a 1.5V Battery on the LOW Vrange and check the voltage.
- Connect a 9V Battery on the LOW Vrange. You should see a max reading near 5V.
- Press the pushbutton to change to the HIGH Range.
Auto Range Select
Run the code: DVM1_basic_voltmeter_auto1.ino
- The Serial Monitor will display: Vinput, ADCword, Vrange
- Default values: Vrange = 0 (LO Range)
Battery Health Check
- Connect a 1.5V Battery. The Range should auto switch to Vrange = 0.
- Connect a 9V Battery. The Range should auto switch to Vrange = 1.
Explore More!
If you've made it this far - high fives for you! The DVM showcases many key concepts of electronic measurement circuits and software, even for a basic instrument as this.
You can dive deeper into the circuit theory or customize the design for a different HIGH voltage range. Check out the following design files and links.
Design Equations
- DVM1_Design_Eqns.pdf (See attached)
Design Calculator
SPICE Simulation
Take a walk through the DVM Design from Specification development to Circuit Design, Coding and Final Test.