Auto-range Ohmmeter – Theory

Part One: Theory

Sometimes you need an easy way to identify resistors laying around your workbench. Of course you can get a very inexpensive multi-meter for the task, but when you have to classify several dozen resistors you wondered if there is a better way of doing it.

When I am working on a new project, either with a breadboard or a new board to solder many times I need to fast identify a resistor and with the small 1/8 watt with five color bands I usually have a problem reading the value, as my sight is not what it use to be. I thought that it was a good idea to design an auto-ranging ohmmeter using an Arduino compatible processor. This project has several goals

  1. It should have an easy way to connect the resistor to the meter, without probe cables. Using an integrated circuit socket with round holes is a convenient way to insert the leads of the resistor and measure it.
  2. It will show a practical use of Ohm’s law and voltage dividers
  3. It will show how to use an Arduino to properly interpret the voltage in terms of resistance
  4. It will show a practical approach of using transistors as gates, as well of using a processor to turn the gates on or off.
  5. My good friends of PCBWay  offered an opportunity to develop this project and provide the prototype printed circuit board.

Here is the message from


Deeply impressed by the words on your website.

Just wanted to check if you would accept our support for your blog and projects, and we are willing to send you PCBs free of charge for getting a review blog from you, or just mention our service in your project posts. How does that sound to you ?

Please let me know your thoughts.

Best Regards


Simon Gao

PCBWay – Cherish every designer’s inspiration.

Organization of this blog

There is a lot of material that needs to be covered in this blog. You don’t need to understand all the physics or the math to build this project, but the idea is to show not only how, but why it works.

The blog is divided in three parts:

  1. Theory behind an auto-range ohmmeter.
  2. Circuit Schematic and PCB design
  3. Building the auto-range ohmmeter

Arduino programming

This blog is about how to make an auto ranged ohmmeter and will explore concepts of the Ohm’s Law and the law of conservation of energy. It will also explain how to lay out a circuit that performs the task. This tutorial is not intended to be an introduction to Arduino programming or to the Arduino microprocessor. If you need to learn more about these topics please refer to the official Arduino site:

Ohm’s Law

Ohm’s law is the fundamental principle in an electric circuit. It is very simple and can be stated as this:

 The current through a conductor between two points is directly proportional to the voltage across the two points

Current is defined as the amount of electric charge that passes through a conductor in a given amount of time. The current is measured in amperes. It is usually identified with a capital letter I.

Voltage is the difference in electric potential between two points or in other words how much more electricity is in one point compared with the other. It is identified with the capital letter V.

How to express Ohm’s Law in mathematical terms? Like this:

V ∝ I

To make ohm’s law useful in calculations we need to add a term to the expression above to replace the proportional sign  for an equal sign

V = I · R

The new term R is called a proportionality constant, and in terms of an electric circuit is called Resistance. It is measured in Ohm’s, in honor of the German physicist that discovered it in the early XIX century. The word ohm for the unit is usually represented with the Greek letter omega: Ω

One ohm is defined as the resistance one conductor must have to allow one ampere to pass through a circuit with a differential of electric potential of one volt.

Once the equation is established we can manipulate it to express any quantity in terms of the other two:

V = I · R
I = V / R
R = V / I

The following circuit will show all this relations:

Circuit 1

In the circuit above we can identify the two basic components of an electric circuit:

  • A source of energy, in this case a battery. The voltage raises from the negative terminal to the positive
  • A consumer of energy, in this circuit a resistor. The voltage drops from the top of the resistor to the bottom.

The wires that connect components also show some resistance, and in some case it is big enough to include it in the calculations. For the moment we will think of the wires as perfect conductors with zero resistance.

Any electrical circuit can be simplified to a source of energy and a consumer of the energy.

Conservation of energy

An electric battery creates a differential of potential between its terminals. The positive terminal has a higher level of energy than the negative terminal. While the terminals are not connected there is no transfer of energy. The system is stable.

Once the terminals are connected, as in the circuit above, then electricity flows from the positive terminal to the negative one, passing the resistor.

The top (positive) terminal of the battery is connected to the top terminal of the resistor. The differential of potential between the two terminals is zero, as they are at the same level

The lower (negative) terminal of the battery is connected to the lower terminal of the resistor. The differential of potential between the two terminals is zero, as they are at the same level.

What happens is that the voltage drops through the resistor all the differential of potential of the battery. This can be expressed in the law of conservation of energy:

The algebraic sum of the voltages (drops or rises) encountered in traversing any loop of a circuit in a specified direction must be zero.

The amount of current that passes through the resistor is given by Ohm’s Law:

I = V / R

If instead of one resistor there are several then the drop of voltage is spread among the resistors in the circuit. Consider this circuit with two resistors:

Circuit 2

The drop of voltage between the top of R1 and the bottom of R2 is V.  And the amount of current I in the circuit is the same as there is only one way in which the current can flow. But what happens in each of the resistors? Let’s find out.

The total amount of current in the circuit is I, and the individual drop of voltage in each resistor is:

V1 = I * R1


V2 = I * R2

The total voltage drop is of course

V = V1 + V2

And if we replace V, V1 and V2 for its equivalent in terms of I and R we have

I * R = I * R1 + I * R2

and simplifying the equation

R = R1 + R2

And this leads to an important conclusion:

In an electrical circuit with resistors in series (one after the other), the equivalent resistance or total resistance is the sum of the individual resistances.

Additional references

The following links will give you more information about Ohm’s law, and the physicists whose names were used to name the units for current, potential differential and resistance:

  • Ohm’s law. In this article you can see a formal definition of the law
  • André-Marie Ampère. Ampère was a French physicist and founder of classic electromagnetism
  • Alessandro Volta. Volta was an Italian physicist, credited as the inventor of the electric battery
  • Georg Ohm. Georg Ohm, a German physicist, was the first to formulate this seminal law in the early XIX century

Voltage Divider

In the last section we found a way to compute the total resistance of a circuit with resistors in series. But why would we want to have resistors in series? Because using the resistors in series we can set any voltage value, in between the resistors terminals. Consider this circuit:

Circuit 3

We know that the voltage between terminal 1 and terminal 3 is exactly V. But what is the voltage between terminals 1 and 2, and between terminals 2 and 3?

In the last section we saw that the voltage drop because of resistor R1 is V1 and its value is

V1 = I * R1

Since we know the value of I we can express V1 in terms of the total voltage and the resistors:

I = V / Rt
I = V / (R1 + R2)
V1 = I * R1 = V / (R1 + R2) * R1
V1 = (V * R1) / (R1 + R2)

We can find the value of V in a similar way

V2 = I * R2
V2 = V / (R1 + R2) * R2
V2 = V * R2 / (R1 + R2)

Numerical examples.

Let’s say that our battery is a 9V battery and that R1 = 100Ω and R2 = 200Ω. What are the values of V1 and V2?

V1 = 9 * 100 / (100 + 200) = 900/300 = 3V
V2 = 9 * 200 / (100 + 200) = 1800/300 = 6V

What happens if R1 = R2 = 100Ω?

V1 = 9 * 100 / (100 + 100) = 900 / 200 = 4.5V
V2 = 9 * 100 / (100 + 100) = 900 / 200 = 4.5V

As in the Ohm’s law, we can use the formula of the voltage divider to find the value of an unknown resistor. Let’s assume that we know V, V2 and R2, what is the value of R1?

V2 = V * R2 / (R1 + R2)
(R1 + R2) = R2 * V /  V2
R1 = (R2 * V /  V2)  - R2
R1 = R2 *  (V / V2 - 1)

Let’s say that V = 9V and V2 = 3V and R2 = 200Ω, what is the value of R1?

R1 = 200 * (9/3 - 1) = 200 * (3 - 1) = 200 * 2 = 400Ω

To build an ohmmeter, a device that measures the resistance, we only need a source of constant voltage, a way to measure the voltage between terminals 2 and 3 of the Circuit 3 above and a know resistor R2.

In the following sections we will see how we can use an Arduino microprocessor to measure the voltage and how to convert an Arduino into an auto ranged ohmmeter.


How to create and experiment with electronic circuits without physically building them? One way is using a simulator. Tinkercad is a web site powered by Autodesk that allows the creation of three dimensional solids and simulates electronic circuits. You can visit the site following this link:

The site is free but you need to sign up in order to create electronic circuits. Once you have access to the site you will find in the left navigator the button that opens the circuit simulator

Tinkercad circuits main page
Tinkercad Circuits Main page

There are several simulations that are used through this blog. For each of them I will add the link to the project in Tinkercad as well as an embedded simulation of it. The embedded simulation will allow you to run the simulation inside this blog, but it has the disadvantage of being small and cannot change the values of the electronic components. Follow the link to the project if you want to explore it with more detail.

Measuring Voltage

One of the features that made the Arduino microprocessor so popular is the ability to do an analog to digital conversion. Arduino features six pins that are dubbed “Analog Ports” that do a 10 bit analog to digital conversion. This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit.

When you combine the ability to read a voltage with a voltage divider you have the making of a resistance meter or ohm meter. A very simple approach is the following circuit where we setup a voltage divider using two 1KΩ resistors. You can play with the circuit and the resistance values in my Tinkercad project:

To further explore this circuit follow this link: Ohm Meter.

You can click on the “code” tab in the embedded simulation to find the Arduino code that computes the value of R1. However most of the code is devoted to display the value in the LCD screen. The following are the code lines where the value of the resistor value is computed

  float r2 = 1000.0;
  int value = analogRead(A0);
  float voltage = (value * 5.0)/ 1023.0;
  float r1 = r2 * ((5 / voltage) - 1);

If you click the code tab in the simulation above you will be able to find this lines of code.
This code will report the value read in A0 (511) and convert it to a voltage (2.5V). The results will be sent to the console using Serial.

If you are not a member of Tinkercad this is a good opportunity to become one. You will be able to copy the designs in this blog and play with them. The designs come together with the Arduino code and you can also inspect it and modify it.

Measuring a resistor

We can modify the code in the Arduino to compute the value of a resistor by using the formula:

R2 = R1 * (V / V2 - 1)

And this is the code

void setup() {

float oldValue = -1000;
float r2 = 1000;

void loop() {
  int value = analogRead(A0);
  if (oldValue != value) {
    float voltage = (value * 5.0)/ 1023.0;
    float r1 = r2 * ((5 / voltage) - 1);
    Serial.print("Value: "); Serial.println(value);
    Serial.print("Voltage: "); Serial.println(voltage);
    Serial.print("R1: "); Serial.println(r1);
    oldValue = value;

This code is very similar to the previous one with two main differences. We included the value of R2 before the loop function. The program computes the value of R1. If you change R1 in the circuit the program will report its new value.

Try running the simulation and stop it and change the value of R1. What happens to the output in the serial port?

A good value for R2

In the first paragraph of this log we discussed that the minimum voltage that can be measured with the Arduino, using a 5V reference is 0.0049 volts. Using

Vin = 5Volts
Vout = 0.0049Volts
R2 = 1000 Ohms

The value for R1 is

R1 = R2 * (Vin/Vout - 1)
R1 = 1000 * (5/0.0049 - 1)
R1 = 1000 * (1020.4 - 1) = 1000 * 1019.4 = 1019408

Using an R2 value of 1KΩ the maximum value of a resistance that can be identified would be about 1MΩ and the minimum of about 1Ω. It seems to be a good value to choose. And in theory it can be, however since the smallest voltage difference that can be detected is 0.0049, for some values the increment from one resistance to the next can be too big. For instance, when getting closer to 1MΩ a small increment in voltage represent a huge increment in resistance. For instance for

Vout = 0.0098, R1 = 511KΩ
Vout = 0.0146, R1 = 340KΩ

This means that a resistance of 400KΩ cannot be distinguished from an either 340KΩ or 511KΩ.

Another problem lies in the precision of floating point operations in an Arduino. Although the values can be computed with great precision using Excel or other spreadsheet software, that is not true for Arduino where the floating point values are stored in 32 bits and have 6 to 7 digits precision.

Instead of using one value for R2, it will be better to use several, to account for all the possible value ranges that are common with resistors. Using five different values it is possible to measure resistances from 0.1Ω all the way up to 100MΩ.

Values for R2

R2R1 minR1 max
Different values for R2 to optimize the range of values for R1

Minimum value of R1

Although it is not required, it is a good idea to add a small resistance value to the circuit, just to limit the amount of current that can go into the Arduino. A 100Ω is a good selection. This implies that the R1 the circuit will measure will be 100Ω plus the value of the unknown resistance. Once the value of R1 is computed we only need to subtract 100 to get the unknown value result. Consider next circuit:

The battery produces 9V, we have an intermediate resistor of 100Ω, then an unknow resistor and finally a 1,000Ω resistor. A voltmeter measures the voltage between terminals 2 and 3 to be 3.451V. What is the value of the unknown resistor?

Vin = 9V
Vout = 3.461V
R2 = 1000Ω
R1 = R2 (Vin/Vout - 1) - 100
R1 = 1000 * (9/3.461 - 1) - 100
R1 = 1000 * (2.6 - 1) - 100
R1 = 1000 * 1.6 - 100
R1 = 1600 - 100 = 1500
R1 = 1500Ω

This resistor is used to protect the battery and the measuring device, in this case an Arduino microprocessor by limiting the amount of current that will go in the circuit. Even if the unknown resistor is very small, like zero, the amount of current is limited to

I = V / R
I = 9 / 100
I = 0.09amp

Arranging multiple resistors to find the best value

In the following circuit there are five known resistors with a switch before each of them. When all of the switches are open, there is no voltage divider and the voltage between terminals is exactly V.

But when one of the circuits is closed, then the voltage divider circuit is complete and the voltage between terminals changes according of the values of R2.

For instance if S1 is closed then the voltage divider will be completed with the unknown resistor and the 100Ω resistor.


The image above is the rendition in Tinkercad of the schematic. The red array of switches has all the switches in the off position. The voltage is 9V, the same as the battery.

When the switch 1 is closed, the voltage divider with the 100Ω resistor is established and the voltage changes.

If you open switch 1 and close switch 2 then the value of the voltage is different.

Run the simulation and you will find out that the values of the output voltage are the ones in the following table:

Switch ClosedResistor valueOutput VoltageUnkown Resistor Value

It is clear that although all values of R2 gave us an idea of the value of R1, there is one that is better that the others, in this case R2 = 1KΩ. Since R1 is relatively small compared with 100KΩ or 1MΩ, the limitation in the voltmeter precision yields poor values. How to choose the better value for R2? The better value of R2 for any given resistor is the one that provides an output voltage closer to 1/2V.

Try playing with the model in Tinkercad. Change the value of R1 and see wich value of R2 is better

Using transistors as switches.

A transistor is a sandwich of two classes of semi-conductor material. How a transistor works is beyond this blog, and you can find excellent sources just Googling “How a transistor works“.

For our project we will be using generic NPN transistors. The diagram for this device will help to understand how it works:

When the enable signal is zero, no current passes from the more positive to the more negative. In effect the circuit is open.

When a positive current is applied to the enable signal the current in the more positive side flows to the more negative side. This closes the circuit.

The following diagram shows how to use a transistor with the voltage divider.  We will connect the enable signal pin to the Arduino processor to enable and disable the reading of the voltage. As we are using five different values for R2 we will need five connections to the Arduino. We will test each value and the software will select the best value.


Using an Arduino to select the value of R2

The only concept we need to add to our design is to be able to select the value of R2, and thus compute the better value for R1 using a micro processor, like Arduino. Instead of the switches we use in the last section we are going to use the ability of an Arduino to change the value of a pin, to turn on or off a transistor circuit. A basic transistor circuit looks like this

In this configuration the program in the Arduino tries to find the best value for R2 and with it the value of R1. Each transistor is connected to a digital output in the Arduino. When the output is set to HIGH then the corresponding transistor closes the circuit and a voltage value is read in the analog port 0. The program tries each transistor and uses the value of R2 that yields a voltage closest to 512.

The code in the sketch above includes the management of the LCD display. The core of the functionality is this:

void loop()
  int r2Index = 0;
  int minDiff = 1000;
  int bestValue = 0;
  for (int index = 0; index < 5; index += 1) {
    int pin = index + 3;
    digitalWrite(pin, HIGH);
    int value = analogRead(A0);
    digitalWrite(pin, LOW);
    int diff = abs(value - 512);
    if (diff < minDiff) {
      r2Index = index;
      minDiff = diff;
      bestValue = value;
  float vout = (bestValue * vin) / 1023;
  float r2 = r2values[r2Index];
  float r1 = round(((vin / vout) - 1.0) * r2) - 100.0;

  printLabelValue("Value: ", bestValue);
  printLabelValue("R1   : ", r1);

Arduino and transistors schematic

This is the configuration of the Arduino used as an auto range ohmmeter using transistors to select the best value for R2. Notice that each transistor is connected to a digital port on the Arduino. In this schematic the LCD display is not included because it add complexity that is not needed for the basic circuit.

End of theory

This is the end of this blog on how it works. In the next one we will design the schematic and the printed circuit board. Stay tuned