วันนึงพี่เห็นวิดีโอของ Scott Marley ใน YouTube ที่ทำ VU meter ด้วย ESP32 แล้วพี่ก็เกิดไอเดียขึ้นมาเลย
ไอเดียนี้มันน่าสนใจมาก เพราะมันเป็นทางเลือกเจ๋งๆ แทนลำโพงเกมมิ่ง Lightsync ของ Logitech ได้เลยนะ ลำโพงของเขามันสร้างอารมณ์เวลาเล่นเกมได้ดีกว่าแถบไฟ RGB ทั่วไปที่แค่เปลี่ยนสีเฉยๆ เบื่อแล้ว
เอาล่ะ มาดูรายละเอียดของโปรเจคกันดีกว่า

ขอโทษทีที่ให้แผนภาพมือวาดมา แต่ช่างมัน! มาดูกันว่าวงจรทำงานยังไง
ต้องแน่ใจว่าแหล่งจ่ายไฟ 5V ของน้องจ่ายกระแสได้อย่างน้อย 2A นะ ส่วนใหญ่พอร์ต USB ของคอมก็น่าจะพอ ถ้าไม่ตั้งความสว่างสูงเกินไป
แนะนำให้ใช้แหล่งจ่ายไฟภายนอก อย่าเอาไฟ 5V จากขา Vin ของ ESP32 ไปใช้เลย AMS 1117 มันมีหน้าที่ลดไฟจาก 5V เป็น 3.3V ให้ ESP เท่านั้น ถ้าดึงกระแสจากมันมากไป มันจะร้อนและอาจจะพังได้
ค่าอาจจะเปลี่ยนไปตามความสว่างที่น้องตั้ง
- ช่องสัญญาณเสียงซ้ายและขวา ต่อเข้าที่ขาอินเวอร์ติ้งอินพุตของ OP AMP
- ใช้โพเทนชิออมิเตอร์ควบคุมเกนของ OP AMP ปรับเกนให้เหมาะสมกับ "ความดัง" ของสัญญาณเสียง เพื่อให้แถบไฟ LED ตอบสนองกับสัญญาณได้ (วงจรนี้ได้เกนประมาณ 20 เท่า)
เตือนใจ: อย่าตั้งเกนสูงเกินไป สัญญาณเสียงจะถูกตัด เพราะสัญญาณที่ขยายแล้วต้องอยู่ในช่วงที่ OP AMP ขยายได้ จะรู้ได้ว่าเมื่อไหร่สัญญาณถูกตัด เมื่อไฟสว่างจ้ามากๆ
- เพื่อให้ง่าย เราจะใช้แหล่งจ่ายไฟเดี่ยว (สมมติว่าส่วนใหญ่ไม่มีแหล่งจ่ายแบบ split supply) เราจะออฟเซ็ต virtual ground ของ OP AMP เพื่อให้มันขยายคลื่นเต็มรูป

- ใช้ตัวเก็บประจุที่เอาต์พุตเพื่อ AC Couple สัญญาณเอาต์พุต เอา virtual ground offset ที่ใส่ที่ขา non-inverting input ของ OP AMP ออก
- เราต้องออฟเซ็ตสัญญาณอีกครั้งด้วย voltage divider เพื่อให้สัญญาณอยู่ในช่วงบวก เพราะ ADC ของ ESP32 อ่านค่าแรงดันลบไม่ได้

จำไว้ว่านี่คือการจำลอง ผลลัพธ์จริงอาจต่างกันไปตามสภาพแวดล้อม พี่ไม่มีออสซิลโลสโคป นี่คือสิ่งที่ดีที่สุดที่พี่ทำได้
(ช่วง ADC ของ ESP32 = 0-3.3V)
พี่ตั้งแรงดันอินพุตให้ OP AMP เป็น 7.3V เพื่อให้สัญญาณอิ่มตัวก่อนที่จะไปถึงแรงดันสูงเกินที่อาจทำลายขา GPIO ของ ESP32 ได้
ถ้าน้องใช้โมดูล buck/boost converter แบบในรูปด้านล่าง มันจะมีสกรูเล็กๆ ให้น้องหมุนปรับแรงดันเอาต์พุตได้
ในกรณีของพี่ พี่มีปัญหาเวลาตั้งแรงดันตรงๆ เป็น 7.3V เลยต้องใช้ voltage divider เพื่อให้ได้ 7.3V สำหรับ OP AMP แทน
อย่าลืมต่อกราวด์ให้สัญญาณเสียงอินพุตนะ!


จบเรื่องฮาร์ดแวร์แล้ววว!
น้องจะใช้กล่องอะไรก็ได้เพื่อให้งานดูเป็นระเบียบและสวยงาม พี่ใช้กล่องเก่าที่เจาะรูสำหรับสายและอินพุต เลือกอะไรก็ได้ที่ชอบ ทำให้โปรเจคน้องพิเศษไปเลย!
หมายเหตุ:
ก่อนจะลงมือเขียนโค้ด แนะนำอย่างยิ่งให้น้องทำความคุ้นเคยกับไลบรารี FastLED ก่อน
อย่าลืมดูวิดีโอแนะนำเพื่อเตรียมตัวทำโปรเจคนะ รับรองว่าจัดไปวัยรุ่น!
High-Speed DSP: สเปกตรัมสเตอริโอแบบจัดเต็ม
ชิป MSGEQ7 นี่มันทางลัดง่ายๆ สำหรับเสียงช่องเดียว แต่ถ้าอยากเห็นภาพสองช่อง (สเตอริโอซ้าย-ขวา) แบบละเอียด 16 แถบจัดเต็ม น้องต้องบังคับให้ไมโครคอนโทรลเลอร์ทำงานประมวลผลสัญญาณดิจิทัล (DSP) ซะเอง ESP32 Stereo Visualizer ตัวนี้ใช้ความเร็วสปีดเทพของชิป 32 บิต 2 คอร์ ในการคำนวณ Fast Fourier Transform (FFT) แบบเรียลไทม์
Dual-Core Fast Fourier Transform
Arduino Uno วิ่งที่ 16MHz ส่วน ESP32 วิ่งที่ 240MHz ต่างกันลิบลับ!
- การเก็บตัวอย่าง (Sampling): ESP32 ใช้ขาแอนะล็อกสองขา (ขาซ้ายต่อช่องเสียงซ้าย, ขาขวาต่อช่องเสียงขวา) โดยใช้ตัวจับเวลา (hardware timer) เก็บตัวอย่างเสียง 40,000 ครั้งต่อวินาที
- การคำนวณ (ใช้ไลบรารี arduinoFFT): ไลบรารีนี้จะเอาตัวอย่างเสียงเล็กๆ 512 ตัวอย่าง ไปคำนวณสมการตรีโกณมิติซับซ้อน มันจะแปลงคลื่นเสียงที่วาดไปมาตามเวลา ให้กลายเป็นกราฟแท่งของความถี่ได้อย่างน่าอัศจรรย์
- เพราะ ESP32 มันเร็วมาก มันสามารถคำนวณ FFT สำหรับหูซ้าย แล้วก็คำนวณสำหรับหูขวาได้ทันที โดยไม่ทำให้เพลงสะดุดเลย
ใช้ WS2812B NeoPixel Matrix สองตัว
ภาพที่ออกมานี่สวยงามตาตั๊วตาตัวมาก
- น้องต้องต่อ เมทริกซ์ LED WS2812B ขนาด 16x16 สองตัว (วางซ้าย-ขวาของลำโพง)
- โค้ดจะทำการแมปแถบความถี่ 16 แถบ กับคอลัมน์ 16 คอลัมน์ของเมทริกซ์ LED
- คอลัมน์ 0 (ซ้ายสุด) แทนความถี่เบส 60Hz
- คอลัมน์ 15 (ขวาสุด) แทนความถี่สูง 16kHz
- ค่าอัมพลิจูดจาก FFT จะกำหนดว่าบาร์ NeoPixel จะสว่างแค่ไหน และพุ่งขึ้นสูงเท่าไหร่
- จานสี (Color Palettes): โดยใช้
<FastLED.h>บาร์จะถูกเปลี่ยนสีแบบไดนามิก (เช่น สีเขียวด้านล่าง ค่อยๆ เปลี่ยนเป็นสีแดงจัดตอนเสียงดังสุด)
อุปกรณ์ที่ต้องจัดให้ครบ
- ESP32 NodeMCU: สำคัญมากสำหรับความเร็วประมวลผล 240MHz
- เมทริกซ์ LED WS2812B ขนาด 16x16 สองตัว (รวมแล้วมี LED แยก 512 ดวง)
- แหล่งจ่ายไฟ 5V/15A ตัวเบิ้ม: เพื่อเลี้ยง NeoPixel 512 ดวงให้สว่างเต็มที่ ระวังไฟช็อตนะตัวนี้!
- แอมป์สเตอริโอ PAM8403 หรือ PAM8610: เพื่อให้ได้ยินเสียงเพลงไปพร้อมๆ กับดูแสงไฟ สู้งานนะน้อง
สอนใช้งาน Op Amp:
ESP32 8-Octave Audio Spectrum Display
ESP32 spectrum analyser VU meter using arduinoFFT and a FastLED matrix
พื้นฐาน FastLED:
ต้องขอบคุณ Scott Marley สำหรับบทสอนทั้งหมดเกี่ยวกับ FastLED และ Arduino FFT รวมถึงทุกคนที่ทำบทสอนออนไลน์ไว้ ช่วยให้โปรเจกต์นี้สำเร็จได้
หมายเหตุท้ายเรื่อง
จัดไปเลยวัยรุ่น! ปรับแต่งโค้ดให้เป็นลวดลายแบบที่ชอบได้ตามใจเลย แล้วก็เอาไปปรับให้เหมาะกับงานของตัวเองด้วย
เรื่องตัวต้านทาน (Resistor): ไม่จำเป็นต้องใช้ตัวต้านทานแบบเดียวกับในโปรเจกต์นี้เป๊ะๆ นะ เราแค่ใช้อะไรที่เหลือๆ อยู่เท่านั้นเอง ใช้ตัวไหนก็ได้ที่มันเวิร์ค!
แนะนำให้ใช้ ESP32: เพื่อให้แน่ใจว่าได้พลังม้าพอที่จะสุ่มตัวอย่างเสียง (sample audio) ที่ความถี่สูงๆ ได้ และทำงานเร็วพอที่จะได้อัตราเฟรม (frame rate) ของแถบไฟ LED ที่น่าพอใจ
ถ้า ESP32 ดับซ่าไปเฉยๆ: ให้เช็คแหล่งจ่ายไฟ (power supply) ของคุณก่อนเลย
ถ้ายังไม่เวิร์คอีก: ลองเปิด Serial Monitor ดูว่ามี back trace อะไรโผล่มาไหม อาจจะมี error ประเภท unhandled exception เกิดขึ้นก็ได้
ในกรณีนั้น: ให้รีเซ็ต ESP32 ผ่าน ESP32 flash tool ที่ดาวน์โหลดได้จากเว็บไซต์ทางการเลย
อัพเดท (7 ม.ค. 2020): ปัญหา error unhandled exception ในส่วน _amp ของโค้ด
สู้งานนะน้อง! ขอให้สนุกกับการทำของเล่นชิ้นนี้!