All the quantities we measure in the physical world are continuous - temperature does not jump from twenty to twenty-one degrees, it passes through every intermediate value. A microcontroller's memory is exactly the opposite: a group of ten bits can hold exactly 1024 distinct configurations, not one more. The block that bridges these two worlds, with a deliberate and carefully sized loss of information, is the analog-to-digital converter - the piece that turns a microcontroller from a logic-driven automaton into a programmable measuring instrument.
1Purpose and structure of the course6 min
We will follow the complete path of a signal, from a continuous voltage to a number in memory: the mandatory stages of conversion, the condition that says how often we must look at the signal to be able to reconstruct it, the trade-off between resolution and range, the essential and often neglected role of the reference voltage, the families of architectures and, at the end, the concrete ADC module of the ATmega328P.
- A timer module turns time from a side effect of execution into a measurable quantity (Lecture 06)
- The prescaling formulas (frequency, prescale factor, compare value) return identically in this lecture, applied to the converter's clock (Lecture 06)
- Explain the three mandatory stages of conversion and the role of the sample-and-hold circuit
- Apply the sampling theorem and recognize a case of aliasing
- Calculate the quantization step and the maximum error for a given resolution and reference
- Explain why the reference voltage is a design decision, not a configuration detail
- Describe step by step the algorithm of a successive-approximation converter
- Correctly configure and read the ATmega328P's ADC, through registers, respecting the ADCL-ADCH order
2Why analog-to-digital conversion is needed9 min
Without an ADC (Analog to Digital Converter), a microcontroller could only communicate with devices that already speak its language - buttons, LEDs, serial buses. All transducers that express a physical quantity through the amplitude of a voltage (thermistors, photoresistors, potentiometers, microphones) would stay outside the system. The converter receives a voltage and delivers an integer, proportional to that voltage relative to a reference - from that moment, the measured value becomes a plain number the program can compare, sum, filter or transmit.
The quantities that compare two converters
Resolution: the number of bits of the result, hence the number of steps (2^r). It says nothing
about accuracy, only about fineness - a poorly designed 16-bit converter can be less
accurate than a well-made 10-bit one. Bandwidth: the range of frequencies the
converter can follow without distortion, determined by the sampling rate. Signal-to-noise
ratio (SNR): for an ideal r-bit converter, SNR = 6.02·r + 1.76 dB -
every added bit brings ~6 dB, but the real value is always lower, due to noise from the supply and the
reference. Conversion time: directly limits the sampling rate. Reference
voltage: fixes the measurable range, and its accuracy transfers entirely into the results.
3The stages of the conversion process13 min
Conversion goes through three mandatory stages: sampling (the continuous-time signal is captured at discrete moments), quantization (the captured value is snapped to the nearest level from a finite set) and coding with storage (the chosen level is expressed in binary and placed into a register). Around them, a low-pass filter (anti-alias) before the sampler, and a hold circuit that freezes the value for the duration of quantization.
Sampling and the sample-and-hold circuit
What happens between two samples is lost for good - the first and most serious loss of information in the whole chain. Real converters use "flat-top" sampling: a switch, a capacitor and a buffer amplifier (sample and hold). The switch closed = acquisition (the capacitor charges to the input voltage); open = hold (the voltage stays nearly unchanged).
The ATmega328P's capacitor is ~14 pF; it charges through the switch's internal resistance in series with the source's impedance. With a 10 kΩ source, the time constant is 140 ns and full charging takes ~1.1 µs, below the few microseconds of acquisition available. With a 1 MΩ source, the constant becomes 14 µs, and charging would need over 100 µs - more than an entire conversion. The result read would be systematically too low, and dependent on the previously measured channel. Hence the data sheet recommendation: source impedance below 10 kΩ.
Quantization
The range, between the lower and upper reference, is divided into 2^r equal
intervals; the width of one interval (the quantization step, or LSB): q = (VREF+ - VREF-)/2^r.
The difference between the real characteristic (a staircase) and the ideal one (a straight line) is the
quantization error - unlike the other errors discussed further on, this is an error of
principle, which cannot be removed by calibration, only reduced by increasing the number of bits. With
rounding, the error is between -q/2 and +q/2; the ATmega328P truncates, so the error is between 0 and q, with a
systematic offset of q/2.
Coding and storage
The level is expressed as a binary number and written into a result register, accessible through an ordinary instruction. On the ATmega328P, the ten-bit result is split into ADCH and ADCL - simultaneously, the hardware sets a completion flag and, if enabled, an interrupt. The converter becomes free for a new conversion; if the program delays too long, a value can be lost with no warning.
4Sampling rate and the aliasing phenomenon13 min
The sampling rate, in samples per second, is limited by the conversion time:
R_s = 1/T_c.
f_s > 2·f_max. The frequency f_s/2 is called
the Nyquist frequency - the upper limit of the band that can be represented correctly. The intuitive reason for the
factor of two: an oscillation has, in every period, a maximum and a minimum, and telling it apart from a
straight line requires at least one observation near each of them.When the condition is not met, components with too high a frequency are not lost, but
turned into low-frequency components - aliasing - indistinguishable from a
legitimate signal: f_alias = min_k |f_in - k·f_s|.
What frequency will the signal reconstructed from the samples have?
See the solution
The Nyquist frequency is f_s/2 = 4 kHz; the signal is 6 kHz, so the theorem is
violated. With k=1: f_alias = |6-8| = 2 kHz (other values of k give larger
results). The apparent frequency is 2 kHz.
Checking against the samples: for k=0,1,2,3,4, the 6 kHz sine gives the values 0,-1,0,+1,0; the 2 kHz one gives 0,+1,0,-1,0 - identical up to sign. Looking only at the samples, it is impossible to tell whether the input was 6 kHz or 2 kHz with an inverted phase. The 6 kHz component has not disappeared: it moved, like an intruder, into the middle of the useful band.
Once folded down into the useful band, a high-frequency component is indistinguishable from a legitimate signal, however sophisticated the later processing. The only remedy is preventive: an anti-alias filter, analog (it must act before sampling), placed between the source and the converter, with its cutoff below the Nyquist frequency. A simple RC cell attenuates slowly (20 dB/decade), which is why the sampling frequency is chosen with a comfortable margin above twice the useful band - in practice three to ten times the useful band, not exactly twice (oversampling). The filter's resistor adds to the source impedance seen by the sampling capacitor: a filter with R=100 kΩ solves the aliasing and creates the incomplete-charging problem - the usual combination is a few kilohms with a capacitor on the order of nanofarads.
5Resolution and quantization error11 min
The quantization step, q = E_full/2^r (where E_full = VREF+ - VREF-), is the
smallest voltage change that can still produce a change of code - any smaller variation
passes unnoticed.
VREF- = 0, VREF+ = 5 V. Calculate the quantization step, the maximum error and the code for V_in = 3.742 V.
See the solution
q = 5/1024 ≈ 4.88 mV. With rounding, the maximum error would be q/2 ≈ 2.44
mV; the ATmega328P truncates, so the error is between 0 and 4.88 mV, average 2.44 mV (a
systematic offset).
The code: 3.742/4.88×10⁻³ ≈ 766.3 → truncation → 766. Reconstructed voltage:
766×4.88 mV = 3.740 V, a deviation of 2 mV, under one step, as expected.
Practical note: if the sensor has its own 1% error (~37 mV), the 4.9 mV resolution is eight times finer than the accuracy of the signal - raising the resolution to 12 bits would bring no real gain.
6The reference voltage11 min
The reference voltage fixes the conversion range: V_in = VREF- ⇒ N=0,
V_in = VREF+ ⇒ N = 2^r - 1. The inverse relation, the one used right after reading the
result: V_in = VREF- + N·(VREF+ - VREF-)/2^r.
A 10-bit converter, VREF- = 0, VREF+ = 5 V. What voltage corresponds to code N=100?
See the solution
V_in = 0 + 100×5/1024 = 488.3 mV. Check: 100/1024 ≈ 9.77% of the range, 9.77% of
5 V = 0.49 V. The value is not exact, but the lower bound of the interval that produces code 100 - all
voltages between 488.3 and 493.2 mV give the same result.
| REFS1:0 | Source | Notes |
|---|---|---|
| 00 | The external AREF pin | the internal reference decoupled, range set externally |
| 01 | AVCC | default on Arduino, assumes exactly 5 V |
| 11 | Internal 1.1 V reference | independent of the supply, ±0.1 V spread |
An Arduino board powered over USB receives, after the protection diode, 4.6-4.8 V, not 5.0 V. A program that divides by 1024 and multiplies by 5 will give results 4-5% higher than reality, with no sign of error - and if the supply varies (a motor driven from the same setup draws current in pulses), the reference "breathes" in step with the load.
In that case, AREF carries the internally generated voltage - connecting an external source short-circuits the two references and can destroy the chip. In normal operation, AREF is only wired through a decoupling capacitor to ground. Any noise on the reference shows up in every result: a 50 mV spike on a 5 V reference represents ten quantization steps at 10 bits, so it renders the last three bits of the result useless.
7Conversion time9 min
The ATmega328P's conversion block has its own clock, obtained from the system clock through a prescaler (the ADPS2:0 bits). The data sheet requires this clock to be between 50 and 200 kHz for the full 10-bit resolution - above 200 kHz, the converter still works, but the last bits become unreliable.
An ordinary conversion takes 13 cycles of the ADC clock (1.5 for acquisition, 10 for the ten comparisons, the rest for synchronization). The first conversion after enabling takes 25 cycles.
The only prescale choice that respects the 50-200 kHz range is 128 (the others give frequencies that are too high).
See the complete calculation
f_ADC = 16×10⁶/128 = 125 kHz. T_c = 13/125×10³ = 104 µs - exactly the duration
of one analogRead() call. Sampling rate: R_s = 1/104µs ≈ 9600 Hz,
Nyquist frequency ~4.8 kHz. With the margin needed for an anti-alias filter, the realistic useful band of
an Arduino setup continuously reading one input is on the order of a kilohertz or two - enough for
temperatures or battery voltages, not enough for audio. Lowering the prescaler to 64 doubles the
rate, at the cost of the last bits of resolution (a legitimate trade-off if made knowingly).
2×104 = 208 µs per full cycle, hence ~4800 Hz per channel, Nyquist ~2.4 kHz per channel.
The shared resource is not the pin, but the conversion block itself - adding a sensor reduces the
band available to all the others.8Implementation architectures13 min
All architectures do the same thing - compare the voltage to be measured with known voltages - differing in how they organize the comparisons.
The common element: the comparator, a one-bit converter (the ATmega328P has one independent of the ADC, useful for threshold detection without the cost of a full conversion).
Successive approximation (SAR) - the ATmega328P's architecture
Four blocks: the approximation register, a digital-to-analog converter, a reference, a comparator. The algorithm is a binary search on voltage: the most significant bit is set to 1 (a trial voltage = half the range); if the input is larger, the bit stays, otherwise it is cleared; move to the next bit, which halves the remaining interval.
See it step by step
Quantization step: q = 5/16 = 0.3125 V.
Bit 3 (MSB): trial 1000=8 → 2.5 V. 3.6>2.5 → the bit stays. Register: 1000.
Bit 2: trial 1100=12 → 3.75 V. 3.6<3.75 → the bit clears. Register: 1000.
Bit 1: trial 1010=10 → 3.125 V. 3.6>3.125 → the bit stays. Register: 1010.
Bit 0 (LSB): trial 1011=11 → 3.4375 V. 3.6>3.4375 → the bit stays. Final register: 1011 = 11.
Reconstructed voltage: 11×0.3125 = 3.4375 V, error 0.1625 V ≈ 0.52q, under one
quantization step, as expected from a truncation. The uncertainty interval halved at each
step: 5 → 2.5 → 1.25 → 0.625 → 0.3125 V.
| Architecture | Speed | Resolution | Typical use |
|---|---|---|---|
| Flash (parallel) | very high | low (≤8 bits) | oscilloscopes, video, digital radio |
| Successive approximation | medium-high | medium-high (10-16) | microcontrollers, general-purpose acquisition |
| Ramp (single/dual) | low | high | multimeters, laboratory use |
| Sigma-delta | low | very high (16-32) | scales, precision thermometers, audio |
Flash (parallel): compares simultaneously against all levels, through a resistive divider and 2^r-1 comparators - a 10-bit converter would need 1023 comparators. The fastest (billions of samples/s), but the cost grows exponentially with resolution - usually stops at 8 bits.
Ramp: a linear voltage generator and a counter start together; the comparator stops the counter when the ramp exceeds the input. Conversion time depends on the measured value, worst case 2^r periods. The dual-ramp variant removes the dependency on the capacitor's and clock's exact values through a ratio simplification - the classic solution in digital multimeters.
Sigma-delta: performs very many very coarse (one-bit) measurements and obtains fineness through averaging - a modulator with an integrator and a comparator produces a bit stream whose density is proportional to the voltage, digitally filtered through a long window. Resolution of 16-32 bits, with simple analog hardware, but low speed and high latency.
9Conversion errors7 min
Besides the quantization error (a matter of principle), a real converter has deviations from component imperfections, measured in multiples of the quantization step.
Offset error: a vertical shift of the whole characteristic - at zero input, the output is not code zero. It comes from the comparators' offset voltage and leakage currents; being constant, it is easily compensated by subtracting a constant from all results.
Gain error: a change in the slope of the characteristic - the main cause is inaccuracy in the reference voltage. It is determined through the end-point method and compensated through a correction factor determined during calibration.
DNL(n) = (W_n - 1 LSB)/1 LSB. DNL = -1 means a step of zero width, a code that
never appears. INL is the maximum cumulative deviation of the real characteristic from the ideal
straight line - unlike offset and gain, it is not fixed by a simple operation, only through a
point-by-point calibration table, and it ultimately limits the converter's real accuracy. For
the ATmega328P, absolute accuracy is on the order of two quantization steps - out of the nominal
10 bits, about 9 are trustworthy.10The ATmega328P microcontroller's ADC module11 min
The ATmega328P's converter is successive-approximation, 10 bits, preceded by a six-input multiplexer (ADC0-ADC5, pins A0-A5) - a single conversion block, the channels are read one at a time, not simultaneously.
ADMUX: REFS1:0 choose the reference; MUX3:0 choose the channel (0000-0101 = ADC0-ADC5, plus a few combinations for the internal temperature sensor and a fixed 1.1 V reference); ADLAR aligns the result to the right (default) or to the left (allows reading the most significant 8 bits from a single register).
ADCSRA: ADEN powers the analog block; ADSC triggers a conversion and returns to 0 on completion; ADATE enables automatic triggering (free running mode); ADIF is the completion flag, ADIE enables the interrupt (vector ADC_vect); ADPS2:0 sets the prescale.
The 10-bit result is split into ADCL and ADCH. Reading ADCL locks the converter's access to the
register pair; the lock lifts when ADCH is read. If the program reads only ADCH, or reads ADCL and
forgets ADCH, the registers stay locked and later conversions are lost, with no
visible error. In C, the pseudo-register ADCW (or ADC) automatically generates
the two reads in the correct order.
/* with the library function */
int raw = analogRead(A0); /* 0..1023, ~104 us */
/* directly on registers */
void adc_init(void) {
ADMUX = (1 << REFS0); /* AVCC, right-aligned */
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); /* prescaler 128 */
DIDR0 = (1 << ADC0D); /* disables the digital buffer */
}
uint16_t adc_read(uint8_t channel) {
ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); /* keeps REFS, only changes the channel */
_delay_us(10);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC)) { ; }
uint8_t low = ADCL; /* ADCL IS READ FIRST */
uint8_t high = ADCH;
return ((uint16_t)high << 8) | low;
}
Vin = (raw × V_REF) / 1024.0 in float, convenient but slow; or, much faster on a
microcontroller with no math coprocessor, in integers: (uint32_t)raw × 5000UL / 1024UL
(result in mV). Dividing by 1024 (a power of two) becomes a simple bit shift - by 1023,
it would require a full division routine, dozens of times slower, for an accuracy gain
of under a thousandth.11Typical mistakes and practical recommendations5 min
- "The result read depends on the previously read channel - it must be a fault." Almost certainly not - it is the source's impedance being too high. A divider of hundreds of kilohms cannot charge the 14 pF capacitor in time, and the result stays systematically close to the value of the previous channel. Lower the source impedance below 10 kΩ, or insert a buffer amplifier.
- "The reference on AVCC is safe - the supply is 5 V anyway." Often false - a board powered over USB often receives 4.6-4.8 V, and a supply that varies makes the reference "breathe" along with the load, with no error message. Use ratiometric measurement where applicable, or switch to the internal 1.1 V reference for small signals.
- "I read a hundred times and average - that solves any accuracy problem." False - averaging only reduces random noise (proportional to the square root of the number of samples), it does not correct any systematic errors (offset, wrong reference) and does not eliminate a component that entered through aliasing, which is not noise, but a deterministic signal. Handle offset and the reference separately through calibration; use an anti-alias filter for high-frequency components, not averaging.
12Summary and glossary5 min
Analog-to-digital conversion goes through three mandatory stages - sampling (discretizes time), quantization (discretizes amplitude) and coding (makes the result accessible to the program) - framed by an anti-alias filter and a sample-and-hold circuit. Sampling requires the sampling frequency to exceed twice the highest frequency in the signal, otherwise aliasing occurs, irreversible after sampling. Quantization introduces an error of at most one step, q=VREF/2^r, and resolution must be chosen relative to the useful variation of the measured quantity. The reference voltage simultaneously fixes the range and the effective resolution, and its noise or inaccuracy transfer undiminished into every result - the choice between AVCC, the internal reference and an external one is a design decision, not a configuration option. The successive-approximation architecture, used by the ATmega328P, is a binary search on voltage, with a conversion time proportional to the number of bits - the balanced trade-off that made it the microcontroller standard. On the ATmega328P, ADCL is always read first, and reconfiguring the reference or the channel requires a discarded trial read before the result can be trusted.
13Self-check questions7 min
- Explain why a physical quantity cannot be stored exactly in a digital system, and in what sense analog-to-digital conversion is a deliberate loss of information.
- Describe the role of the sample-and-hold circuit. What would happen to a 10-bit SAR if the input changed by half the range between the first and second comparison?
- State the sampling theorem and intuitively explain the factor of two. Why must the inequality be strict?
- A 6 kHz signal is sampled at 8 kHz. Determine the apparent frequency and explain why the phenomenon cannot be corrected by later digital processing.
- Calculate the quantization step for a 10-bit converter with a 5 V reference, and with the internal 1.1 V reference. For a signal between 0 and 0.8 V: which measures better?
- Explain what a ratiometric measurement is and why, for a potentiometer powered from VCC, the reference on AVCC gives correct results even if the supply is not exactly 5 V.
- Why must ADCL be read before ADCH on the ATmega328P? What happens if a program reads only ADCH?
14Directions for further study2 min
The next lecture moves from measuring an analog voltage to exchanging digital data between the microcontroller and the outside world: asynchronous serial communication, the UART protocol and the format of a data frame.
The sampling formulas, the resolution calculation and the direct ADC configuration from this lecture become a real setup in Laboratory 05.