The puzzle
A logger samples a vibration sensor 100 times a second and shows a slow 10 Hz wobble. The machine has no part turning at 10 Hz. It does have a motor at 90 Hz. How can an ADC report a frequency that is not there, and how do you stop it?
STEP 1
Sampling
An ADC measures the input at discrete instants, the sampling rate f_s times per second. Between samples it sees nothing. The sampling theorem says that a signal containing only frequencies below f_s / 2 is completely described by its samples. That limit is the Nyquist frequency:
In practice, sample a good margin faster than twice the highest frequency you need, because real filters do not stop sharply at f_N.
STEP 2
Aliasing
Above f_N the samples become ambiguous: a sine at frequency f produces the same samples as a sine (with suitable phase) at |f − k·f_s| for the integer k that makes it smallest. The higher frequency takes on the identity of the lower one, its alias:
↑ This step uses the figure at the top of the page.
A signal exactly at f_s is sampled at the same phase every time and looks constant; one slightly off f_s looks like a slow drift. Once the samples are taken, nothing in software can tell the alias from a real signal at that frequency: a digital filter only sees the sequence of numbers.
STEP 3
Anti-alias filtering
The cure is to remove everything above f_N before it reaches the ADC, with an analog anti-alias filter. A single RC low-pass is common because it is cheap, but it falls off only 20 dB per decade above its cut-off f_c:
An interferer ten times above f_c is reduced only tenfold. Whether that is enough depends on how large the interferer is compared with one LSB of the converter.
Aliasing cannot be undone after sampling, so unwanted high frequencies must be removed before the ADC. A single RC low-pass falls off only 20 dB per decade: an interferer far above the band of interest is reduced, but may still be many LSBs large. The readout compares what is left with one LSB (0.81 mV) of a 12-bit converter on a 3.3 V range.
Sampling much faster than needed (oversampling) relaxes the filter: the Nyquist frequency moves up, a gentle filter has more room to fall, and a digital filter can then reduce the bandwidth and the sample rate afterwards.
STEP 4
Bandwidth, not just frequency
The sampling rate must cover the bandwidth of the signal you need, including fast edges and harmonics, not just its fundamental. A 50 Hz current waveform with harmonics up to the 20th (1 kHz) needs a sampling rate well above 2 kHz; sampling it at 200 Hz gives four samples per cycle, and every harmonic folds onto DC, 50 Hz or 100 Hz, silently corrupting the measured fundamental and RMS value.
STEP 5
Worked example: the 10 Hz wobble
The logger samples at f_s = 100 Hz, so f_N = 50 Hz. The motor’s 90 Hz vibration is above f_N; with k = round(90/100) = 1,
exactly the phantom wobble. The fix is an analog low-pass well below 50 Hz in front of the ADC (if 90 Hz content is unwanted), or sampling fast enough to capture 90 Hz honestly, more than 180 Hz and in practice several hundred.
MYTHS AND FACTS
Common misconceptions
Sampling at twice the frequency is enough
Only for a signal with nothing above f_N, which needs a filter; exactly 2f samples can land on the zero crossings.
A digital filter can remove aliasing
After sampling, an alias is indistinguishable from a real in-band signal.
The ADC’s maximum rate is the rate to use
Sample at what the signal and the filter need; faster wastes memory and power, slower aliases.
Only high-frequency signals alias
Any interference above f_N does, including switching noise and mains harmonics on a slowly sampled sensor.
Check yourself
Answer in your head, then open the card.
A 1.2 kHz tone is sampled at 1 kHz. What frequency does the firmware see?
k = round(1.2) = 1: |1200 − 1000| = 200 Hz.
Why can’t an averaging filter in firmware remove a 60 Hz alias of a 540 Hz vibration sampled at 600 Hz?
The alias is a genuine 60 Hz component of the sampled sequence; a filter that removed it would also remove a real 60 Hz signal. It had to be stopped before sampling.
An RC filter has f_c = 1 kHz. By how much does it attenuate a 20 kHz interferer?
1/√(1 + 20²) ≈ 0.050, about −26 dB, a factor of 20.
The RP2040 samples one input back to back with adc_set_clkdiv(0). What is the Nyquist frequency?
Each conversion takes 96 cycles of 48 MHz, 500 kS/s, so f_N = 250 kHz.
Sources (3)
- Raspberry Pi Ltd, pico-sdk 1.5.1, hardware_adc/adc.h — RP2040 ADC: “SAR ADC”, “500 kS/s (Using an independent 48MHz clock)”, “12 bit (8.7 ENOB)”, a 5-input mux, a 4-sample FIFO; adc_set_clkdiv: “Period of samples will be (1 + div) cycles on average. Note it takes 96 cycles to perform a conversion”
- Raspberry Pi Ltd, pico-examples, adc/dma_capture/dma_capture.c — captures 1000 samples back to back into a buffer with DMA; the ADC runs free, “timed by the 48 MHz ADC clock” (adc_set_clkdiv(0))
- Arm, CMSIS-DSP, Source/FilteringFunctions/arm_fir_f32.c — a digital FIR filter computes “y[n] = b[0] * x[n] + b[1] * x[n-1] + …” from a state buffer of earlier input samples: it operates only on the already-sampled sequence