Skip to content
Study Hall
Lesson 3 of 4Computer Interfacing
Unit 6 · Lesson 3 of 4

Analog Inputs and Sensors

Turning a temperature, a light level or a knob position into a number a program can act on.

4 min read10 practice questionsAsk AI about this →

Key things to remember

  1. 1The Uno's ADC is 10-bit: levels, reported as 0–1023 across 0–5 V.
  2. 2, and one step is about 4.9 mV.
  3. 3Use 5.0 and 1023.0 in C, or integer division silently returns 0.
  4. 4A resistive sensor needs a voltage divider, because an analog pin measures voltage, not resistance.
  5. 5Choose the fixed resistor near the middle of the sensor's resistance range for maximum sensitivity.
  6. 6A TMP36 gives 10 mV per °C with a 500 mV offset.
  7. 7Never apply more than 5 V to an analog input.

The physical world does not come in HIGH and LOW. Temperature, light, pressure and position all vary continuously, and to act on them a microcontroller must convert a voltage into a number. That conversion is done by an analog-to-digital converter, and understanding what it can and cannot represent is the whole of this topic.

An ADC turns a continuous voltage into one of a fixed number of integers.5 V0 Vtimereal voltagewhat the code seesArduino Uno: 10-bit → 2¹⁰ = 1024 levels, 0–1023. V = reading × 5.0 / 1023. One step ≈ 4.9 mV.
Fig 1A smooth voltage becomes a staircase of integers.
The Uno's ADC in one line
10-bit resolution means possible levels, reported as 0 to 1023 across 0 V to 5 V. So analogRead() returns 0 at 0 V and 1023 at 5 V, and each step is 5 ÷ 1023 ≈ 4.9 mV. Any voltage difference smaller than that is invisible to the program.
Converting an ADC reading back to volts.
Arduino CWhat it does
int raw = analogRead(A0);Read pin A0 as a value from 0 to 1023
float volts = raw * 5.0 / 1023.0;Convert to volts — note the .0 to force float arithmetic
int pct = map(raw, 0, 1023, 0, 100);Rescale a reading into a different range
int safe = constrain(pct, 0, 100);Clamp a value so it cannot go outside the range
Integer division will silently ruin this
raw * 5 / 1023 in C uses integer arithmetic and gives 0 for every reading below 205. Writing 5.0 and 1023.0 forces floating-point division. This produces no error message at all — just a program that reports zero volts forever.

How a sensor becomes a voltage

Most simple sensors are variable resistors: a light-dependent resistor (LDR) has low resistance in bright light, a thermistor's resistance falls as it warms, a force sensor's resistance drops under pressure. But an analog pin measures voltage, not resistance. The voltage divider from the electronics unit is what bridges the gap — put the sensor and a fixed resistor in series across 5 V, and read the junction between them.

Two resistors in series split the supply in proportion to their resistance.+5 VR₁ = 10 kΩV_outR₂ = 20 kΩV_out = V_in × R₂ / (R₁ + R₂)= 5 × 20 000 / 30 000= 3.33 VCurrent through both:I = 5 / 30 000 = 0.167 mAReplace R₂ with an LDR or thermistor and the output voltage becomes a sensor reading an Arduino can measure.
Fig 2Replace the lower resistor with a sensor and the output becomes a measurement.
With the sensor on top and the fixed resistor to ground: as the sensor's resistance falls, V_out rises.

Choosing the fixed resistor matters more than it looks. The divider is most sensitive when the fixed resistor is near the middle of the sensor's working resistance range. An LDR that swings between 1 kΩ in bright light and 100 kΩ in darkness pairs well with a 10 kΩ fixed resistor: the output moves across most of the 0–5 V range. Pair it with a 1 MΩ resistor instead and the output barely moves at all.

SensorWhat it measuresOutput type
PotentiometerKnob positionAlready a divider — the wiper gives 0–5 V directly
LDR (photoresistor)Light levelVariable resistance — needs a divider
ThermistorTemperatureVariable resistance — needs a divider
TMP36TemperatureOutputs a voltage directly: 10 mV per °C, with a 500 mV offset
Ultrasonic (HC-SR04)DistanceDigital — a pulse whose width encodes the time of flight
Push buttonPressed or notDigital — use digitalRead
A potentiometer is already a voltage divider
The two ends go to 5 V and ground; the wiper is the tap between the two halves. Turning the knob moves the tap, so the wiper voltage sweeps smoothly from 0 V to 5 V. No extra components are needed, which is why a pot is the ideal first analog input to test with.

Calibration

The number a sensor gives you is rarely the number you want. Calibration is the step of finding the relationship between raw readings and real units. The practical method is to record the raw reading at two known conditions, then use map() or a straight-line equation to convert between them. A TMP36 is easier because the datasheet gives you the relationship directly: the output is 10 mV per degree with a 500 mV offset, so °C = (millivolts − 500) ÷ 10.

Averaging noisy readings
Analog readings jitter by a few counts from electrical noise, which makes a display flicker and can cause a threshold to trigger repeatedly. Taking ten readings in quick succession and averaging them smooths this out for the cost of a few milliseconds — and it is almost always worth doing before comparing a reading to a threshold.
Never exceed 5 V on an analog pin
An analog input is rated for 0 V to 5 V. Applying more damages the pin and often the whole chip. If a sensor outputs a higher voltage, reduce it with a voltage divider first — two resistors, exactly as in the electronics unit.

Worked examples

Reveal one step at a time and try to beat it to the next line.

Example 1
analogRead(A0) returns 614. What voltage is on the pin, and what would a TMP36 on that pin be reading in °C?
Example 2
Design a night light: an LED on pin 9 turns on when the room gets dark, using an LDR on A0. Describe the circuit and the sketch logic.
Example 3
A student writes float v = analogRead(A0) * 5 / 1023; and every reading prints as 0.00 or 1.00. Explain and fix.

Where marks get lost

  • Using integer literals in the ADC conversion, so the result truncates to 0.
  • Connecting a resistive sensor directly to an analog pin with no divider — the pin cannot measure resistance.
  • Choosing a fixed resistor far from the sensor's range, giving a tiny usable output swing.
  • Forgetting the TMP36's 500 mV offset, which puts every reading 50 °C too high.
  • Applying more than 5 V to an analog pin.
  • Comparing a noisy reading against a single threshold with no hysteresis, so the output flickers.
  • Dividing by 1024 instead of 1023 — a small error, but the maximum reading maps to 5 V, not just below it.

Flashcards 10

What does analogRead() return on an Uno?
How many levels does a 10-bit ADC have?
Convert an ADC reading to volts
How big is one ADC step on an Uno?
+ 6 more

Practice

1
analogRead() returns 512. What voltage is on the pin? Answer in volts to 2 decimal places.
V
2
A sensor puts 1.80 V on an analog pin. What value will analogRead() return?
3
How many discrete levels can a 10-bit ADC distinguish?
levels
4
Why must a light-dependent resistor be used in a voltage divider rather than connected straight to A0?
5
In C, analogRead(A0) * 5 / 1023 gives 0 for most readings. Why?
6
A TMP36 outputs 750 mV. What temperature is that, in °C?
°C
7
An LDR is wired from 5 V to a junction, with a 10 kΩ resistor from the junction to ground. The junction feeds A0. What happens to the reading in darkness?
8
A sensor outputs up to 9 V. What must you do before connecting it to an analog pin?
9
Match each sensor to how it connects.
Potentiometer
LDR
TMP36
Push button
10
What is the smallest voltage change an Uno's 10-bit ADC can detect across a 5 V range? Answer in millivolts, to 1 decimal place.
mV

Spot a mistake on this page? Let us know