กลับไปหน้ารวมไฟล์
dft-audio-analyser-b2fee9.md

ไอเดียคร่าวๆ

ไอเดียของโปรเจคนี้คือการเอา DFT ไปรันบนไมโครคอนโทรลเลอร์ AVR 8 บิต ด้วยอัลกอริทึมแบบง่ายสุดๆ แล้วให้มันแสดงผลการแปลงฟูเรียร์ของสัญญาณเสียงแบบเรียลไทม์ได้เลย

ก่อนจะเริ่มลงมือกัน มาดูกันก่อนว่าน้องต้องรู้อะไรบ้าง:

  • DFT - สมการและการตีความทางคณิตศาสตร์
  • ไมโครคอนโทรลเลอร์ตระกูล AVR: พื้นฐานและการเขียนโปรแกรมด้วย C
  • อิเล็กทรอนิกส์สำหรับงานเสียง

ถ้าพร้อมแล้วกับหัวข้อพวกนั้น... มาจัดการกันเลย!

อย่างที่รู้กัน 'เสียง' เกิดจากการรบกวนทางกายภาพในตัวกลาง สิ่งนี้สร้างขึ้นด้วยลำโพงที่แปลงสัญญาณไฟฟ้ารูปไซน์ให้เป็นการกระจัด ดังนั้นคลื่นเสียงทั้งหมดก็มาจากสัญญาณไซน์นั่นแหละ และคลื่นใดๆ ก็สามารถแสดงเป็นผลรวมแบบถ่วงน้ำหนักของคลื่นไซน์ที่มีความถี่เชิงมุมเป็นพหุคูณของความถี่ฐานได้ สมการด้านล่างคือรูปแบบทางคณิตศาสตร์ของคลื่นใดๆ โดยที่น้ำหนัก (weights) ก็คือแอมพลิจูดของความถี่นั้นๆ เอง อัลกอริทึม DFT จะทำหน้าที่หา weights พวกนี้สำหรับความถี่ต่างๆ เมื่อเราให้สัญญาณที่ไม่รู้จักเข้าไป

อัลกอริทึม DFT

ทีนี้ DFT สามารถคำนวณได้จากสมการนี้:

สมการด้านบนนี่เอาไปเขียนใน C ได้ตรงๆ เลย แต่ก่อนจะเข้าสู่โค้ด มาดูวงจรกันก่อน:

ลงมือต่อวงจร

สำหรับวงจรนี้ เราใช้ ATmega328P กับ LCD JHD162A นะ LCD ต่อเข้ากับ PORT-D ของ MCU และตั้งค่าให้ทำงานในโหมดบัสข้อมูล 4 บิต ส่วน LM386 นั้นเป็นแอมป์เสียงโดยเฉพาะ หน้าที่ของมันคือขยายสัญญาณเสียงซึ่งปกติจะมีแอมพลิจูดสูงสุดแค่ประมาณ 0.7V เพื่อผลลัพธ์ที่แม่นยำ เราต้องปรับค่าโพเทนชิออมิเตอร์ 10K ให้เหมาะสม รวมถึงจัดวางตัวเก็บประจุให้ดีเพื่อลดสัญญาณรบกวนให้เหลือน้อยที่สุด

การลงมือทำจริง: ตารางไซน์-โคไซน์ และการแสดงผลแบบฮิสโตแกรม

โปรเจคนี้เผยให้เห็นเลเยอร์ต่างๆ ของการทำงานแบบง่ายๆ ตั้งแต่รับสัญญาณไปจนถึงแสดงผล:

  • เลเยอร์ตรวจจับ: ADC ใน ATMega328p
  • เลเยอร์แปลงสัญญาณ: ระบบใช้พินดิจิทัลความเร็วสูงเพื่อรับสถานะบิตแบบเร่งด่วน เพื่อประสานงานงานสำคัญๆ ด้านการรับรู้
  • เลเยอร์อินเทอร์เฟซสเปกตรัม: LCD 16x2 แบบคัสตอมแคร็กเตอร์
  • เลเยอร์อินเทอร์เฟซเสียง: แอมป์ LM386
  • ลอจิกการประมวลผล: โค้ด C ใช้กลยุทธ์ "ตารางค้นหา" (หรือ DFT-dispatch): มันจะตีความค่าสัญญาณเสียงที่สุ่มมา แล้วจับคู่กับบินความถี่ต่างๆ เพื่อให้การวิเคราะห์สเปกตรัมภาพที่ปลอดภัยและเป็นจังหวะ โดยไม่ต้องพึ่งฟังก์ชันใน math.h ที่คำนวณช้า

หลังจากอัพโหลดโค้ดเสร็จ พอเริ่มต้น ตัวคอนโทรลเลอร์จะเซ็ตพิน I/O จากนั้นตั้งค่า ADC โหลดไดรเวอร์ LCD แล้วก็รันแอนิเมชั่นตอนบูต...

ส่วนโค้ด DFT จะเริ่มรันตั้งแต่บรรทัดที่ 7 นับจาก 'int main()'

ในที่นี้เราใช้ DFT 32 จุด เพื่อให้สามารถจำแนกสัญญาณเสียงเข้าเป็น 16 ความถี่ได้ สำหรับ DFT 32 จุด นี้ MCU ต้องคำนวณค่า ไซน์และโคไซน์ทั้งหมด 512 ค่า ถ้าใช้ฟังก์ชันจากไลบรารี math.h การคำนวณจะใช้เวลานานมาก ดังนั้นเราจึงสร้างตารางค้นหา (lookup table) เก็บไว้ในแฟลชของ MCU แทน ทำให้การคำนวณเร็วขึ้นมากและแสดงผลแบบเรียลไทม์ได้สำเร็จ สู้งานนะน้อง!

พอโปรแกรมเคาน์เตอร์วิ่งเข้ามาในส่วนแอปพลิเคชัน (ลูปอนันต์) อันดับแรกมันจะทำการสุ่มตัวอย่างอินพุต แล้วส่งต่อไปให้ DFT ผลลัพธ์จะแสดงออกมาในรูปแบบกราฟแท่ง (ฮิสโตแกรม) บน LCD ซึ่งเราเรียกมันว่า 'บิน' (bins) นั่นแหละ

ที่นี่เราใช้ Character LCD ธรรมดา เลยต้องมานั่งกำหนดรูปแท่งกราฟเองด้วยการเขียนโค้ดเพิ่ม LCD รุ่นนี้มันให้เราสร้าง 8 ตัวอักษรกำหนดเอง (Custom Character) ได้ โดยแต่ละตัวใช้พื้นที่ 8 ไบต์ ในซอร์สโค้ดพี่เขียนฟังก์ชันสำหรับสร้างตัวอักษรพวกนี้ไว้ให้แล้ว จัดไปวัยรุ่น

ส่วนสุ่มตัวอย่างเสียง (Audio Sampling)

มาเข้าเรื่องการสุ่มตัวอย่างเสียงกันดีกว่า พอ MCU เริ่มทำงาน มันจะเข้าสู่โหมด 0 (mode0) โดยอัตโนมัติ ซึ่งมีความถี่สุ่มตัวอย่าง (Sampling Frequency) อยู่ที่ 17.920 Ksps เราก็เลยได้ช่วงความถี่ที่วิเคราะห์ได้ประมาณ 560 - 8960 Hz ตามเกณฑ์ของ Nyquist ไงล่ะ อัตราการสุ่มตัวอย่างนี่กำหนดด้วยค่า Prescaler ของ ADC ซึ่งเซ็ตไว้ในรีจิสเตอร์ ADCSRA ของ MCU

ปุ่ม 'SW' เนี่ย เอาไว้ใช้สลับช่วงความถี่นั่นเอง คือเริ่มต้นจะอยู่ที่ 560 - 8960 Hz (mode0) พอกดปุ่มมันจะเปลี่ยนเป็น 280 - 4480 Hz (mode1, อัตราสุ่มตัวอย่าง = 8960 Hz) พอกดอีกทีก็กลับมาที่โหมดเริ่มต้น สรุปคือปุ่มนี้มันไปสลับค่าในรีจิสเตอร์ ADCSRA นั่นเอง (อยากรู้ลึกกว่านี้ ไปเปิด datasheet ของ MCU ดูนะน้อง ห้ามช็อตนะตัวนี้)

ผลลัพธ์จาก DFT จะออกมาในช่วง 0 - 32 (ประมาณนี่แหละ) (ต้องปรับ Trimmer Pot ให้เหมาะสม หรือไม่ก็เพิ่มโค้ดสำหรับหารค่าผลลัพธ์เพื่อปรับสเกล) พี่เลยเอามาหาร 2 เพื่อปรับสเกลก่อนส่งไปแสดงผลบน LCD (ดูในโค้ดได้)

สำคัญมาก: ถ้าอยากให้การวิเคราะห์สเปกตรัมแม่นยำ อย่าลืมทำ ADC Offset Calibration (ค่ากลางมักจะอยู่ที่ 511 บิต) ในโค้ดด้วย! และต้องมั่นใจว่าตั้ง อัตราการสุ่มตัวอย่าง (Sampling Rate) (เช่น 17.92 Ksps) ให้เหมาะสมกับช่วงความถี่เสียงที่ต้องการวิเคราะห์ทุกครั้ง!

รูป DFT เมื่อให้อินพุตและโหมดต่างกัน:

ทีนี้คำถามก็คือ 'เจ้าเครื่องนี้มันแม่นยำแค่ไหน?' เนื่องจากพี่ใช้วิธี Lookup Table เพื่อประหยัดพื้นที่ใน Flash พี่เลยเก็บค่าจำนวนเต็มของ sine กับ cosine โดยคูณมันขึ้นมา 1000 เท่า แล้วค่อยหารผลลัพธ์สุดท้ายลง 1000 เท่า มันเลยไม่ใช่เครื่องมือที่แม่นยำสุดๆ แต่เรื่องความแม่นยำเนี่ย เราต้องหาจุดสมดุลระหว่างความแม่นยำกับความเร็วให้ดี พี่เลือกแสดงผลแบบเรียลไทม์ เลยยอมลดความแม่นยำลงนิดหน่อย แต่มันก็ยังมีความแม่นยำและความเร็วที่ใช้การได้ดีเลยล่ะ เมื่อเทียบกับอุปกรณ์ที่ใช้ฟังก์ชันจากไลบรารี math.h

สาธิตการทำงาน

นี่คือวิดีโอสาธิต DFT Audio Analyser กำลังวิเคราะห์เพลง 'flute' โดย Tony Igy

แนวทางการพัฒนาต่อ

  • เพิ่ม OLED Identity Dashboard: ต่อจอ OLED ขนาดเล็กเพื่อแสดงข้อมูลเช่น "ความถี่สูงสุด (Peak Frequency)" หรือเมตริกอื่นๆ
  • เพิ่ม Multi-sensor Sync Synchronization: ต่อโมดูลบลูทูธเฉพาะทาง เพื่อทำการวิเคราะห์ "Wireless Spectrogram" แบบไร้สายด้วยความแม่นยำสูงขึ้น
  • เพิ่ม Cloud Interface Registration Support: สร้างเว็บแดชบอร์ดเฉพาะทางบนสมาร์ทโฟนผ่าน WiFi/BT เพื่อติดตามและบันทึกประวัติการวิเคราะห์เสียงได้อย่างแม่นยำ
  • เพิ่ม Advanced Profile Customization Support: บูรณาการอัลกอริทึมเฉพาะทาง เพื่อให้สามารถเปลี่ยนค่า Trigger อัตโนมัติตามอินพุตจากผู้ใช้หรือลักษณะของสัญญาณได้

DFT Audio Analyser เป็นโปรเจกต์ที่เพอร์เฟกต์สำหรับสายวิทย์ที่กำลังมองหาเครื่องมือสำหรับวิเคราะห์สัญญาณแบบอินเทอร์แอคทีฟและน่าสนใจ! สู้งานนะน้อง

สำหรับโปรเจกต์ Arduino และ AVR อื่นๆ

ข้อมูล Frontmatter ดั้งเดิม

apps:
  - "1x Microchip Studio (C programming)"
  - "1x Arduino IDE"
author: "AkashKollipara"
category: "Audio & Sound, Embedded Systems"
components:
  - "1x Arduino UNO (ATMega328p)"
  - "1x Standard LCD - 16x2 White on Blue"
  - "1x LM386 Audio Amplifier (Module)"
  - "1x Trimmer Potentiometer, 10 kohm (for Gain/Offset)"
  - "1x Pushbutton (for Mode selection)"
  - "1x Breadboard (generic)"
  - "12x Jumper wires (generic)"
  - "1x Micro-USB Cable"
description: "A professional and advanced signal-processing project that uses an ATMega328p microcontroller and high-speed Discrete Fourier Transform (DFT) algorithms to build a real-time audio frequency spectrum visualizer with a custom-character LCD histogram."
difficulty: "Intermediate"
documentationLinks: []
downloadableFiles:
  - "https://projects.arduinocontent.cc/deea4cb5-ea57-4d69-99ce-caae3019aa18.c"
encryptedPayload: "U2FsdGVkX1+8xs/IW7Sw+2rVaT3BtC32hPI3Nnf8CggeyvDEB86LgsQ7/CYIPf8waHBDaHU6JpdUXWfxERcn5LQukjP//XBMb8/LqIvPZU8="
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/dft-audio-analyser-b2fee9_cover.jpeg"
lang: "en"
likes: 6
passwordHash: "38c65f3721f8795627f53baff5d0c5e2e578419a1b6e9c26efe6e95f74c5aa13"
price: 2450
seoDescription: "An advanced and playsomely interactive DFT-Audio-Analyser-Sync for beginners interested in Arduino signal-processing and audio-to-viz projects."
tags:
  - "dft-audio-analyser"
  - "spectrum-visualizer"
  - "signal-processing"
  - "atmega328p-c"
  - "arduino-uno"
  - "advanced"
title: "โปรเจค DFT วิเคราะห์เสียง ตึงๆ วัยรุ่น!"
tools: []
videoLinks:
  - "https://www.youtube.com/embed/VJ9gT_6wWdE"
views: 9690