ARDUINO MULTIMETER
Complete Build Guide
Voltage • Current • Resistance • Power
Arduino Uno R3 | ACS712 | LCD 16x2 I2C
1kΩ & 330Ω Resistors | Breadboard Project
Table of Contents
1. Project Overview & How It Works 2
2. Parts List 2
3. Circuit Schematic 3
4. Component Details & Pin Functions 4
5. Step-by-Step Assembly 5
6. Arduino Code 7
7. How to Take Measurements 9
8. Calibration 10
9. Troubleshooting 10
10. Safety Rules 11
1. Project Overview & How It Works
This project turns an Arduino Uno R3 into a fully functional digital multimeter capable of measuring four electrical
quantities: Voltage (V), Current (A), Resistance (Ω), and Power (W). Results are displayed on a 16x2 LCD
screen. A single pushbutton cycles through measurement modes.
Measurement Method Range Arduino Pin
Voltage Resistor voltage divider 0 – 20 V DC A0
Current ACS712 Hall-effect sensor ±5 A or ±20 A A1
Resistance Voltage divider with Rx 0 – 100 kΩ A2
Power Calculated: P = V × I Derived —
How each measurement works
• Voltage: R1 (1kΩ) and R2 (330Ω) form a voltage divider. The junction sits at V_in × 330/1330 = V_in × 0.248.
Arduino A0 reads this scaled voltage and the firmware multiplies back by 4.03 to get the real voltage. Maximum
safe input: ~20 V DC.
• Current: The ACS712 is a Hall-effect sensor. Current flowing through its IP+ to IP- pins creates a magnetic
field; the chip converts this to a voltage output centered at 2.5 V (= zero amps). Each amp shifts the output by
185 mV (5A module) or 100 mV (20A module). Arduino A1 reads this voltage and converts to amps.
• Resistance: R3 (1kΩ) and the unknown resistor Rx form a divider from 5 V to GND. Arduino A2 reads the
mid-point. Firmware computes Rx = 1000 × ADC / (1023 – ADC).
• Power: Computed purely in software as P = V × |I|. No extra hardware needed.
2. Parts List
# Component Value / Spec Qty Purpose
1 Arduino Uno R3 ATmega328P, 5V 1 Microcontroller & ADC
2 LCD 16x2 with I2C module PCF8574, addr 0x27 1 Display readings
3 ACS712 current sensor 5A or 20A version 1 Measure current
4 Resistor 1 kΩ (brown-blk-red) 2 R1 divider + R3 ohm ref
5 Resistor 330 Ω (org-org-brn) 1 R2 voltage divider
6 Pushbutton 4-pin tactile switch 1 Mode selector
7 Breadboard 830 hole, standard 1 Component mounting
8 Jumper wires Male-to-male, mixed 15+ Connections
9 Red wire ~30 cm Insulated, stranded 1 Red probe
10 Black wire ~30 cm Insulated, stranded 1 Black probe
11 USB cable Type-A to Type-B 1 Power & programming
TIP: The ACS712 comes in three versions — 5A, 20A, and 30A. The sensitivity constant in the code must match your module.
Check the label printed on the black IC chip: it will say ACS712ELCTR-05B (5A), -20A, or -30A.
3. Circuit Schematic
The schematic below shows every connection. Filled dots (•) mean wires are joined at that point. Lines crossing
without a dot are NOT connected — they just cross over each other.
5V
GND
Arduino Uno R3
5V
GND
A0 GND
LCD 16x2
A1 VCC + I2C module
SDA
ATmega328P A2
V:00.00V A:0.000A
SCL
W:00.00W R:-----
A4/SDA
A5/SCL
Pin7
ACS712
IP+ VCC
Current Sensor
IP- GND
OUT
ACS712
5A/20A
5V / power
Current (A1) GND sense A2
Ohm SDA (pin 7)
Mode SCL Voltage sense A0
Wire legend:
R1 Mode btn
Figure 1 — Complete circuit schematic
Pin 7 / GND
1kΩ
R2
Connection reference table
330Ω
From To Wire Color Notes
R3 Red probe (+)
VIN+ RED
Arduino 5V 5V power
1kΩ (ohmrail
ref) Red Powers all components
DUT / Load
Arduino GND GND power rail Black GND BLK
Common ground
Black probe (-)
device under test
Arduino A0 R1–R2 junction Blue Voltage sense point
Arduino A1 ACS712 OUT Purple Current sense
Arduino A2 R3–Rx junction Green Resistance sense
Arduino A4 (SDA) LCD I2C SDA Orange I2C data
Arduino A5 (SCL) LCD I2C SCL Yellow I2C clock
Arduino Pin 7 Button leg 1 Gray Mode switch input
Button leg 2 GND rail Black Active-low with pullup
ACS712 VCC 5V rail Red Sensor power
ACS712 GND GND rail Black Sensor ground
ACS712 IP+ Red probe terminal Red Current in
ACS712 IP- Black probe / GND Black Current out
R1 top Red probe terminal Red Voltage input to divider
R1–R2 junction Arduino A0 Blue Scaled voltage reading
R2 bottom GND rail Black Divider reference
R3 top 5V rail Red Ohmmeter reference supply
R3 bottom Arduino A2 + Rx probe Green Resistance measurement node
LCD GND GND rail Black LCD power
LCD VCC 5V rail Red LCD power
4. Component Details & Pin Functions
Arduino Uno R3
The Arduino Uno is the brain of the project. Its built-in 10-bit ADC (Analog-to-Digital Converter) converts voltages
on pins A0–A5 into numbers from 0 to 1023, where 0 = 0V and 1023 = 5V.
Pin Function Connected to Description
5V Output Power rail + LCD + ACS Supplies 5V to all modules
GND Ground GND rail (common) Common reference ground
A0 Analog in R1-R2 junction Reads divided input voltage
A1 Analog in ACS712 OUT Reads current sensor output
A2 Analog in R3-Rx junction Reads unknown resistance
A4 SDA I2C Data LCD SDA Sends data to LCD
A5 SCL I2C Clock LCD SCL Clock signal for LCD
Pin 7 Digital in Mode button Detects button press
ACS712 Current Sensor
The ACS712 uses the Hall effect to measure current without breaking the circuit. Current flows physically through
the IC from IP+ to IP-. The chip outputs a proportional voltage on the OUT pin — 2.5V at zero amps, increasing or
decreasing depending on direction.
Pin Connect to Description
VCC 5V rail Power supply for the sensor IC
GND GND rail Ground reference
OUT Arduino A1 Analog voltage proportional to current
IP+ Red probe terminal Current flows IN here (positive terminal)
IP- Black probe / GND Current flows OUT here (negative terminal)
ACS712 Version Max Current Sensitivity Code constant
ACS712ELCTR-05B ± 5 A 185 mV per amp ACS_SENSITIVITY = 0.185
ACS712ELCTR-20A ± 20 A 100 mV per amp ACS_SENSITIVITY = 0.100
ACS712ELCTR-30A ± 30 A 66 mV per amp ACS_SENSITIVITY = 0.066
Resistors — Voltage Divider (R1 + R2)
R1 (1kΩ) and R2 (330Ω) are placed in series between the input voltage (red probe) and GND. The junction
between them is at exactly V_in × R2/(R1+R2) = V_in × 330/1330 = V_in × 0.248. This keeps the voltage safely
within Arduino's 0–5V ADC range for inputs up to ~20V.
Resistor — Ohmmeter Reference (R3)
R3 (1kΩ) is permanently connected between 5V and the Rx probe terminal. When you connect an unknown
resistor Rx between the Rx terminal and GND, R3 and Rx form a voltage divider. Arduino A2 reads the junction
voltage and the firmware calculates: Rx = R3 × ADC_reading / (1023 − ADC_reading).
LCD 16x2 with I2C Module
The LCD uses an I2C interface (via the PCF8574 expander chip soldered onto it), so only 4 wires are needed:
GND, VCC, SDA, SCL. On the Arduino Uno, SDA is A4 and SCL is A5. The small blue potentiometer on the I2C
module adjusts LCD contrast — turn it until text is clear. Default I2C address is 0x27; some modules use 0x3F.
5. Step-by-Step Assembly
Important: Always place ALL components on the breadboard before connecting any wires. This prevents mistakes and makes
the layout clearer.
Phase A — Place components
1. Place the breadboard flat, long side horizontal. Identify the two power rails (thin strips along top and bottom
edges) and the two main halves separated by the center gap.
2. Place R1 (1kΩ) horizontally, spanning the center gap, near columns 10–14 on the left area.
3. Place R2 (330Ω) directly below R1, spanning the same columns but 4 rows lower. The right pins of R1 and
R2 must share the same column to connect them.
4. Place R3 (1kΩ) horizontally about 10 columns to the right of R1/R2.
5. Place the pushbutton so its legs straddle the center gap, around columns 32–33.
6. Place the ACS712 module in the lower half of the breadboard with its pins in separate rows.
Phase B — Power rails
7. Red wire: Arduino 5V pin → red (+) column of top power rail.
8. Black wire: Arduino GND pin → blue (−) column of top power rail.
Phase C — LCD connections
9. Black wire: LCD GND → GND rail.
10. Red wire: LCD VCC → 5V rail.
11. Orange wire: LCD SDA → Arduino A4.
12. Yellow wire: LCD SCL → Arduino A5.
Phase D — ACS712 connections
13. Red wire: ACS712 VCC → 5V rail.
14. Black wire: ACS712 GND → GND rail.
15. Purple wire: ACS712 OUT → Arduino A1.
16. ACS712 IP+ will connect to the red probe terminal (done in Phase F).
17. ACS712 IP− will connect to the black probe / GND (done in Phase F).
Phase E — Voltage divider & ohmmeter
18. The right pin of R1 and left pin of R2 share a column — this is the voltage sense junction. Connect a blue
wire from this junction to Arduino A0.
19. Black wire: right pin of R2 (bottom of divider) → GND rail.
20. Red wire: left pin of R3 → 5V rail (ohmmeter reference supply).
21. Green wire: right pin of R3 → Arduino A2.
Phase F — Mode button
22. Gray wire: one leg of button (top half side) → Arduino Pin 7.
23. Black wire: opposite leg of button (bottom half side) → GND rail. No resistor needed — code uses internal
pull-up.
Phase G — Probe wires
24. Strip 5mm insulation from both ends of the 30cm red wire. Connect one end to the breadboard node that is
the left pin of R1 AND the ACS712 IP+. This is the VIN+ / red probe terminal. The bare other end is your red
probe tip.
25. Strip both ends of the 30cm black wire. Connect one end to the GND rail AND the ACS712 IP−. The other
end is your black probe tip.
26. Optionally run a third wire (any color) from the right pin of R3 — this is your Rx probe for resistance
measurements.
Double-check: With USB connected, the red rail should be at 5V and the blue rail at 0V. Use your probes to verify before
uploading code.
6. Arduino Code
Install the LiquidCrystal_I2C library by Frank de Brabander before uploading. Go to Sketch → Include Library →
Manage Libraries, search for it, and click Install.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Change 0x27 to 0x3F if LCD shows nothing
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ■■ Pin definitions ■■■■■■■■■■■■■■■■■■■■
const int PIN_VOLTAGE = A0; // R1-R2 junction
const int PIN_CURRENT = A1; // ACS712 OUT
const int PIN_OHM = A2; // R3-Rx junction
const int PIN_BUTTON = 7; // Mode button
// ■■ Calibration ■■■■■■■■■■■■■■■■■■■■■■■■
const float VREF = 5.0;
const float R1 = 1000.0; // 1kΩ
const float R2 = 330.0; // 330Ω
const float R_REF = 1000.0; // R3
const float V_RATIO = (R1+R2)/R2; // 4.03
// ACS712: change for your module version
// 5A module → 0.185
// 20A module → 0.100
// 30A module → 0.066
const float ACS_SENSITIVITY = 0.185;
const float ACS_ZERO_V = 2.5;
// ■■ Mode ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
enum Mode {MODE_ALL,MODE_VOLTAGE,MODE_CURRENT,MODE_OHM,MODE_WATT};
Mode currentMode = MODE_ALL;
unsigned long lastDebounce = 0;
bool lastBtnState = HIGH;
// ■■ Read voltage (avg 64 samples) ■■■■■■
float readVoltage() {
long sum = 0;
for(int i=0;i<64;i++) sum += analogRead(PIN_VOLTAGE);
return (sum/64.0)*(VREF/1023.0)*V_RATIO;
}
// ■■ Read current via ACS712 ■■■■■■■■■■■■■
float readCurrent() {
long sum = 0;
for(int i=0;i<64;i++) sum += analogRead(PIN_CURRENT);
float vSensor = (sum/64.0)*(VREF/1023.0);
return (vSensor - ACS_ZERO_V) / ACS_SENSITIVITY;
}
// ■■ Read resistance ■■■■■■■■■■■■■■■■■■■■■
float readResistance() {
long sum = 0;
for(int i=0;i<64;i++) sum += analogRead(PIN_OHM);
float adc = sum/64.0;
if(adc >= 1022) return -1; // open circuit
if(adc <= 1) return 0; // short
return R_REF * adc / (1023.0 - adc);
}
// ■■ Format resistance string ■■■■■■■■■■■■
String fmtR(float r) {
if(r < 0) return "OL ";
if(r < 1000) return String(r,1)+" ohm ";
if(r < 999999) return String(r/1000.0,2)+" kohm ";
return ">1Mohm ";
}
// ■■ Button handler ■■■■■■■■■■■■■■■■■■■■■■
void handleButton() {
bool state = digitalRead(PIN_BUTTON);
if(state==LOW && lastBtnState==HIGH) {
if(millis()-lastDebounce > 200) {
currentMode = (Mode)((currentMode+1)%5);
[Link]();
lastDebounce = millis();
}
}
lastBtnState = state;
}
void setup() {
pinMode(PIN_BUTTON, INPUT_PULLUP);
[Link]();
[Link]();
[Link](0,0); [Link](" Arduino Meter ");
[Link](0,1); [Link](" V A W Ohm ");
delay(2000);
[Link]();
}
void loop() {
handleButton();
float V = readVoltage();
float I = readCurrent();
float W = V * abs(I);
float R = readResistance();
switch(currentMode) {
case MODE_ALL:
[Link](0,0);
[Link]("V:"); [Link](V,2);
[Link]("V I:"); [Link](abs(I),3); [Link]("A");
[Link](0,1);
[Link]("W:"); [Link](W,2);
[Link](" "); [Link](fmtR(R).substring(0,8));
break;
case MODE_VOLTAGE:
[Link](0,0); [Link](" -- VOLTAGE -- ");
[Link](0,1); [Link](" ");
[Link](V,3); [Link](" V ");
break;
case MODE_CURRENT:
[Link](0,0); [Link](" -- CURRENT -- ");
[Link](0,1); [Link](" ");
[Link](I,4); [Link](" A ");
break;
case MODE_OHM:
[Link](0,0); [Link](" -- RESISTANCE -");
[Link](0,1); [Link](" ");
[Link](fmtR(R));
break;
case MODE_WATT:
[Link](0,0); [Link](" -- POWER -- ");
[Link](0,1); [Link](" ");
[Link](W,3); [Link](" W ");
break;
}
delay(250);
}
Upload steps: (1) Connect Arduino via USB. (2) Open Arduino IDE. (3) Select Tools → Board → Arduino Uno. (4) Select Tools
→ Port → your COM port. (5) Click the Upload button (right arrow). Wait for 'Done uploading'.
7. How to Take Measurements
Press the Mode button to cycle between five display modes: ALL → VOLTAGE → CURRENT → OHM →
POWER → ALL (repeats).
Measuring Voltage (DC)
• Touch the red probe to the positive (+) terminal of your circuit or battery.
• Touch the black probe to the negative (−) terminal or ground.
• The display shows voltage in Volts (e.g. 9.03V for a 9V battery).
• Maximum safe input: 20V DC. Do NOT exceed this.
• For best accuracy in VOLTAGE mode, press the button until the screen shows '-- VOLTAGE --'.
Measuring Current (DC)
• The probes must be connected in series with the load — break the circuit and insert the meter in the gap.
• Red probe connects to the positive supply side. Black probe connects to the load, which then connects to
negative supply.
• Example: Battery (+) → Red probe → Black probe → Resistor → Battery (−).
• Current flows through ACS712 inside the circuit. The sensor reads it without resistance loss.
• Maximum: 5A (5A module) or 20A (20A module).
Measuring Resistance
• Always disconnect power from the component before measuring resistance.
• Touch red probe to one leg of the resistor.
• Touch the Rx probe (or black probe + Rx terminal) to the other leg.
• The display shows the resistance (e.g. 999.3 ohm for a 1kΩ resistor).
• Range: 0 – ~100 kΩ. Displays 'OL' (overload) if the resistor is too large or disconnected.
Reading Power
• Power is calculated automatically from voltage and current: P = V × I.
• Both red and black probes must be connected to a live circuit simultaneously.
• Switch to POWER mode to see watts displayed in large format.
• Example: 5V circuit drawing 0.5A = 2.500W displayed.
Mode Red probe → Black probe → Rx probe → What you see
VOLTAGE V+ of your circuit V− / GND Not used Voltage in V
CURRENT Supply positive Into load (series) Not used Current in A
RESISTANCE One leg of Rx GND Other leg Ohms / kohms
POWER V+ of circuit Load (series) Not used Watts
ALL V+ of circuit Load (series) Optional V, A, W, R
8. Calibration
Component tolerances mean readings may be slightly off. Use a reference multimeter to calibrate each
measurement.
Voltage calibration
Measure a known voltage (e.g. USB 5V output) with both your multimeter and a reference meter. If your circuit
reads 5.3V and the real value is 5.0V, multiply V_RATIO by (5.0/5.3) and re-upload. Alternatively, trim R1 and R2
values in the code to match real resistor values.
Current calibration (ACS712 zero offset)
With nothing connected to the probes, the ACS712 should output exactly 2.5V → ADC reading of 512. Add
[Link](analogRead(A1)); to loop(), open Serial Monitor at 9600 baud, and read the idle value. If it reads 508
instead of 512, set ACS_ZERO_V = 508.0 * (5.0/1023.0) and re-upload.
Resistance calibration
Connect a known resistor (e.g. one of your spare 1kΩ resistors) and compare the display to the color-code value. If
the reading is consistently off, adjust R_REF in the code to the actual measured value of R3.
9. Troubleshooting
Problem Likely cause Fix
LCD is on but shows no text Contrast too low Turn the blue pot on I2C module slowly
LCD shows nothing at all Wrong I2C address or no power Run I2C scanner; try 0x3F instead of 0x27
Voltage reads zero A0 not connected or R1/R2 wrong Check R1-R2 junction wire to A0
Voltage reads wrong value Resistor tolerance Measure R1 and R2 with reference meter; update code
Current always shows ~0 ACS712 not powered or wrong pin Check VCC, GND, OUT wires on ACS712
Current reads non-zero at rest ACS zero offset Calibrate ACS_ZERO_V (see Section 8)
Resistance shows OL always Rx not connected or too large Check Rx probe connection; range is 0-100kΩ
Mode button does not work Button wired wrong Check pin 7 wire and GND connection to button
Upload fails Wrong port or board selected Tools → Board → Uno; Tools → Port → correct COM
Code compile error Library not installed Install LiquidCrystal_I2C via Library Manager
10. Safety Rules
This multimeter is designed for LOW VOLTAGE DC electronics only. It is NOT safe for mains AC electricity (wall outlets). Never
connect it to household wiring.
The voltage divider ratio limits safe input. Above 20V you risk
Maximum voltage 20V DC
damaging the Arduino ADC.
Depends on your ACS712 module version. Exceeding this
Maximum current 5A or 20A
can burn the sensor IC.
This circuit has no protection for AC. Connecting to mains
AC voltage NEVER
WILL destroy the Arduino and may cause injury.
Always power off the circuit before measuring resistance.
Powered resistance NEVER Voltage present during ohm measurement gives wrong
readings and may damage the Arduino.
Connecting probes backwards for voltage measurement
Reverse polarity Avoid returns a negative reading but does not damage. For current,
it just shows negative.
Never touch both probes together while they are connected
Short circuit Avoid
to a powered circuit in voltage mode.
Quick reference — Arduino Multimeter
Voltage (A0): max 20V DC | Current (A1): ACS712, max 5A/20A | Resistance (A2): 0-100kΩ | Power: V x I
Mode button on Pin 7 | LCD on A4 (SDA) + A5 (SCL) | Library: LiquidCrystal_I2C | I2C address: 0x27