
Discover how you can build a professional digital multimeter using Arduino that measures up to 24V DC voltage, checks resistance, conducts diode testing, and performs continuity tests. This comprehensive Arduino based multimeter project provides full circuit diagrams, programming code, and even a 3D printed enclosure design.
A multimeter is a must-have tool in your arsenal when it comes to creating or developing electrical circuits. Without it, executing a job will be extremely tough. So, in this post, we chose to create a low-cost digital multimeter using Arduino and other basic components. When it comes to the multimeter's functions, it can measure voltage up to 24V, as well as diode, resistance, and voltage drop across an LED. It also includes a continuity feature with a buzzer, so you can use it to identify short circuits. Previously, we have built many projects in the field of measuring instruments, like
You can check the above projects if you are interested in the topics.
Table of Contents
What is an Arduino Digital Multimeter?
An Arduino digital multimeter is a multipurpose measuring device that uses an Arduino microcontroller. It combines multiple electrical measurement features into a single device, and as a DIY digital multimeter, electronics enthusiasts can use our project as a low-cost equivalent to an expensive multimeter, while they learn about analog-to-digital conversion, voltage dividers, and embedded programming.
Our digital multimeter project has four important measurement modes.
- Arduino Voltmeter - Measures DC voltage from 0-24V
- Ohmmeter mode - Measure resistance
- Diode and LED - Measure forward voltage drop
- Continuity - Can listen for continuity with audio output.
Components Required for Arduino Based Multimeter
Components required to build a digital multimeter project circuit are simple and can be easily found in your local store; the complete list of components is given below.
- Arduino Pro Micro - 1
- Push Button - 1
- 1K Resistor - 1
- 10K Resistor - 1
- 4.7K Resistor - 2
- Active Buzzer - 1
- 0.91” 128x32 OLED - 1
- Toggle Switch - 1
- Banana Socket - 4
- 3.7V, 300mA lithium Battery - 2
- AMS1117-5.0 - 1
- Perf Board - 1
- Connecting Wires - 1
Digital Multimeter Circuit Diagram and Working Principle
The complete schematic diagram of the Arduino Digital Multimeter is shown below. The schematic is simple and easy to understand. This shows a systematic approach to measurement using Arduino's ADC (anolog-to-digital converter). It is beneficial to understand the digital voltmeter connection diagram for ease of assembly and calibration.
The working of the schematic is simple: we have an Arduino working as the brain of our project. In the circuit, we have used two pairs of banana connectors to connect the external input. As you can see in the above diagram, we have a 10K resistor and two 4.7K resistors in parallel to form a voltage divider. With this voltage divider configuration and Arduino, we can measure the input voltage up to 24V. Please note that input voltage more than 24V can damage the device. Next, we have another pair of banana sockets that are for testing continuity, the Diode and LED. These tests are done by measuring a certain voltage drop across the test device. We have also connected a 0.91” OLED display to display all the data processed by the Arduino, and we have a push button switch for toggling between all features of this multimeter. Finally, we have two 3.7V battery packs in series and an AMS1117-5.0 5V regulator to power the total circuit. The voltmeter using Arduino employs a precision voltage divider network.
We previously used Arduino to build many test and measurement instruments:
- Frequency Counter using Arduino
- Arduino Ohm Meter
- Capacitance Meter using Arduino
- LC Meter using Arduino: Measuring Inductance and Frequency
- Measure Sound/Noise Level in dB with Microphone and Arduino
Find all the test and measurement-related projects here.
Digital Multimeter Using Arduino Programming
Arduino based multimeter programming is very simple and easy to understand. The complete code for a digital multimeter using Arduino programming is shown below.
We start our code by including all the required libraries; for that, we need to include SPI.h and Wire.h, Adafruit_GFX.h, Adafruit_SSD1306.h to control the OLED display.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Next, we have defined the screen_height and screen_width of the display, and we have defined the screen address of the OLED Display.
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Finally, we have created an instance of the Adafruit_SSD1306 library named display.
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Next, we initialised all the required variables that are required by the code.
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 10000.0; // resistance of R1 (100K) -see text!
float R2 = 2200.0; // resistance of R2 (2.2K) - see text!
int value = 0;
int mode = 0;
int interval = 300;
unsigned long previousMillis = 0;
int raw = 0;
int Vin = 5;
float Vout = 0;
float R11 = 1000;
float R22 = 0;
float buffer = 0;
Next, we have our setup function. In the setup function, we first initialise the serial, and we have made the ADC pins and switch pin as input, and we have made the other pins as output.
Serial.begin(9600);
pinMode(analogInput, INPUT);
pinMode(9, OUTPUT);
pinMode(7, INPUT_PULLUP);
digitalWrite(9, HIGH);
delay(40);
digitalWrite(9, LOW);
pinMode(13, OUTPUT);
Next, we have used the begin() method of the display instance to initialise the display.
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
}
Next, we have our void loop() function inside the loop function. We have four modes. The modes can be changed by the mode switch. Mode 0 is the voltage measurement function, mode 1 is for the diode test mode, mode 2 is for the ohm meter mode, and finally, we have the continuity test mode. We will explain all the modes in this section.
In mode 0, we read the analog pin A0 and store the value in the variable. Now we store the value in the value variable. Now we calculate the measured value and store it in the vin variable. Now we display the data on the OLED display.
if (mode == 0) {
// Measure Voltage
value = analogRead(A0);
vout = (value * 5.0) / 1024.0;
vin = vout / (R2 / (R1 + R2));
if (vin < 0.09) {
vin = 0.0; //statement to quash undesired reading !
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Voltmeter Mode");
display.setTextSize(2);
display.setCursor(10, 12);
display.print((vin));
display.print("V");
display.display();
}
Next, we have mode1 and mode 1. We have to read pin A2 and calculate the voltage drop across the resistor and diode. Please refer to the schematic if you are having a hard time understanding the part.
if (mode == 1) {
// Diode Test
value = analogRead(A2);
vout = (value * 5.0) / 1024.0; // see text
vout = 5 - vout;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Diode/LED Test");
display.setTextSize(2);
display.setCursor(10, 12);
display.print((vout));
display.print(" V");
display.display();
}
Next, we have our mode2. Mode 2 is the OHM meter mode. In this mode, we read the ADC data from the A2 pin of the Arduino, and we have calculated the resistor value using the following code.
if (mode == 2) {
// OHM Meter
raw = analogRead(A2);
buffer = raw * Vin;
Vout = (buffer) / 1024.0;
buffer = (Vin / Vout) - 1;
R22 = R11 * buffer;
Serial.print(Vout);
Serial.print("R2: ");
Serial.println(R22);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("OHM Meter Mode");
display.setTextSize(2);
display.setCursor(2, 12);
if (R22 < 1000) {
display.setCursor(2, 12);
display.print((R22));
display.print(" OHM");
}
else {
display.setCursor(10, 12);
display.print((R22 / 1000));
display.print(" K");
}
display.display();
//delay(300);
}
Finally, we have mode3. In mode 3, we check the continuity function of the digital multimeter. In this condition, we check the resistance value, and if the value is less than 100, we sound the buzzer.
if (mode == 3) {
// Continuity Test Mode
raw = analogRead(A2);
buffer = raw * Vin;
Vout = (buffer) / 1024.0;
buffer = (Vin / Vout) - 1;
R22 = R11 * buffer;
Serial.print(Vout);
Serial.print("R2: ");
Serial.println(R22);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("continuity Test Mode");
display.setTextSize(2);
display.setCursor(2, 12);
display.print((R22));
display.print(" OHM");
display.display();
if (R22 < 100) {
digitalWrite(9, HIGH);
}
else {
digitalWrite(9, LOW);
}
}
previousMillis = currentMillis;
}
Finally, we have another if condition. In this, we have checked the button status. If the button status is low, we increment the mode counter.
if (digitalRead(7) == LOW) {
delay(150);
mode++;
if (mode >= 4)
mode = 0;
Serial.println(mode);
}
This marks the end of the code portion for the digital multimeter.
Technical Summary and GitHub Repository
The Technical Summary highlights the project’s design, workflow, and core functionality in a concise manner. The GitHub Repository complements it with complete code, schematics, and resources for hands-on replication.
Designing a Cover for a Multimeter with Fusion 360
Once the circuit was completed, we decided to build a cover for the multimeter to hide the batteries and to make it look a little neater. The enclosure looks like the image shown below
You can download the STL File for this enclosure by clicking on the link. Once the print was done, it looked like the image shown below.
Testing the Digital Meter with Arduino
Once the build process was completed, we started testing the overall features of this project, and the results we got are shown below
We started our testing process by testing voltage with the voltmeter and found out it needs a little bit of calibration, because in the voltage measurement mode, it was showing a 200mV difference when we compared it to a conventional multimeter. Comprehensive testing validates the DIY digital multimeter performance across all measurement modes.
Next, we have the diode/LED Test Mode. In this mode, you can check the voltage drop across the diode or LED.
In the above image, you can see that we have connected a white LED, and you can see the forward voltage drop across the LED.
Next, we have Diode Test Mode connected to a diode, and as you can see, the meter is showing the forward voltage drop across the diode. The diode under test is a Schottky diode, so the 0.6V drop is very accurate.
Finally, we have continuity test mode. In this mode, as you can see, we have shortened the two alligator clips, and the multimeter shows the resistor value of the wire, and the buzzer is also making a sound.
Troubleshooting Common Issues
Problem | Possible Cause | Solution |
Inaccurate voltage readings | Resistor tolerance variations | Software calibration or precision resistors |
No OLED display | Wrong I2C address or wiring | Check connections and address (0x3C) |
Buzzer not working | Incorrect pin connection | Verify pin 9 connection and polarity |
Mode switching issues | Button debouncing problems | Add software debouncing delay |
These are all the features that this multimeter has to offer, but there is a lot of room for improvement. By using an additional IC, we can reduce the banana sockets to only a single pair. We can replace the Arduino with an ESP to add additional wireless capabilities. Also, the circuit can be made on a PCB for better mechanical stability.
Frequently Asked Questions on Digital Multimeter using Arduino
⇥ 1. What is the maximum voltage level I can safely measure with this Arduino digital multimeter?
The home-built digital multimeter can measure a maximum of 24V DC voltage without causing damage to itself or the Arduino. The voltage divider circuit will lower the input voltage to the 5V level needed by the Arduino's ADC. It should be noted that the voltage divider circuit should never exceed 24V, or components of the digital multimeter product could be damaged.
⇥ 2. How accurate is this Arduino multimeter in comparison to a store-bought, similar multimeter?
If calibrated properly, this digital multimeter project has a range of accuracy at ±2-5% for voltage and resistance. Store-bought multimeters provide similar values of accuracy, and often have ±0.1-1%. The multimeter's accuracy provides a level of accuracy that is fine for most hobbyist projects.
⇥ 3. Does this digital multimeter measure AC voltage or current?
No, this Arduino digital multimeter design only measures DC voltage and resistance. To take AC measurements, additional components and circuits would be required, such as rectifiers and current-sensing resistors. However, those additional measures are excluded from this simplified design.
⇥ 4. How long can you expect this do-it-yourself digital multimeter to last on battery?
With two 300mAh 3.7V batteries, expect around 8-12 hours of continuous usage. Battery usage time will vary based on the levels of OLED (light) brightness and how often the buzzer (for continuity testing) is tripped on and off.
⇥ 5. Why does the Arduino-based voltmeter display values when there is nothing plugged in?
Floating inputs can be subject to electrical noise. The program has a 0.09V limit to filter out these spurious readings. Grounding and shielding enhance measurement stability.
⇥ 6. Can you change the digital multimeter circuit to a higher voltage
If the resistor values of the voltage divider are changed. For a 50V range, you would use R1 = 39kΩ and R2 = 4.7kΩ. Just remember to double-check your calculations and use higher voltage-rated components. Annotate that you must also check the resistor wattage rating and voltage rating for safety. Once changes are made, don't forget to research to determine the new accuracy or calibrate the multimeter product.
⇥ 7. What Arduino libraries will I require for this digital multimeter project?
For the digital multimeter project, you will need the Adafruit_GFX library for graphics, the Adafruit_SSD1306 library for working with the OLED display, the Wire library for I2C communication, and the SPI library for the display. All of these libraries can be installed through the Library Manager while inside the Arduino IDE.
This tutorial was created by the Circuit Digest engineering team. Our experts focus on creating practical, hands-on tutorials that help makers and engineers master Raspberry Pi projects, Arduino, and IoT development projects.
This is the end of this project, and if you have any questions regarding this article, you can comment down below, or you can ask in our forum.
DIY Projects Involving a Multimeter
We have applied the multimeter in various exciting projects; you can explore them through the links below.
Newbie Guide - How to Use a Digital Multimeter
In this article, we will learn how to use a digital multimeter and how this will help us in our journey with electronics. This will be a very basic article which will take you through the different operations of a multimeter with illustrative pictures and videos.
How to Test if a Multimeter is Working & Tips to Use it Properly
This tutorial will show you how you can test if your multimeter is working, and if it is working, I will also give you a few tips on how to use this device. So, let’s first start with testing whether the multimeter is working or not.
From Multimeter to Alarm Clock: Fluke 87V Transformation
Join us as we explore the evolution of this extraordinary project, filled with ingenious upgrades that showcase the power of DIY engineering. Get ready to dive into the fascinating world of the Fluke 87V Alarm Clock and discover the magic of DIY engineering.
Complete Project Code
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 10000.0; // resistance of R1 (100K) -see text!
float R2 = 2200.0; // resistance of R2 (2.2K) - see text!
int value = 0;
int mode = 0;
int interval = 300;
// Tracks the time since last event fired
unsigned long previousMillis = 0;
int analogPin = 0;
int raw = 0;
int Vin = 5;
float Vout = 0;
float R11 = 1000;
float R22 = 0;
float buffer = 0;
void setup() {
Serial.begin(9600);
pinMode(analogInput, INPUT);
pinMode(9, OUTPUT);
pinMode(7, INPUT_PULLUP);
digitalWrite(9, HIGH);
delay(40);
digitalWrite(9, LOW);
pinMode(13, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
}
void update_display(String val)
{
}
void loop()
{
unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillis) >= interval) {
if (mode == 0)
{
value = analogRead(A0);
vout = (value * 5.0) / 1024.0; // see text
vin = vout / (R2 / (R1 + R2));
if (vin < 0.09) {
vin = 0.0; //statement to quash undesired reading !
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Voltmeter Mode");
display.setTextSize(2);
display.setCursor(10, 12);
display.print((vin));
display.print("V");
display.display();
}
if (mode == 1)
{
value = analogRead(A2);
vout = (value * 5.0) / 1024.0; // see text
vout = 5 - vout;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Diode/LED Test");
display.setTextSize(2);
display.setCursor(10, 12);
display.print((vout));
display.print(" V");
display.display();
}
if (mode == 2)
{
raw = analogRead(A2);
buffer = raw * Vin;
Vout = (buffer) / 1024.0;
buffer = (Vin / Vout) - 1;
R22 = R11 * buffer;
Serial.print(Vout);
Serial.print("R2: ");
Serial.println(R22);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("OHM Meter Mode");
display.setTextSize(2);
display.setCursor(2, 12);
if (R22 < 1000)
{
display.setCursor(2, 12);
display.print((R22));
display.print(" OHM");
}
else
{
display.setCursor(10, 12);
display.print((R22 / 1000));
display.print(" K");
}
display.display();
//delay(300);
}
if (mode == 3)
{
raw = analogRead(A2);
buffer = raw * Vin;
Vout = (buffer) / 1024.0;
buffer = (Vin / Vout) - 1;
R22 = R11 * buffer;
Serial.print(Vout);
Serial.print("R2: ");
Serial.println(R22);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("continuity Test Mode");
display.setTextSize(2);
display.setCursor(2, 12);
display.print((R22));
display.print(" OHM");
display.display();
if(R22 < 100)
{
digitalWrite(9, HIGH);
}
else
{
digitalWrite(9, LOW);
}
}
previousMillis = currentMillis;
}
// Use the snapshot to set track time until next event
//previousMillis = currentMillis;
if (digitalRead(7) == LOW)
{
delay(150);
mode++;
if (mode >= 4)
mode = 0;
Serial.println(mode);
}
}