Fanlab

Robotics · Microcontrollers · Grade 7

Analogue input and the Serial Monitor

A night light that switches itself on in the dark: where do the numbers 0–1023 come from, and why does the light flicker?

Open the experiment

The situation

A night light in a corridor switches itself on when evening comes and off at dawn — nobody presses a button. Inside are a photoresistor and a small “brain”. An Arduino can be such a light too: the analog input A0 gives not a voltage but a number from 0 to 1023. First, with a potentiometer, we find out where these numbers come from and watch them in the Serial Monitor, then we connect the photoresistor. We dim the desk lamp — the light comes on… but at dusk it flickers. Why? 1024 levels, `map()`, a threshold and hysteresis — it is all in this experiment.

Topic

Analogue input and the Serial Monitor. Potentiometer and photoresistor: where the numbers 0–1023 come from, map() and Serial.println()

Key ideas

  • analogRead, 10-bit
  • Photoresistor divider
  • Serial Monitor and hysteresis

Formulas

N=⌊U5 V⋅1024⌋,0≤N≤1023

ADC (10-bit): `analogRead(A0)` divides the voltage into 1024 levels; 5 V → 1023, 2.5 V → 512.

ΔU=5 V1024≈4.9 mV

One level is the smallest difference the ADC can “see”; a smaller change does not alter the number.

UA0=5 V⋅R10kRLDR+R10k

Photoresistor divider: in the light RLDR is small — A0 sees almost 5 V (a large number); in the dark RLDR rises to megaohms — the number is close to zero.

𝚖𝚊𝚙(𝙽, 𝟶, 𝟷𝟶𝟸𝟹, 𝟶, 𝟷𝟶𝟶)=⌊N⋅1001023⌋

`map()` converts a value from one range to another using whole numbers: 512 → 50, the fractional part is dropped.

N<Nlow⇒on,N>Nhigh⇒off

Hysteresis: the switch-on and switch-off thresholds are different (450 / 550) — noise cannot cross both thresholds at once, so the light does not flicker.

Theory

Analog and digital

`digitalRead` knows only two answers: HIGH or LOW. The world, however, is continuous: light, temperature, the angle of a knob — any value. The pins A0–A5 of the Arduino are connected to an analog-to-digital converter (ADC): it measures a voltage of 0–5 V and gives a 10-bit number — 210=1024 levels, from 0 to 1023. One level is 5/1024≈4.9 mV. Each measurement takes ≈ 100 µs: about 10 000 times a second. `analogRead(A0)` returns not the voltage but a number; you convert it to volts yourself: U=N⋅5/1023.

Potentiometer on A0

The outer legs of the potentiometer go to 5V and GND, the middle one to A0: this is a voltage divider — the knob gives the fraction k=α/270° of 5 V. In the “Potentiometer” experiment the LED “pulled down” the divider; the ADC input, however, draws almost no current (≈ 100 MΩ), so a 10 kΩ potentiometer gives exactly k⋅5 V: 2.5 V in the middle → 512, 5 V at the end → 1023. `map(N, 0, 1023, 0, 100)` converts the number to per cent — using whole numbers, so the fractional part is dropped.

Photoresistor (LDR)

A photoresistor is a disc with a layer of cadmium sulfide (CdS): its resistance drops sharply in the light. A typical GL5528: ≈ 10 kΩ at 10 lx, hundreds of ohms in daylight, ≈ 1 MΩ in the dark. The ADC measures voltage, not resistance — so we need a divider: 5V → LDR → A0 → 10 kΩ → GND. In the light the LDR is small and A0 sees almost 5 V (900+); in the dark the LDR is large and A0 is close to zero (10–50). The 10 kΩ is not accidental: it equals the LDR’s “dusk” resistance — so the threshold falls in the middle, around 512. Cover it with your hand and within two seconds the number falls to about a hundred.

Serial Monitor and Serial Plotter

`Serial.begin(9600)` opens a link to the computer over USB: 9600 baud ≈ 960 characters per second. `Serial.print(x)` writes a number, `println` — and starts a new line. The Serial Monitor shows the text, while the Serial Plotter draws a graph, turning the number on each line into a point — the fastest way to “see” a sensor. In this experiment the graph is automatic: A0 and the state of the night light against time. `float` numbers are printed with two decimal places: 2.50.

Threshold, flicker and hysteresis

Night light: `if (N < 500) on; else off;`. It works in the light and in the dark, but at dusk — when N is right around 500 — the light flickers: the glow of the lamp, shadows and ADC noise shake the number by ±10–20 and it crosses the threshold dozens of times a second. The cure is hysteresis: two thresholds, switch on at 450 and off at 550; nothing changes within the 100 levels between them, and noise cannot reach across. A thermostat, street lamps, a refrigerator — they all work this way. A second helper is the average of several measurements.

About the model and the danger

ADC: N=⌊1024U/5⌋ (never above 1023), noise ±1 level; LDR: R=10 kΩ⋅(E/10 lx)−0.7, 1 MΩ in the dark; the light fluctuates by ±4 % (lamp and shadows); lamp 0–100 % → 1–1000 lx. Serial transmission is instantaneous in the model (in reality a line at 9600 baud takes ≈ 5 ms). Danger: never put more than 5.5 V on A0 — if you power the divider from a 9 V battery, A0 sees 8 V in bright light: the pin’s protection diode opens, a few mA flow through the chip and the ATmega328P burns out (in dim light it is still 4.5 V — it survives, and you notice nothing!).

Did you know?

  • The ADC in the ATmega328P spends ≈ 100 microseconds on each measurement (125 kHz clock, 13 clock cycles) — the Arduino documentation says “about 10 000 measurements a second”; so even in a `loop()` without `delay()` A0 is read no more than ten thousand times a second.
  • A substance whose resistance changes in light was discovered in 1873 by the English engineer Willoughby Smith, in selenium — the “grandfather” of the photoresistor; today’s cheap photoresistors are made of cadmium sulfide (CdS) and are used to switch street lamps on automatically.

Inside the experiment

A real board in a hand-inked isometric drawing: turn it, place the parts, wire the circuit, write and upload the code — current and voltage are computed at once, and a wrong connection burns a part. Inside are missions, theory, a quiz and a guided tour.

More experiments in this section