Nyquist-Shannon Sampling
Copy this iframe to your website:
1 | |
Description
This MicroSim samples a 5 Hz sine wave, \(x(t) = \sin(2\pi \cdot 5t)\), at the sampling rate \(f_s\) set by the slider (1 to 50 Hz in steps of 0.1 Hz) and shows one second of the result.
- Upper plot: the original signal in black and its samples \(x[n] = x(n/f_s)\) as red dots.
- Lower plot: two continuous signals rebuilt from the samples alone. The blue curve is the ideal (sinc) reconstruction that the sampling theorem promises. The gray curve joins neighboring samples with straight lines.
The read-out line gives the signal frequency \(f\), the Nyquist rate \(2f = 10\) Hz, the Nyquist frequency \(f_s/2\) and the number of samples per period \(f_s/f\). The colored status line is the Nyquist indicator: green when \(f_s > 2f\), gold when \(f_s = 2f\) exactly, and red when \(f_s < 2f\), in which case it reports the alias frequency.
This is the introductory sampling sim for the sections on the sampling theorem and aliasing in Chapter 5: Sampling and Quantization. The Sampling Theorem Explorer adds spectra and more controls.
Mathematical Concepts
The blue curve is the Whittaker-Shannon interpolation of the samples,
The theorem needs every sample from \(n = -\infty\) to \(\infty\). The sim uses the samples in the window plus 2000 more on each side, which keeps the blue curve within 0.01 of the exact result for every slider setting.
When \(f_s > 2f\) the sum returns the original 5 Hz wave. When \(f_s < 2f\) the samples are identical to the samples of a slower sine at the alias frequency
where the integer \(k\) makes \(f_a \le f_s/2\), and the sum returns that alias instead.
Lesson Plan
Learning Objectives
After using this MicroSim, students will be able to:
- State the Nyquist criterion \(f_s > 2f\) and calculate the Nyquist rate of a sinusoid of known frequency
- Calculate the samples per period \(f_s/f\) and the Nyquist frequency \(f_s/2\) for a given sampling rate
- Predict the alias frequency \(f_a = |f - k f_s|\) when \(f_s < 2f\) and verify it by counting the cycles of the reconstruction
- Distinguish ideal (sinc) reconstruction from straight-line interpolation and explain why a jagged straight-line plot does not mean that information was lost
- Explain why sampling at exactly \(f_s = 2f\) can fail to capture a sine wave
Target Audience
Undergraduate students in a first signals and systems or digital signal processing course. Plan 20 minutes for the activities below.
Prerequisites
- Frequency and period of a sine wave (\(f = 1/T\))
- Sampling as taking the values \(x[n] = x(nT_s)\) every \(T_s = 1/f_s\) seconds
- Reading a plot of amplitude against time
Activities
Activity 1: Above the Nyquist rate (5 min). Start at the default \(f_s\) = 22.0 Hz. The read-out shows 4.40 samples per period and \(f_s/2\) = 11.00 Hz, and the status line is green. The blue curve passes through every red dot and matches the black original, while the gray straight lines cut the corners off each peak. Lower \(f_s\) to 12.0 Hz (2.40 samples per period): the gray zigzag no longer looks like a sine, yet the blue curve is still the 5 Hz wave.
Activity 2: Find the edge (5 min). Set \(f_s\) = 10.5 Hz (2.10 samples per period): the status is still green and the blue curve still completes 5 cycles in one second. Set \(f_s\) = 10.0 Hz: the status turns gold, the 11 samples fall at \(t\) = 0, 0.1, ..., 1.0 s on zero crossings, and both reconstructions are flat lines. Set \(f_s\) = 9.5 Hz: the status turns red and reports a 4.5 Hz alias. The blue curve completes 4.5 cycles and starts downward instead of upward.
Activity 3: Predict the alias (5-10 min). Before moving the slider, compute \(f_a = |5 - k f_s|\) for \(f_s\) = 8.0, 6.0 and 4.5 Hz. Then check: at 8.0 Hz the status reports 3.0 Hz and the blue curve completes 3 cycles; at 6.0 Hz it reports 1.0 Hz and the blue curve completes one cycle; at 4.5 Hz it reports 0.5 Hz and the blue curve rises to +1 at \(t\) = 0.5 s and falls back to 0 at \(t\) = 1 s, half a cycle.
Activity 4: Samples that vanish (5 min). Set \(f_s\) = 5.0 Hz (1.00 sample per period). Every sample lands at the same point of the cycle, where \(\sin(2\pi n) = 0\), so the status reads "Every sample is 0" and the reconstruction is flat: the 5 Hz wave has aliased to 0 Hz. Try 2.5 Hz and 2.0 Hz and explain why the samples are again all zero.
Assessment
- A 5 Hz sine wave is sampled at 8 Hz. What frequency does the reconstruction show? Answer: 3 Hz, since \(|5 - 8| = 3\) Hz is below \(f_s/2 = 4\) Hz.
- What is the lowest sampling rate that captures a 5 Hz sine wave, and why does exactly 10 Hz fail in this sim? Answer: any rate above 10 Hz. At exactly 10 Hz the samples fall at \(t = n/10\), where \(\sin(\pi n) = 0\), so every sample is zero.
- At \(f_s\) = 12 Hz the gray curve looks nothing like a sine wave. Has information been lost? Answer: no. 12 Hz is above the 10 Hz Nyquist rate, and the blue sinc reconstruction recovers the 5 Hz wave; the distortion comes from straight-line interpolation, not from sampling.
- CD audio is sampled at 44.1 kHz. What is the highest frequency it can represent, and where does a 30 kHz tone appear if it reaches the converter unfiltered? Answer: 22.05 kHz; the 30 kHz tone aliases to \(|30 - 44.1| = 14.1\) kHz.
- How many samples per period does the default setting take, and how many does the Nyquist rate take? Answer: 4.4 samples per period at 22 Hz; exactly 2 at the 10 Hz Nyquist rate.
Common Misconceptions
"A sine wave needs many samples per period, say ten, to be captured." At \(f_s\) = 12 Hz there are only 2.4 samples per period and the straight-line plot looks badly distorted, but the blue sinc reconstruction is the original 5 Hz wave. The number of samples needed is set by the theorem, not by how the dots look when joined with straight lines.
"Sampling at exactly twice the frequency is enough." At \(f_s\) = 10.0 Hz every sample of this sine is zero and the wave disappears. The criterion is a strict inequality, \(f_s > 2f\), and practical systems sample well above it.
"Aliasing makes a signal look noisy." At \(f_s\) = 8.0 Hz the reconstruction is a clean, smooth sine wave. It is simply the wrong one: 3 Hz instead of 5 Hz. Nothing in the samples reveals that it is an alias.
References
- Nyquist-Shannon sampling theorem - Wikipedia - statement of the theorem, the condition \(f_s > 2B\), and sinc reconstruction
- Aliasing - Wikipedia - how frequencies above \(f_s/2\) fold to lower alias frequencies
- Nyquist rate - Wikipedia - the minimum sampling rate \(2B\) for a signal of bandwidth \(B\)
- Nyquist frequency - Wikipedia - the highest frequency \(f_s/2\) that a given sampling rate can represent
- Whittaker-Shannon interpolation formula - Wikipedia - the sinc sum used to draw the blue curve
- The Scientist and Engineer's Guide to Digital Signal Processing - Steven W. Smith - free online textbook; Chapter 3 (ADC and DAC) explains the sampling theorem and aliasing
Development Notes
Prompt history
Version 2.0.0 (2026-10-14). Ported from p5.js 1.10.0 to p5.js 2.3.2 and made responsive (one createCanvas call,
updateCanvasSize(), windowResized()); the legacy entry file nyquist-shannon-sampling.html now redirects to
main.html. Samples are now taken at the exact times \(t = n/f_s\). The earlier sketch stepped through the canvas in whole
pixels (floor(width / samplingRate)), so the true number of samples per period differed from the label (4.5 instead of
the 4.4 shown at the default setting on a 450 px canvas) and changed with the canvas width. The slider keeps its range,
step and default (1 to 50, 0.1, 22); its value is now labeled as the sampling rate in Hz for the 5 Hz signal shown over
one second, with samples per period (\(f_s/5\), the old label) in the read-out. The lower plot keeps the original
straight-line reconstruction (now gray) and adds the ideal sinc reconstruction (blue), a legend, a time axis and the Nyquist
status line with the alias frequency.
Original prompt (sent to ChatGPT o1-preview)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Template supplied with the prompt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
ChatGPT response (o1-preview, thought for 6 seconds). "Below is a p5.js simulation that demonstrates sampling and aliasing. You can adjust the sampling rate using a slider to see how it affects the reconstructed signal."
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
How to use the original simulation (from the response)
- Adjust the Sampling Rate: Use the slider at the bottom of the canvas to change the sampling rate. The sampling rate is displayed above the slider.
- Observe the Top Graph: The top waveform represents the original signal. Red circles indicate the sampling points based on the current sampling rate.
- Observe the Bottom Graph: The bottom waveform is reconstructed from the sampled points. As you adjust the sampling rate, notice how the reconstructed signal changes.
Explanation of the original code (from the response)
samplingRateSlider: the slider control for adjusting the sampling rate.samplingRate: the current sampling rate value from the slider.signalFrequency: the frequency of the original signal.time,signal,sampledSignal: arrays that store the time values, the original signal values and the sampled points.setup()initializes the canvas and the slider and computes the original signal using a sine function.draw()clears the background, reads the slider, draws the labels and the original waveform, draws red circles at the sampling points, and draws the reconstruction from the sampled points in the bottom half of the canvas.
Key concepts named in the response
- Sampling rate: the number of samples taken per period of the signal. A higher sampling rate captures the signal more accurately.
- Aliasing: when the sampling rate is too low (below the Nyquist rate), the reconstructed signal may differ significantly from the original.
The response ended by suggesting that the code be pasted into the p5.js online editor and that students experiment with different signal frequencies.