Digital ChallengeArduino × Processing
P4Project module

Arduino Ohm Meter with Processing Display

Turn your Arduino into a measuring instrument.

Build a digital ohm meter: a voltage divider with one known resistor lets Arduino calculate an unknown resistance using Ohm’s law, and Processing shows the result like a real instrument.

2 × 45 min difficultyPhysicsMathematicsTechnology
Arduino Ohm Meter with Processing Display
Ohm’s lawRearranging formulasADC resolutionnf() formattingGauges
01Before you start

What you’ll learn

By the end of this module you can…
  • 1Apply Ohm’s law and the voltage-divider rule to a real circuit.
  • 2Rearrange the divider formula to solve for an unknown resistor.
  • 3Convert ADC readings to voltage and estimate measurement accuracy.
  • 4Handle edge cases (open circuit, short circuit) in code.
  • 5Present a measurement professionally with units and formatting.
Key vocabulary
Ohm’s law
U = R · I — voltage equals resistance times current.
Series circuit
Components connected one after another; the same current flows through all of them.
Reference resistor
The known resistor (R_known) used to compare against the unknown one.
Resolution
The smallest change an instrument can detect. The Uno ADC: 5 V / 1023 ≈ 4.9 mV.
Tolerance
How far a real resistor may differ from its printed value (gold band = ±5 %).
02Kit list

Required equipment

ComponentQtyPurpose
Arduino Uno1Microcontroller
Known resistor (e.g. 1 kΩ)1Reference for the voltage divider
Unknown resistorsseveralComponents to measure
Breadboard + jumper wires1 setComponent connection
USB cable1Connection to computer
Processing IDE1Display
03Theory

Voltage Divider & Ohm’s Law

Two resistors in series share the 5 V supply. The voltage at the midpoint depends on their ratio — so if we know one resistor and measure the voltage, we can calculate the other.

Formula
V_A0 = V_in × R_known / (R_x + R_known)
R_x (unknown) sits between 5V and A0, R_known between A0 and GND — exactly as in the diagram.
Formula
R_x = R_known × (V_in / V_A0 − 1)
Rearranged to solve for the unknown resistor.
Corrected from the original handbook
The original wiring table placed the known resistor on the 5V side, which does not match the diagram or the formula. This edition follows the diagram: unknown on top (5V → A0), known on the bottom (A0 → GND).
Note
The larger the unknown resistor, the lower the voltage at A0. Accuracy is best when R_x is close to R_known.
InteractiveVirtual ohm meterVirtual ohm meter: pick resistors and see the voltage, ADC reading and calculated result.
Known resistor R_known
V_A0 = 5 × 1.00 kΩ / (2.20 kΩ + 1.00 kΩ) = 1.563 V
analogRead = round(1.563 / 5 × 1023) = 320
R_x = 1.00 kΩ × (5 / 1.564 − 1) = 2.20 kΩ
1101001k10k100k1M2.20 kΩ
Real value
2.20 kΩ
Measured
2.20 kΩ
Error
-0.14%

Try R_x = 1 MΩ with R_known = 1 kΩ: the voltage is so small that one ADC step is a huge change in resistance. Accuracy is best when R_x ≈ R_known.

04Hands-on

Step 1 — Circuit Setup

Unknown resistor between 5V and A0; known resistor between A0 and GND.
Unknown resistor between 5V and A0; known resistor between A0 and GND.
ConnectionDescription
R_x (unknown)Between 5V and A0
R_known (e.g. 1 kΩ)Between A0 and GND
A0Junction between R_x and R_known
Tip
Measure your known resistor with a multimeter first and type the exact value into the code — that alone improves accuracy.
05Hands-on

Step 2 — Arduino Code

OhmMeter.inoArduino · C++
const int analogPin = A0;
const float Vin = 5.0;
const float R_known = 1000.0;     // known resistor in ohms

void setup() {
  Serial.begin(9600);
}

void loop() {
  int raw = analogRead(analogPin);
  if (raw == 0) {
    Serial.println(-1);           // nothing connected (open circuit)
  } else {
    float Vout = raw * Vin / 1023.0;
    float Rx = R_known * (Vin / Vout - 1);
    Serial.println(Rx);           // send resistance to Processing
  }
  delay(500);
}
UpdatedFixed the vconst typo and added a guard for an open circuit (division by zero).
06Hands-on

Step 3 — Processing Code

OhmDisplay.pdeProcessing · Java
import processing.serial.*;

Serial myPort;
float resistance = 0;

void setup() {
  size(400, 200);
  myPort = new Serial(this, Serial.list()[0], 9600);
  myPort.bufferUntil('\n');
}

void draw() {
  background(255);
  fill(0);
  textSize(20);
  text("Measured Resistance:", 50, 80);
  if (resistance < 0) text("no resistor", 50, 120);
  else                text(nf(resistance, 1, 2) + " \u03A9", 50, 120);
}

void serialEvent(Serial p) {
  String val = p.readStringUntil('\n');
  if (val != null) resistance = float(trim(val));
}
  • ▸Arduino reads the voltage at the midpoint of the divider.
  • ▸It calculates the unknown resistance with the rearranged formula.
  • ▸The value is sent over serial to Processing.
  • ▸Processing displays it in real time with units.
07From the original handbook

Student tasks

Basic
Display the resistance value as text
Intermediate
Colour the text based on the resistance range
Advanced
Draw a dial / gauge visualization
Challenge
Log multiple measurements and plot a graph
08When it doesn’t work

Troubleshooting

ProblemLikely causeFix
Shows “no resistor” or a huge valueR_x not connected / open circuitCheck both legs of R_x are in the right rows.
Shows ≈ 0 ΩR_x shorted (both legs in the same row)Place each leg in a different row.
Reading is inaccurateR_known value in code is wrongMeasure R_known and update the constant.
Fluctuating valuesPoor breadboard contactAverage 10 readings; press parts in firmly.
Golden rule
Check the physical connections first, then the code. If nothing works, unplug, close both programs, reconnect and try again.
09New in this edition

Exercises

Basic · 2Intermediate · 2Advanced · 1Challenge · 1
P4.1BasicCalculate 10 min

Derive the formula

Starting from V_A0 = V_in · R_known / (R_x + R_known), show step by step that R_x = R_known · (V_in / V_A0 − 1).

Multiply both sides by (R_x + R_known), then divide by V_A0, then subtract R_known.
V_A0 (R_x + R_known) = V_in · R_known → R_x + R_known = V_in · R_known / V_A0 → R_x = R_known · V_in / V_A0 − R_known = R_known (V_in / V_A0 − 1) ✓
P4.2BasicCalculate 10 min

From reading to ohms

With R_known = 1 kΩ, Arduino reads raw = 310. Calculate V_A0 and R_x. Which standard resistor is it probably? (1 kΩ, 2.2 kΩ, 3.3 kΩ, 4.7 kΩ)

V_A0 = 310 × 5 / 1023 ≈ 1.515 V → R_x = 1000 × (5 / 1.515 − 1) ≈ 2300 Ω → most likely a 2.2 kΩ resistor (within ±5 %).
P4.3IntermediateDebug 15 min

Debug the textbook

The first edition of this handbook said: “R1 (known) between 5V and A0, R2 (unknown) between A0 and GND” but used the formula R2 = R1 · (Vin/Vout − 1). Using R1 = 1 kΩ and a real unknown of 2.2 kΩ, calculate what the meter would display. What is the correct formula for that wiring?

First find the real Vout for that wiring: Vout = 5 × 2200 / (1000 + 2200).
Vout = 5 × 2200/3200 = 3.44 V. Wrong formula: 1000 × (5/3.44 − 1) ≈ 455 Ω — completely wrong! For that wiring the correct formula is R2 = R1 · Vout / (Vin − Vout) = 1000 × 3.44 / 1.56 ≈ 2200 Ω ✓. Lesson: always check that the formula matches the circuit.
P4.4IntermediateCode 15 min

Colour by range

Colour the displayed value: green below 1 kΩ, orange 1 kΩ–10 kΩ, purple above 10 kΩ. Also display large values in kΩ (e.g. 4.70 kΩ).

solutionProcessing · Java
String label;
if (resistance < 1000) {
  fill(0, 170, 80);
  label = nf(resistance, 1, 1) + " \u03A9";
} else {
  fill(resistance < 10000 ? color(255, 140, 0) : color(130, 60, 200));
  label = nf(resistance / 1000.0, 1, 2) + " k\u03A9";
}
textSize(36);
text(label, 50, 140);
P4.5AdvancedCode 25 min

Analog gauge

Draw a semicircular gauge (like an old multimeter) from 0 to 10 kΩ with tick marks every 1 kΩ and a needle pointing at the current value.

Use arc(cx, cy, d, d, PI, TWO_PI). Map resistance to an angle between PI and TWO_PI.
Gauge.pde (draw part)Processing · Java
void drawGauge(float value, float maxValue) {
  float cx = width / 2, cy = height - 30, r = 150;
  noFill();
  stroke(40);
  strokeWeight(3);
  arc(cx, cy, r * 2, r * 2, PI, TWO_PI);

  strokeWeight(1);
  for (int i = 0; i <= 10; i++) {                        // ticks
    float a = map(i, 0, 10, PI, TWO_PI);
    line(cx + cos(a) * (r - 12), cy + sin(a) * (r - 12),
         cx + cos(a) * r,        cy + sin(a) * r);
  }

  float a = map(constrain(value, 0, maxValue), 0, maxValue, PI, TWO_PI);
  stroke(220, 40, 40);                                   // needle
  strokeWeight(4);
  line(cx, cy, cx + cos(a) * (r - 20), cy + sin(a) * (r - 20));
}
P4.6ChallengeDesign 40 min

Accuracy investigation

Measure at least 8 resistors (100 Ω … 100 kΩ) with your Arduino meter and a real multimeter. Calculate the percentage error for each. Plot error vs. resistance. When is your meter most accurate, and why? Propose an improvement (e.g. auto-ranging).

Expected result: smallest error when R_x ≈ R_known; errors grow for very small or very large R_x, because V_A0 approaches 5 V or 0 V where one ADC step (≈ 4.9 mV) represents a large change in resistance. Improvement: switch between several known resistors (auto-ranging) and average multiple readings.
10Check yourself

Self-check quiz

Progress
0/5 answered · 0 correct
  1. Q01

    Ohm’s law states…

  2. Q02

    In this circuit, if R_x gets bigger, V_A0…

  3. Q03

    If R_x = R_known, the reading on A0 is about…

  4. Q04

    Why does the code check raw == 0?

  5. Q05

    What does nf(1234.5678, 1, 2) return?

11Beyond the classroom

Real world & extensions

Where this is used
digital multimetersbattery and sensor testingquality control in electronics factoriestouch and force sensors (resistance changes)thermistor temperature sensors
Extension ideas
  • +Automatic resistor classification by range
  • +An analog-style gauge in Processing
  • +Show the resistor colour code next to the measured value
  • +Measure potentiometers and watch the value change
  • +Log measurements to CSV and compare with tolerances
  • +Auto-ranging with several known resistors
Cross-curricular connections
SubjectConnection
PhysicsOhm’s law, series circuits, voltage division
MathematicsRearranging equations, error and percentages
TechnologyMeasurement instruments, calibration
12Think about it

Reflection & conclusion

?1

How does a commercial multimeter measure resistance? Is it similar to your circuit?

?2

What sources of error did you notice? Which could you reduce?

?3

Why is it important that a formula matches the actual circuit? Where else in science does this matter?

Conclusion

This project introduced electrical measurement, voltage dividers and real-time display. By combining the Arduino Uno with Processing you built a working ohm meter, practised rearranging formulas, and learned to question whether a formula really matches the circuit in front of you — a core skill for every engineer.