กลับไปหน้ารวมไฟล์
play-polyphonic-tones-c65443.md

ภาพรวมโปรเจกต์

"Sync-Harmonizer Polyphonic Engine" เป็นโปรเจกต์เสียงระดับเทพ ที่ทำลายกำแพง "เล่นโน้ตได้ทีละตัว" ของฟังก์ชัน tone() มาตรฐานบน Arduino ให้แหลกกระจาย! โดยการคว้า ไลบรารี MusicWithoutDelay มาใช้ร่วมกับ ไลบรารี Tone ที่ขับเคลื่อนด้วยฮาร์ดแวร์ไทเมอร์ ระบบนี้ทำให้ Arduino Uno ของเราสามารถเล่นเมโลดี้สองเสียงพร้อมกันได้แบบชิลๆ มันใช้รูปแบบ RTTL (Ring Tone Transfer Language)—ที่โด่งดังจากมือถือโนเกียรุ่นเก๋า—เพื่อเก็บโน้ตเพลงซับซ้อนไว้ในหน่วยความจำ และเล่นมันออกมาได้โดย ไม่บล็อกการทำงานของโค้ดหลักแม้แต่วินาทีเดียว นี่เป็นการศึกษาที่สำคัญในเรื่อง เสียงแบบขับเคลื่อนด้วยอินเตอร์รัปต์, ลอจิกของสเตทแมชชีน และ การมอดูเลตความถี่

วิดีโอ

ดาวน์โหลดไลบรารี

โปรเจกต์นี้เป็นตัวอย่างการใช้งานไลบรารี MusicWithoutDelay ที่พี่เขียนขึ้นมา

นอกจากนี้คุณยังต้องมีไลบรารี Tone อันเลื่องชื่อของ Bhagman ด้วย

ทำไมต้องทำ?

  • พี่สร้างไลบรารีนี้ขึ้นมาเพราะว่า... มันไม่มีวิธีที่จะเล่นเพลงสไตล์ 8-bit คลาสสิก ในขณะที่สเก็ตช์หลักของคุณกำลังรันอยู่ แถมการอ่านไฟล์เพลงของคนอื่นก็ยากและวุ่นวายอีกต่างหาก
  • พี่อยากเล่นโน้ตมากกว่าหนึ่งตัวพร้อมกันไงล่ะ หลังจากค้นคว้ามากมาย พี่ก็ได้ความสามารถนี้มาด้วยไลบรารี Tone ของ Bhagman น่าเสียดายที่จำนวนโน้ตที่เล่นพร้อมกันได้ ขึ้นอยู่กับว่าบอร์ดของคุณมีไทเมอร์กี่ตัว (ใช้ Timer0 ไม่ได้เพราะ millis() ใช้มันอยู่) ดังนั้น Arduino Uno เล่นได้สูงสุด 2 โน้ตพร้อมกัน

เพราะไม่มีใครสร้างไลบรารีเพื่อทำให้การเล่นและอ่านเพลงง่ายขึ้น พี่เลยตัดสินใจสร้างไลบรารีของตัวเองซะเลย

มันทำงานยังไง?

มันใช้ไลบรารี MusicWithoutDelay ของพี่เพื่อแปลงเพลงให้เป็นค่าความยาวเวลา (duration) ที่อ่านง่าย แล้วส่งให้ไลบรารี Tone ของ Bhagman เล่นต่อ

ไฟล์เพลงใช้รูปแบบ RTTL (Ring Tone Transfer Language) อันโด่งดัง ที่มือถือโนเกียรุ่นเก่าใช้สำหรับริงโทน

  • อยากรู้วิธีอ่านและเขียนเพลงของตัวเองมั้ย? ไปศึกษาเรื่อง RTTL ได้เลย
  • RTTL เป็นภาษาที่เข้าใจง่ายมากๆ ทั้งสำหรับนักดนตรีและมือใหม่หัดเล่น

ไฟล์เพลงเหล่านี้จะถูกเก็บไว้ในตัวแปรพอยน์เตอร์แบบ char ที่คุณเขียนก่อนฟังก์ชัน setup() จากนั้นไลบรารีของพี่จะรับไฟล์เพลงมาและแปลงมันเป็นมิลลิวินาที จำสเก็ตช์ BlinkWithoutDelay ได้มั้ย? ไลบรารีของพี่ใช้เทคนิคคล้ายๆ กันนั่นแหละในการเล่นโน้ต

ไฟล์เพลงจะถูกเก็บไว้ใน char *song

ลงลึกเรื่องเทคนิค

  • ความท้าทายของเสียงประสาน (การจัดสรร Timer):
    • ข้อจำกัดของ Hardware Timer: การสร้างพัลส์สำหรับความถี่เฉพาะเจาะจงต้องการจับเวลาที่แม่นยำ Arduino Uno (ATmega328P) มี Timer อยู่สามตัว: Timer0 (8-bit), Timer1 (16-bit), และ Timer2 (8-bit)
    • การจัดการทรัพยากร: เนื่องจาก Timer0 ถูกจองไว้ให้ millis() และ delay() อยู่แล้ว ไลบรารี่ Tone เลยใช้ Timer1 กับ Timer2 ในการขับขาพินเอาต์พุตสองช่องที่เป็นอิสระต่อกัน โปรเจคนี้จัดการทรัพยากรฮาร์ดแวร์สองตัวนี้เพื่อเล่นโน้ตประสานหรือไลน์เบส/เมโลดี้แยกกันได้พร้อมกัน
  • ตรรกะแบบ "Blink-Without-Delay" ที่ไม่บล็อกการทำงาน:
    • เครื่องเล่นเพลงทั่วไปใช้ delay() รอระหว่างโน้ต ซึ่งจะทำให้โปรเซสเซอร์หยุดนิ่ง ไลบรารี่ MusicWithoutDelay ใช้หลักการ State Machine มันจะตรวจสอบเวลาปัจจุบันเทียบกับ nextNoteTime ในทุกๆ รอบของ loop() ถ้าเวลาผ่านไปแล้ว มันก็จะอัปเดตความถี่ (Hz) และเลื่อนไปอ่านตัวอักษรถัดไปในสตริง RTTL
    • สถาปัตยกรรมแบบนี้ทำให้ระบบสามารถอ่านเซนเซอร์ อัปเดตไฟ RGB LED หรือตอบสนองต่ออินเตอร์รัปต์จากปุ่มได้ ขณะที่เพลงยังคงเล่นต่อด้วยความแม่นยำไร้การกระตุก
  • การแยกวิเคราะห์ RTTL (Ring Tone Transfer Language):
    • โครงสร้างโปรโตคอล: สตริง RTTL ประกอบด้วยสามส่วน: ชื่อ, การตั้งค่า (กำหนดค่าดีฟอลต์ของความยาวโน้ต d, ระดับเสียง o, และ BPM b), และ ข้อมูลโน้ต
    • คณิตศาสตร์ในการแยกวิเคราะห์: ไลบรารี่จะแปลงระดับเสียง (octave) และชื่อโน้ตให้เป็นดัชนีของความถี่ ตัวอย่างเช่น โน้ต 4c (Middle C) จะถูกแปลงเป็น 261.63Hz ความยาวของโน้ตคำนวณจากสูตร: $Duration (ms) = (60000 / BPM) \times (4 / NoteValue)$
  • การตอบสนองด้วยภาพแบบ Synesthetic:
    • โปรเจคนี้ผนวก RGB LED ที่ถูกโปรแกรมให้ทำงานประสานกับความถี่ที่กำลังเล่นอยู่ ด้วยการแมปช่วงความถี่ (31Hz ถึง 4978Hz) เข้ากับสเปกตรัมสี (โดยใช้ PWM) อุปกรณ์จะให้การแสดงผลทางภาพของเสียงประสาน สร้างเอฟเฟกต์ "Color-Organ" ได้อย่างมีประสิทธิภาพ

วิศวกรรมและการทำงาน

  • เครื่องยนต์ "เล่นย้อนเวลา": ไม่เหมือนเครื่องเล่นเพลงแบบตายตัว ไลบรารี่ MusicWithoutDelay ช่วยให้การเล่นเป็นแบบอินเตอร์แอคทีฟได้ เพราะมันใช้พอยน์เตอร์ชี้ไปยังสตริง RTTL ระบบจึงสามารถ ย้อนเมโลดี้ ได้แบบเรียลไทม์ หรือ ข้ามไปยังส่วนเฉพาะ (เช่น ท่อน verse/chorus) ได้ด้วยการจัดการดัชนีของสตริง
  • การเชื่อมต่อกับลำโพงเรโซแนนซ์: ใช้ตัวต้านทาน (Resistor) 220 โอห์มต่ออนุกรมกับลำโพง 8 โอห์มเพื่อจำกัดกระแสที่ดึงมาจากพินดิจิตอลของ Arduino (ให้อยู่ต่ำกว่า 40mA อย่างปลอดภัย) สำหรับเสียงที่ดังขึ้น ผู้พัฒนาขอแนะนำให้ใช้ LM386 audio amplifier หรือไดรเวอร์แบบ MOSFET เพื่อป้องกันความเครียดจากความร้อนบนชิป ATmega328P
  • การควบคุมอินเตอร์เฟซ: ปุ่มกดสามปุ่มถูกโปรแกรมไว้สำหรับ:
    1. เล่น/หยุดชั่วคราว: หยุดการทำงานของอินเตอร์รัปต์จาก Timer
    2. เลือกเพลง: วนลูปผ่านรายการพอยน์เตอร์ RTTL ที่เก็บไว้ใน Flash memory
    3. โหมดย้อนกลับ: สลับตรรกะการเพิ่ม/ลดของตัวแยกวิเคราะห์
  • การประยุกต์ใช้ในอุตสาหกรรม: นอกเหนือจากเพลง 8-bit แล้ว เทคนิคเสียงประสานนี้มีความสำคัญมากสำหรับ ระบบสัญญาณเตือนภัยในอุตสาหกรรม ที่จำเป็นต้องสร้างสัญญาณ "เร่งด่วน" ที่มีโทนเสียงหลายแบบที่แตกต่างกัน ขณะที่ยังคงต้องเฝ้าติดตามเซนเซอร์วัดอุณหภูมิหรือความดันเพื่อรับข้อมูลด้านความปลอดภัยที่สำคัญ

ข้อดี

  • เล่นโน้ตหลายตัวพร้อมกันได้ (จัดไปวัยรุ่น!)
  • รันงานอื่นๆ อย่าง Serial monitor ไปด้วยในพื้นหลังได้ (มัลติทาสกิ้งแบบไม่สะดุด)
  • เล่นเพลงย้อนหลังหรือเดินหน้าได้ (Rewind/Forward แบบกดเล่น)
  • หยุด/เล่นเพลงได้ตามใจ (Pause/Play)
  • ข้ามไปยังท่อนเฉพาะในเพลงได้ (Skip to section)
  • เลือกเพลงใหม่ได้เมื่อไหร่ก็ได้
  • อีกเพียบรออยู่ข้างหน้า :D

อัพเกรดประสบการณ์เสียงในโปรเจคต์ของคุณ: ทำนองประสานเสียง พร้อมทำงานหลายอย่างแบบไม่บล็อก (non-blocking)! สู้งานนะน้อง!

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

apps:
  - "1x Arduino IDE"
author: "nathan_ramanathan"
category: "Audio & Sound"
components:
  - "1x Speaker: 0.25W, 8 ohms"
  - "1x Arduino UNO"
  - "1x vibrating motor"
  - "2x Resistor 221 ohm"
  - "3x Pushbutton switch 12mm"
  - "1x Jumper wires (generic)"
  - "1x Breadboard (generic)"
  - "1x RGB Diffused Common Cathode"
description: "โปรเจกต์นี้ใช้ไลบรารี MusicWithoutDelay ของพี่เลย งานง่ายแต่หล่อ ตึงๆ เพราะเล่นเสียงโพลีโฟนิกได้หลายเสียงพร้อมกันแบบจัดเต็ม!"
difficulty: "Intermediate"
documentationLinks: []
downloadableFiles: []
encryptedPayload: "U2FsdGVkX18tD71V2qe4YUZ2SXyPCNRs4rH3J0dQOz1PJq8mZWREOmnHADHPWlfa50SecE7fou3BeCizJQCnVFPAyIbyW4eZVUv1oNbr7Vg="
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/play-polyphonic-tones-c65443_cover.jpg"
lang: "en"
likes: 23
passwordHash: "5eb5c09b58f7eb23184fa602c26d9f69a274f69241dc79a0f0d2d8478b1df123"
price: 299
seoDescription: "Play polyphonic tones on Arduino using the MusicWithoutDelay library to output multiple sounds simultaneously."
tags:
  - "audio"
  - "lights"
title: "มาเล่นเสียงหลายชั้นแบบเทพๆ กันดีกว่า!"
tools: []
videoLinks:
  - "https://www.youtube.com/embed/uoHhlrqZYDI"
views: 39598