窗函數・補零・Cooley-Tukey・THD ── 從示波器 CSV 到 Excel 的完整流程

最後還有免費FFT 頻譜分析工具

前言

每當你用示波器擷取波形並匯出成 CSV,你拿到的是一段訊號的時域快照。頻率內容──有哪些諧波、各自有多大、總諧波失真是多少──在你做**快速傅立葉轉換(FFT)**之前都是隱形的。

本文完整走過 FFT 分析流程的每一個步驟,從原始 CSV 資料到帶有完整標註的 Excel 輸出。我們會解釋每個步驟為什麼必要、Cooley-Tukey 如何讓 FFT 快到可以即時分析,以及窗函數的關鍵作用──特別是 Flat-top 窗在精確量測諧波振幅上的不可取代性。

步驟一 去直流(Remove DC Offset)

示波器訊號常常帶有一個固定的直流偏移。如果不去掉它,FFT 會在 0 Hz 產生一個巨大的尖峰,把其他頻率的成分全部淹沒。解決方法很簡單:把所有樣本的平均值算出來,然後每個樣本都減去它。

去直流後的值[i] = 原始訊號[i] — 平均值

圖 1 ── 左:含 DC 偏移的原始訊號(均值 = 0.60 V)。右:減去均值後,波形歸零於中心線。 圖 1 ── 左:含 DC 偏移的原始訊號(均值 = 0.60 V)。右:減去均值後,波形歸零於中心線。

去直流後,訊號的均值精確等於 0,所有 FFT 能量都正確代表振盪成分,而不是靜態偏移。

步驟二 補零(Zero-Padding)

Cooley-Tukey FFT 只有在 N 是 2 的次方時才能達到最佳效率。示波器擷取的點數幾乎不可能剛好是 2ⁿ。補零的做法是在訊號尾端填入 0,直到總長度達到下一個 2 的次方。10,000 個樣本對應的下一個值是 16,384

圖 2 ── 左:100 個原始樣本。右:補入 28 個 0(橘色區域)達到 128 = ²⁷。補零讓 FFT 更快,也讓頻譜曲線更平滑,但不會提高真正的頻率解析度。 圖 2 ── 左:100 個原始樣本。右:補入 28 個 0(橘色區域)達到 128 = ²⁷。補零讓 FFT 更快,也讓頻譜曲線更平滑,但不會提高真正的頻率解析度。

**重要:**補零不能增加頻率解析度。真正的解析度永遠是 Δf = fs / N原始點數。補零只是讓頻譜「插值得更密」,看起來更平滑。

步驟三 窗函數(Window Functions)

什麼是頻譜洩漏?

FFT 假設擷取的訊號會無限循環。如果訊號的末端無法平滑接回開頭***(這幾乎每次都發生)***邊界處的突然跳變會引入各種假頻率成分,擴散到整個頻譜。這就是頻譜洩漏(Spectral Leakage)。

窗函數如何解決?

窗函數是一條加權曲線,乘上每個樣本。它讓訊號兩端平滑地降到 0,頭尾自然接在一起,突變消失,洩漏大幅減少。

圖 3 ── 四種常見窗函數的形狀。矩形窗不做任何加權(最容易洩漏);Hann 和 Hamming 兩端平滑歸零;Flat-top 頂部極度平坦,以犧牲頻率解析度換取最高振幅精度。 圖 3 ── 四種常見窗函數的形狀。矩形窗不做任何加權(最容易洩漏);Hann 和 Hamming 兩端平滑歸零;Flat-top 頂部極度平坦,以犧牲頻率解析度換取最高振幅精度。

圖 4 ── 頻譜洩漏比較(訊號頻率為 5.7 Hz,不對齊任何 bin)。紅色虛線為真實頻率。矩形窗出現大量裙擺;Flat-top 的峰值即使不對齊 bin 仍最接近真實振幅。 圖 4 ── 頻譜洩漏比較(訊號頻率為 5.7 Hz,不對齊任何 bin)。紅色虛線為真實頻率。矩形窗出現大量裙擺;Flat-top 的峰值即使不對齊 bin 仍最接近真實振幅。

窗函數比較表

Flat-top 窗的數學公式

我們使用的是 5 項餘弦疊加版本:

w(i) = 0.21558–0.41663cos(θ) + 0.27726cos(2θ) — 0.08358cos(3θ) + 0.00695cos(4θ)

其中 θ = 2π·i / (N−1)。各項係數正負交替,讓函數在兩端略微低於 0,這正是頂部能如此平坦的原因。

步驟四 Cooley-Tukey FFT 演算法

直接計算離散傅立葉轉換(DFT)需要 O(N²) 次運算。N = 16,384 時約需 2 億 6 千萬次乘法。Cooley-Tukey 演算法利用對稱性,把複雜度壓到 O(N log₂N),約 22 萬次,速度提升約 1,000 倍

核心概念

演算法的關鍵洞察是:一個 N 點 DFT 可以分拆成兩個 N/2 點 DFT。反覆二分,直到變成 1 點 DFT(結果就是原值本身),再由下往上合併,過程稱為蝶形運算(Butterfly Operation)。

圖 5 ── N=8 的蝶形運算示意圖。三個階段(log₂8 = 3)從 bit-reversal 排列的輸入產生完整頻譜。每個階段用複數旋轉因子(twiddle factor)合併相鄰配對。 圖 5 ── N=8 的蝶形運算示意圖。三個階段(log₂8 = 3)從 bit-reversal 排列的輸入產生完整頻譜。每個階段用複數旋轉因子(twiddle factor)合併相鄰配對。

• 第一階段 ── Bit-reversal 排列:把輸入重新排序,使遞迴二分對應到簡單的索引交錯

• 第二階段 ── 蝶形運算:log₂(N) 個回合,每回合用旋轉因子 e^(−j2πk/N) 合併相鄰配對

最終結果與直接 DFT 完全相同,但快上千倍。

步驟五 振幅補償(Amplitude Correction Factor, ACF)

加了窗函數之後,訊號整體能量被壓低了──大多數樣本的加權係數都小於 1。不補償的話,頻譜上的每個振幅都會比真實值小。振幅修正因子(ACF)補回這個誤差:

振幅 = |FFT(i)| × (2 / N) × ACF

公式三個部分各司其職:

• |FFT(i)| ── FFT 複數輸出的絕對值(模)

• 2 / N ── FFT 正規化係數,同時補回正負頻率各佔一半的因素

  • ACF ── 窗函數專屬補償係數:Flat-top = 4.638、Hann = 2.0、Hamming = 1.852

圖 6 ── 淡色柱 = ACF 補償前,深色柱 = 補償後,紅色虛線 = 真實振幅(1.0 V)。補償後三種窗函數都能恢復正確峰值,但 Flat-top 在頻率不對齊 bin\u00a0時誤差最小。 圖 6 ── 淡色柱 = ACF 補償前,深色柱 = 補償後,紅色虛線 = 真實振幅(1.0 V)。補償後三種窗函數都能恢復正確峰值,但 Flat-top 在頻率不對齊 bin 時誤差最小。

步驟六 諧波提取與 THD

找基頻

計算完所有振幅後,掃描頻譜(排除 DC bin)找到最大的峰值,那就是基頻 f₁。我們的示波器資料結果是 228.9 Hz。

提取各次諧波

諧波是基頻的整數倍:2f₁、3f₁、…、10f₁。對每一個目標頻率,找到最近的 FFT bin 索引,讀取其振幅:

bin 索引 = round(諧波次數 × 基頻 / 頻率解析度)

總諧波失真(THD)

THD 衡量訊號中非基頻成分佔整體的比例,是電力品質的關鍵指標:

THD = sqrt(A²² + A³² + … + A1⁰²) / A1

圖 7 ── 左:log 刻度的諧波振幅。基頻(藍色)228.9 Hz 主導訊號,所有諧波(紅色)至少低 40 dB。右:能量佔比圓餅圖,THD = 1.37%,代表訊號非常純淨。 圖 7 ── 左:log 刻度的諧波振幅。基頻(藍色)228.9 Hz 主導訊號,所有諧波(紅色)至少低 40 dB。右:能量佔比圓餅圖,THD = 1.37%,代表訊號非常純淨。

THD 1.37% 遠低於 IEC 61000–3–2 Class A 奇次諧波限值 15%,確認訊號來源具有高度線性。

完整流程總結

以下是用 web 實作的完整諧波分析流程:

• 讀取任何 Tektronix 示波器 CSV(D 欄 = 時間、E 欄 = 電壓)

• 選擇窗函數:Flat-top、Hann、Hamming 或矩形(無窗)

• 程式自動去直流、加窗、補零至 2 的次方、執行 Cooley-Tukey FFT、振幅補償、提取 10 次諧波並計算 THD

  • 輸出 csv,包含Harmonic Summary, THD等等資訊

有興趣歡迎使用!

FFT Spectrum Analyser