The FFT and the frequency domain: bins, Nyquist, DC, leakage and the Hann window
Module 4 — Signal analysis · Slides: slides.md · Module overview · Course page
See a signal in the frequency domain. Understand how the FFT splits a signal into sines of several frequencies, convert a bin to Hz with f = k·FS/N, know bin width and Nyquist, choose N sensibly, and handle the spectrum’s enemies with DC removal, a Hann window and the magnitude.
Objectives
Section titled “Objectives”By the end of this lesson, you will:
- Explain the difference between the time and frequency domains, and give at least two reasons audio models look at the spectrum instead of the raw wave.
- Compute a bin’s frequency with f = k·FS/N, the bin width FS/N and Nyquist FS/2, and choose N for a task by stating the resolution-versus-responsiveness trade-off.
- Explain why you subtract the mean (removing DC), multiply by a Hann window, and take the magnitude √(re² + im²) over only the first half of the bins before reading the spectrum.
- Check an FFT’s correctness with a sine of known frequency, and predict which bin the peak should land in.
Before you start
Section titled “Before you start”You’ve been through lessons 4.1–4.2, and understand time-domain filters, and remember the Nyquist rule from lesson 2.1. If you have time, download math_lab.html and open it in a browser (needs internet to load GeoGebra) to try sliding the frequency of a mixed wave.
- Hardware: a TESAIoT Dev Kit board already flashed with BENTO’s MicroPython firmware, or the BENTO Emulator inside BENTO IDE
- Prior lesson: lesson 4.2 — Hands-on: cleaning a live signal with a filter
See it work first
Section titled “See it work first”Run s09_fft_spectrum_full.py (in lesson 4.4) and shake the board up and down slowly, then quickly. The spectrum bars move, and the dominant frequency shifts with the rhythm. See “energy moving between frequencies” first, then ask how it knows.
Concepts
Section titled “Concepts”The same signal can be viewed two ways. The time domain says when it’s high and when it’s low; the frequency domain says which frequency is strong. Audio models choose the latter, because the same sound played twice never matches in the time domain, but the way energy spreads across frequencies stays similar. The spectrum also compresses 16,000 points per second down to a few dozen values, and frequency carries physical meaning. Fourier’s core idea is that any signal can be written as a sum of sines at several frequencies. The FFT asks back: “which sine frequencies are present, and how strong is each?”
The FFT is a fast way to compute the DFT, $X[k] = \sum_{n=0}^{N-1} x[n] e^{-j 2\pi k n / N}$, taking N points (a power of two) and returning N complex values, in $N\log N$ time instead of $N^2$. Bin k has frequency $f_k = k F_S / N$; the bin width $F_S/N$ is the resolution, and Nyquist $F_S/2$ is the ceiling. At $F_S = 50$ Hz and $N = 32$, one bin is 1.5625 Hz wide, bin 4 is 6.25 Hz, and you can read up to 25 Hz. Choosing N is a trade-off: a larger N tells nearby frequencies apart but needs a longer capture (N = 64 takes about 1.28 seconds); a smaller N updates faster but merges nearby frequencies into one bin.
A spectrum has enemies that must be handled before reading it: (1) DC — an accelerometer lying still has constant gravity, which piles up at bin 0 and drowns out everything else. Fixed by subtracting the window’s mean. (2) Spectral leakage — the edges of a signal chunk don’t line up exactly with the signal’s period, so energy leaks into neighbouring bins. Fixed with a Hann window, $w[i] = 0.5 - 0.5\cos(2\pi i/(N-1))$, which pushes the edges to zero, at the cost of a slightly fatter peak. (3) The result is complex numbers — we only care about the magnitude, $|X[k]| = \sqrt{re^2 + im^2}$, and only use the first half (HALF = N//2), since the second half is a mirror image. Then find the dominant bin, skipping bin 0, and convert it to Hz. Before trusting an FFT against real data, always check it with a sine whose answer you already know — for example, a 6.25 Hz sine must give a peak at bin 4.
Worked example
Section titled “Worked example”This lesson’s slides also reference a file under shared/:
Check your understanding
Section titled “Check your understanding”The same questions are in quiz.yaml for automated checking.
-
Which of these are reasons audio models look at the spectrum instead of the raw wave? (select every correct answer) (multiple choice · objective 1)
- a) The same sound played twice has a different waveform, but a similar energy distribution across frequencies
- b) The spectrum compresses the data shorter, so the model is smaller and faster
- c) Frequency carries physical meaning that can be read
- d) The FFT makes the sound louder
Solution
a, b, c — the first three are the reasons in the slides. The FFT doesn’t change loudness — it only changes the viewpoint from time to frequency.
-
FS = 50 Hz and N = 32. What frequency is bin 3? (single choice · objective 2)
- a) 3 Hz
- b) 4.69 Hz
- c) 6.25 Hz
- d) 25 Hz
Solution
b — f = k·FS/N = 3 × 50 / 32 ≈ 4.69 Hz. One bin is 1.5625 Hz wide.
-
If you increase N from 32 to 128 at FS = 50 Hz, what’s the result? (single choice · objective 2)
- a) Bins get wider, updates get faster
- b) Bins narrow to about 0.39 Hz, telling nearby frequencies apart, but capturing takes about 2.56 seconds, so the spectrum updates more slowly
- c) Nyquist rises to 100 Hz
- d) No effect, since the FFT works with any N
Solution
b — bin width = FS/N, while Nyquist depends only on FS. Frequency resolution and time responsiveness always trade off against each other.
-
The board lies still, and you see bin 0’s bar towering over everything else. Which step was skipped? (single choice · objective 3)
- a) Removing DC by subtracting the window’s mean
- b) Multiplying by a Hann window
- c) Taking the magnitude
- d) Finding the peak
Solution
a — gravity is a constant value, which is 0 Hz in the frequency domain, so it piles up at bin 0. The mean must be subtracted before the FFT.
-
You generate a 12.5 Hz sine at FS = 50 Hz, N = 32, and feed it into the FFT. Which bin should the peak land in? (single choice · objective 4)
- a) bin 4
- b) bin 8
- c) bin 12
- d) bin 16
Solution
b — k = f·N/FS = 12.5 × 32 / 50 = 8 exactly. If the FFT is correct, the peak must be at bin 8.
- Compute the frequency of bins 1, 3 and 8 at FS = 50 Hz, N = 32, and note them in your learning log.
- In the REPL, do the sanity check with a 6.25 Hz sine as in the slides, then try 5 Hz and see which bins the peak splits between.
- Choose N for a task that must tell a 3.0 Hz vibration apart from a 3.5 Hz one, at FS = 50 Hz, with your reasoning.
Going further
Section titled “Going further”In lesson 4.4, we’ll fill in a four-step pipeline in s09_fft_spectrum.py and read a live spectrum from the IMU with our own eyes.
Next lesson: lesson 4.4 — Hands-on: a live spectrum from the IMU
Reflect
Section titled “Reflect”- What job around you would “frequency” tell you more about than “a value over time” — such as a motor starting to fail?
- If you needed a spectrum that updates fast and is finely resolved at the same time, how would you solve that?
Review questions
Answer on your own first, then open the answer.
-
Which are reasons audio models look at the spectrum rather than the raw wave? (select all that apply) (Objective 1)
- เสียงเดียวกันสองครั้งมีรูปคลื่นต่างกัน แต่การกระจายพลังงานตามความถี่คล้ายกัน
- สเปกตรัมบีบข้อมูลให้สั้นลง โมเดลจึงเล็กและเร็วขึ้น
- ความถี่มีความหมายทางกายภาพที่อ่านออก
- FFT ทำให้เสียงดังขึ้น
Show answer
Answer: A. เสียงเดียวกันสองครั้งมีรูปคลื่นต่างกัน แต่การกระจายพลังงานตามความถี่คล้ายกัน · B. สเปกตรัมบีบข้อมูลให้สั้นลง โมเดลจึงเล็กและเร็วขึ้น · C. ความถี่มีความหมายทางกายภาพที่อ่านออก
สามข้อแรกคือเหตุผลในสไลด์ FFT ไม่ได้เปลี่ยนความดัง มันแค่เปลี่ยนมุมมองจากเวลาเป็นความถี่
-
With FS = 50 Hz and N = 32, what frequency is bin 3? (Objective 2)
- 3 Hz
- 4.69 Hz
- 6.25 Hz
- 25 Hz
Show answer
Answer: B. 4.69 Hz
f = k·FS/N = 3 × 50 / 32 ≈ 4.69 Hz หนึ่ง bin กว้าง 1.5625 Hz
-
Raising N from 32 to 128 at FS = 50 Hz does what? (Objective 2)
- bin กว้างขึ้น อัปเดตเร็วขึ้น
- bin แคบลงเหลือราว 0.39 Hz แยกความถี่ใกล้กันได้ แต่ต้องเก็บจุดนานราว 2.56 วินาที สเปกตรัมจึงอัปเดตช้า
- Nyquist สูงขึ้นเป็น 100 Hz
- ไม่มีผลเพราะ FFT ใช้ N เท่าไรก็ได้
Show answer
Answer: B. bin แคบลงเหลือราว 0.39 Hz แยกความถี่ใกล้กันได้ แต่ต้องเก็บจุดนานราว 2.56 วินาที สเปกตรัมจึงอัปเดตช้า
bin width = FS/N ส่วน Nyquist ขึ้นกับ FS เท่านั้น ความละเอียดความถี่กับความไวในเวลาแลกกันเสมอ
-
With the board still, bin 0 towers over every other bar. Which step was skipped? (Objective 3)
- การตัด DC ด้วยการลบค่าเฉลี่ยของหน้าต่าง
- การคูณ Hann window
- การหา magnitude
- การหา peak
Show answer
Answer: A. การตัด DC ด้วยการลบค่าเฉลี่ยของหน้าต่าง
แรงโน้มถ่วงเป็นค่าคงที่ ในโดเมนความถี่คือ 0 Hz จึงไปกองที่ bin 0 ต้องลบค่าเฉลี่ยก่อน FFT
-
You feed a 12.5 Hz sine sampled at FS = 50 Hz with N = 32 into the FFT. Which bin should the peak land in? (Objective 4)
- bin 4
- bin 8
- bin 12
- bin 16
Show answer
Answer: B. bin 8
k = f·N/FS = 12.5 × 32 / 50 = 8 ลงตัวพอดี ถ้า FFT ถูก peak ต้องอยู่ที่ bin 8
Cite this lesson
If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.
"The FFT and the frequency domain: bins, Nyquist, DC, leakage and the Hann window" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
Thai attribution: "FFT และโดเมนความถี่: bin, Nyquist, DC, leakage และ Hann window" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA