Raspberry Pi Pico เรียนรู้ ADC และ FFT แบบเข้าใจง่าย
อยากรู้ว่า Raspberry Pi Pico สามารถอ่านสัญญาณอนาล็อกและวิเคราะห์ความถี่ได้อย่างไร? ADC (Analog-to-Digital Converter) และ FFT (Fast Fourier Transform) เป็นเครื่องมือที่ทรงพลังสำหรับการประมวลผลสัญญาณ บทความนี้จะพาคุณสำรวจเทคนิคเหล่านี้ด้วยตัวอย่างโค้ดและการอธิบายที่เข้าใจง่าย เหมาะสำหรับผู้ที่เริ่มต้นศึกษาการประมวลผลเสียงและสัญญาณ

พื้นหลังและความรู้เบื้องต้น
ก่อนที่จะเจาะลึกเข้าไปในรายละเอียด ลองมาเข้าใจแนวความคิดพื้นฐาน:
สัญญาณอนาล็อก
ค่าต่อเนื่องที่เปลี่ยนแปลงตลอดเวลา เช่น เสียง อุณหภูมิ ความสว่าง
สัญญาณดิจิทัล
ค่าที่เป็นตัวเลขแยกแยะ ที่คอมพิวเตอร์สามารถเข้าใจได้
ADC
แปลงสัญญาณอนาล็อกเป็นตัวเลขดิจิทัล
FFT
แปลงข้อมูลเสียงเป็นข้อมูลความถี่
Raspberry Pi Pico มี ADC ตัวใจ 12-bit ที่สามารถสุ่มเก็บข้อมูล (Sampling) ได้ที่ความเร็วสูง โดยใช้พิน GPIO ที่กำหนด เมื่อเรามีข้อมูลดิจิทัลแล้ว เราสามารถใช้ FFT เพื่อวิเคราะห์ว่าสัญญาณประกอบด้วยความถี่ใดบ้าง
💡 ใช้งานจริง: ADC + FFT ใช้ในการบันทึกเสียง ตรวจจับโทนเสียง วิเคราะห์ EEG หรือสัญญาณเซ็นเซอร์อื่น ๆ
ADC Sampling: อ่านสัญญาณอนาล็อก
ADC (Analog-to-Digital Converter) คือสมองส่วนที่เปลี่ยนสัญญาณอนาล็อกที่ต่อเนื่องเป็นตัวเลข ที่คอมพิวเตอร์สามารถเข้าใจและประมวลผลได้
ขั้นตอนการทำงาน:
1. สุ่มเก็บข้อมูล (Sampling): ADC อ่านค่าแรงดันไฟฟ้า ณ เวลาที่กำหนด (เช่น ทุก 1 ไมโครวินาที)
2. แปลงค่า: แปลงแรงดันไฟฟ้า (0-3.3V) ให้เป็นตัวเลข (0-4095) โดยใช้ 12 บิต
3. เก็บข้อมูล: ตัวเลขเหล่านี้ถูกเก็บไว้ในหน่วยความจำสำหรับการประมวลผลต่อไป
Pico มี 4 ช่องสำหรับ ADC:
GPIO 26
GPIO 27
GPIO 28
สำหรับวัดอุณหภูมิภายใน
การเลือก Sampling Rate (อัตราการสุ่มเก็บข้อมูล) นั้นสำคัญ ตามทฤษฎีของ Nyquist ค่า Sampling Rate ต้องเป็นสองเท่าของความถี่สูงสุดของสัญญาณที่ต้องการบันทึก
ตัวอย่าง: เพื่อบันทึกเสียงมนุษย์ (ประมาณ 20Hz-20kHz) ต้องใช้ Sampling Rate 48kHz ขึ้นไป (เสียงสมดุล CD ใช้ 44.1kHz)
FFT: แปลงสัญญาณเป็นความถี่
FFT (Fast Fourier Transform) เป็นสูตรทางคณิตศาสตร์ที่มหัศจรรย์ ที่เปลี่ยนการดูสัญญาณจากมุมมอง "เวลา" เป็นมุมมอง "ความถี่"
ลองนึกภาพแบบนี้:
มุมมองเวลา: "ฉันได้ยินเสียง และมันลดลงแล้วเพิ่มขึ้นตามเวลา" (ตัวอักษรชี้ขึ้นและลง)
มุมมองความถี่: "เสียงนี้เป็นการรวมกันของความถี่ 440Hz 880Hz และ 1320Hz" (ธนาคารของสูตร)
FFT ช่วยให้เราเห็นว่าสัญญาณนั้นประกอบด้วยความถี่ใด ซึ่งมีประโยชน์มากในการ:
- → ตรวจจับโทนเสียง (ความถี่ที่หลัก)
- → กรองสัญญาณรบกวน (Noise Filtering)
- → วิเคราะห์ผลการแขวนระบบ (Frequency Analysis)
- → สร้างสเปกตรัมแสดงผล (Spectrum Analyzer)
Pico ไม่มี FFT Library ตัวเอง แต่มีห้องสมุด CMSIS-DSP จาก ARM ที่ให้มาพร้อม Pico SDK ซึ่งมี Optimized FFT Function พร้อมใช้งาน
💡 ความเร็ว: FFT ใช้เวลา 16,384 ตัวอย่าง ประมาณ 10-50ms ขึ้นอยู่กับขนาด (ตามปกติ 256-1024 ตัวอย่าง)
ตั้งค่าสภาพแวดล้อมและ Compile
เพื่อใช้ ADC และ FFT บน Pico ต้องตั้งค่าสภาพแวดล้อมการพัฒนา:
ขั้นตอนที่ 1: ติดตั้ง Pico SDK
ดาวน์โหลด Pico SDK จากเว็บไซต์ Raspberry Pi และตั้งค่า PATH ให้ถูกต้อง
ขั้นตอนที่ 2: ติดตั้ง ARM Toolchain
ติดตั้ง GCC สำหรับ ARM เพื่อ Compile โค้ด C/C++
ขั้นตอนที่ 3: ตั้งค่า CMakeLists.txt
ในไฟล์ CMakeLists.txt เพิ่ม:target_link_libraries(project_name pico_stdlib arm_cortex_cmsis_dsp)
ขั้นตอนที่ 4: Clone ตัวอย่างโปรเจกต์
Clone จาก GitHub: github.com/AlexFWulff/awulff-pico-playground
ขั้นตอนที่ 5: Build และ Upload
ใช้ Command Line:cmake ..make -j4
จากนั้น Copy ไฟล์ .uf2 ไป Pico
ตัวอย่างโค้ด ADC และ FFT
โค้ด ADC สำหรับการสุ่มเก็บข้อมูล:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#define SAMPLES 1024
uint16_t adc_buffer[SAMPLES];
void init_adc() {
adc_init();
adc_gpio_init(26); // ADC0
adc_select_input(0);
}
void sample_adc() {
for (int i = 0; i < SAMPLES; i++) {
adc_buffer[i] = adc_read();
}
}
int main() {
stdio_init_all();
init_adc();
while (1) {
sample_adc();
// พิมพ์ข้อมูลที่ได้
for (int i = 0; i < SAMPLES; i++) {
printf("%d\n", adc_buffer[i]);
}
}
}
โค้ด FFT สำหรับการวิเคราะห์ความถี่:
#include "arm_math.h"
#define FFT_SIZE 256
float32_t fft_input[FFT_SIZE * 2];
float32_t fft_output[FFT_SIZE];
void perform_fft() {
arm_cfft_f32(&arm_cfft_sR_f32_len256,
fft_input, 0, 1);
arm_cmplx_mag_f32(fft_input, fft_output,
FFT_SIZE);
}
void find_peak_frequency() {
uint32_t max_idx = 0;
float32_t max_val = 0;
for (int i = 0; i < FFT_SIZE/2; i++) {
if (fft_output[i] > max_val) {
max_val = fft_output[i];
max_idx = i;
}
}
printf("Peak frequency bin: %d\n", max_idx);
}
หมายเหตุ: FFT ต้องการข้อมูลที่เป็นจำนวนเชิงซ้อน (Complex Numbers) ดังนั้นต้องเตรียมข้อมูลให้เหมาะสมก่อน




การใช้งานจริง
ADC และ FFT มีประโยชน์มากมายในโปรเจกต์จริง:
🎵 Sound Analysis
บันทึกเสียงและวิเคราะห์ความถี่เพื่อตรวจจับโทนเสียงหรือเสียงพูด
📡 Signal Detection
ตรวจจับสัญญาณไร้สาย (RF Signal) หรือสัญญาณใดก็ได้
🏥 Biomedical
ติดตามหัวใจ EKG หรือวัดการสั่นสะเทือน (Vibration Analysis)
🎮 Interactive Projects
สร้างตัวควบคุมด้วยเสียง หรือ Gesture Recognition
🔧 Predictive Maintenance
วิเคราะห์เสียงของเครื่องเพื่อเตือนก่อนเกิดความเสียหาย
เคล็ดลับและการแก้ไขปัญหา
💡 ปรับปรุงคุณภาพ ADC
ใช้ capacitor 100nF ต่อจาก GPIO ไป GND เพื่อกรองสัญญาณรบกวน
🎯 เลือก FFT Size ที่เหมาะสม
ขนาด 256-512 เหมาะสำหรับโครงการ Pico ส่วน 1024-2048 ต้องการ RAM มากขึ้น
⚡ ประหยัดพลังงาน
ใช้ Oversampling และถัวเฉลี่ย (Averaging) เพื่อลดตัวอักษรสัญญาณรบกวน
🔍 Debug ผ่าน Serial Monitor
ใช้ Serial Port เพื่อดูค่า ADC และ FFT ในเวลาจริง
❌ หลีกเลี่ยง Aliasing
ใช้ Low-Pass Filter เพื่อตัดความถี่ที่สูงกว่า Nyquist Frequency
ขั้นตอนถัดไป: พัฒนาเพิ่มเติม
หลังจากเรียนรู้พื้นฐาน ADC และ FFT แล้ว คุณสามารถ:
- → ใช้ Window Function: Hamming, Hann เพื่อลดสเปกตรัล Leakage
- → Real-time Processing: ประมวลผล ADC โดยรับข้อมูลใหม่ขณะประมวลผลก่อนหน้า
- → Digital Filter Design: สร้าง IIR หรือ FIR Filter ของตัวเอง
- → Visualization: ส่งข้อมูล FFT ไปยังคอมพิวเตอร์แล้วแสดงผลแบบ Real-time
- → Multi-channel ADC: ใช้หลายช่อง ADC พร้อมกันเพื่อบันทึกสเตอริโอ
แหล่งเรียนรู้เพิ่มเติม
ต่อไปนี้เป็นแหล่งข้อมูลดีสำหรับเรียนรู้เพิ่มเติม:
- ✓ Pico Documentation: github.com/raspberrypi/pico-sdk (Official Docs)
- ✓ CMSIS-DSP Manual: ARM Developer Documentation
- ✓ Example Code: github.com/AlexFWulff/awulff-pico-playground
- ✓ DSP Tutorial: www.dspguide.com (Digital Signal Processing)
เริ่มต้นทดลองกับ Pico วันนี้
สั่งซื้อ Raspberry Pi Pico พร้อมเซ็นเซอร์ หรือปรึกษาทีมผู้เชี่ยวชาญของเรา