เป็นนักดนตรี เลยต้องใช้พวกซอฟต์แวร์อัดเสียง, เครื่องดนตรี VST, อุปกรณ์เล่นเสียง ฯลฯ การใช้ปุ่มหมุนหรือเฟดเดอร์แบบจับต้องได้มันง่ายดี แต่ถ้านั่งจ้องแต่หน้าจอคอม มันก็ต้องมัวแต่กดเมาส์เลื่อนไปมา
ถ้าเป็นมือกลองนี่ทำไม่ได้เลยอะ :)
ก่อนหน้านี้เคยทำระบบเมนูด้วย Encoder กับจอ OLED แบบง่ายๆ ไปแล้ว โปรเจกต์นี้เลยเอามาพัฒนาต่อให้เจ๋งขึ้น แล้วเอามารวมกับระบบ MIDI ซะเลย
สเปคคร่าวๆ
- จอยสติ๊ก 1 ตัว สำหรับควบคุมพล็อตเตอร์ XY
- โพเทนชิโอมิเตอร์ (เฟดเดอร์) 4 ตัว (เพิ่มได้ตามจำนวนพอร์ตในบอร์ด)
- ปุ่มกด 9 ปุ่ม
- จอแสดงผล OLED
- ตัวควบคุม Encoder
- ปุ่มเปิด/ปิดการทำงาน
- เมนูตั้งค่า
- ใช้งานง่าย (สำหรับพี่นะ)
สัญญาณ MIDI จะวิ่งผ่านสาย USB ไปยังคอมพิวเตอร์ โดยใช้ Hairless MIDI รับสัญญาณจากพอร์ตอนุกรม (Serial) แล้วส่งต่อไปยังช่อง MIDI ต่างๆ
การต่อสายไม่ยากเลย เดี๋ยวพี่แจกขั้นตอนให้
1 - Oled SDA ต่อกับ A4 2 - Oled SCL ต่อกับ A5 3 - Oled GND ต่อกับ GND, VCC ต่อกับ +5V 4 - Encoder GND ต่อกับ GND, VCC ต่อกับ +5V 5 - Encoder sw ต่อกับขา switch ที่กำหนดในโค้ด 6 - Encoder CLK ต่อกับขา Digital 2 7 - Encoder Data ต่อกับขา Digital 3 8 - Joystick GND ต่อกับ GND, +5V ต่อกับ +5V 9 - Joystick x ต่อกับ A0, y ต่อกับ A1 10 - โพเทนชิโอมิเตอร์ต่อกับขา Analog อื่นๆ ที่เหลือ
Hairless MIDI จะอ่านข้อมูลจากพอร์ตอนุกรม ดังนั้นอัตราบอด (Baud Rate) ต้องตรงกัน อัตราบอดเริ่มต้นของ Hairless MIDI คือ 115200
Hairless MIDI รับข้อมูลจากพอร์ตอนุกรม แล้วเราก็ต้องเอาข้อมูลนี้ส่งต่อไปยังพอร์ต MIDI อีกที ซึ่ง loopMIDI ทำหน้าที่นี้ได้ดีมาก มันสร้างพอร์ต MIDI เสมือนสำหรับรับ-ส่งข้อมูล

The Infinite Rotary Encoder Library
ปุ่มปรับเสียงทั่วไปมันหมุนได้แค่ 0-100% แต่ Rotary Encoder นี่หมุนได้ไม่รู้จบ เลยเหมาะมากสำหรับใช้กับ DAW แบบดิจิทัล
- Encoder จะส่งสัญญาณพัลส์สองชุดออกมาเป็นคลื่นใหญ่ๆ (เรียกว่า
A และ Bใช้หลักการ Quadrature) - ถ้าขา A ขึ้น HIGH ก่อนขา B แปลว่าหมุนไปทาง ขวา แต่ถ้าขา B ขึ้นก่อน แปลว่าหมุนไปทาง ซ้าย
- ฮาร์ดแวร์อินเตอร์รัปต์ (Hardware Interrupt): เพื่อไม่ให้พลาดพัลส์เล็กๆ น้อยๆ เราต้องต่อ Encoder กับ
ขา 2 และ 3เท่านั้น แล้วใช้คำสั่งattachInterrupt(0, readEncoder, CHANGE); - โค้ด C++ จะอัปเดตตัวแปร
counterอย่างรวดเร็ว พอค่าเพิ่มจาก 0 ไปเป็น +10 Arduino ก็ต้องแปลงค่านั้นให้เป็นข้อมูล MIDI CC ขนาดใหญ่ส่งออกไป!
The 31250 Baud MIDI Hex Stack
เราไม่ส่งข้อความแบบ "เปิดเบสหน่อย" ไปหา Ableton นะ เราต้องยิงข้อมูลดิบที่เป็นอาร์เรย์ของไบต์เลขฐานสิบหก (Hexadecimal) ไปเลย
- MIDI มาตรฐานทำงานที่
Serial.begin(31250);(เป็นอัตราบอดที่แปลกและตายตัวมาตั้งแต่ยุค 80s) - คำสั่งสำหรับการทำงาน: เวลาหมุนปุ่ม Arduino Uno จะส่งข้อมูลออกมา 3 ไบต์พอดี:
0xB0(คำสั่ง Control Change บนช่องที่ 1)0x07(เป้าหมายที่ต้องการควบคุม เช่น ระดับเสียงหลัก)0x40(ค่าที่ต้องการ ตั้งแต่ 0 ถึง 127)
- Arduino Uno ใช้คำสั่ง
Serial.write(byte);ที่เร็วมากๆ ในการส่งอาร์เรย์เลขฐานสิบหกพวกนี้เข้าไปในคอมพิวเตอร์โดยตรง!
การแมปหน้าจอ OLED และการเรียกคืนค่าจาก EEPROM
มีน้องๆ อยากเซฟการตั้งค่าปุ่มหมุนแบบที่ตัวเองชอบไว้ใช่มั้ยล่ะ?
- หน้าจอ I2C SSD1306 OLED จะโชว์เมนูปัจจุบัน เช่น "Rotary 1 = Filter Cutoff."
- ตัว Arduino อาศัยไลบรารี
<EEPROM.h>เยอะมาก เวลาผู้ใช้กำหนดค่า MIDI CC ใหม่ให้กับ Rotary 1, บอร์ด Uno จะเขียนค่า0x07ลงไปในหน่วยความจำแฟลช ROM เลยจ้าEEPROM.write(1, 0x07); - ต่อให้ DJ ดึงปลั๊กบอร์ดออกกลางคอนเสิร์ต พอเสียบกลับมาใหม่ ระบบก็ดึงการแมปสำหรับ Ableton Live กลับมาได้ทันทีจากหน่วยความจำฮาร์ดแวร์ในชิปเลย! ไม่มีหลุด
ชุดอุปกรณ์สำหรับสตูดิโอ
- Arduino Pro Micro หรือ Leonardo (ต้องใช้ชิป ATmega32u4 เท่านั้น ถึงจะทำตัวเป็น Native USB-MIDI Human Interface Device ได้ บอร์ด Uno นั้น Ableton มองไม่เห็นเป็น MIDI Controller ทันทีแบบนี้ไม่ได้นะจ๊ะ!)
- Rotary Encoders (KY-040) พร้อมปุ่มกดแบบ Physical
- จอแสดงผล OLED ขนาด 0.96 นิ้ว แบบ I2C
- โพเทนชิโอมิเตอร์แบบเลื่อน (Slide Faders) 10K สำหรับเลย์เอาต์มิกเซอร์
มีวิดีโอเกี่ยวกับโปรเจกต์นี้ด้วย พี่ทำเสร็จแล้วและกำลังใช้อยู่ที่โรงเรียน พี่จะเพิ่มซับไตเติ้ลให้นะ ระหว่างรอ ลองดูการควบคุมในคลิปนี้ได้เลย
สเปคความคืบหน้า:
- ปุ่มกดสามารถใส่โน๊ตที่แก้ไขได้: เรียบร้อย - ตั้งค่าความไวของ Encoder เรียบร้อย - MIDI Input/Output -เรียบร้อย (ไม่ได้ใช้ opto isolator นะ พี่เสี่ยงเอง) - Bank Select เรียบร้อยสำหรับปุ่มกด - EEPROM สำหรับบันทึกการเปลี่ยนแปลง เรียบร้อย - การเพิ่มโน๊ตโดยการกดปุ่มหลายปุ่มพร้อมกัน (ดูเหมือนจะไม่ค่อยมีประโยชน์) - Mozzi กำลังทำอยู่ (พี่จะไม่ทำกับ Atmega328 นะ) - เลือก Baud Rate จากเมนูเพื่อใช้กับ USB หรือ MIDI เรียบร้อย
- ตอนนี้พี่กำลังพยายามควบคุมสไลด์ 12 แชนเนลด้วยปุ่มกดจริงๆ แค่ 4 ปุ่ม
พี่อยากเพิ่มฟังก์ชันซินธิไซเซอร์ง่ายๆ ลงในโปรเจกต์ พี่ต้องการการสื่อสารแบบอนุกรม 2 ช่อง ช่อง Hardware serial ไปยังพีซีผ่านพอร์ตอนุกรม, ช่อง Software serial ออกไปยัง midi out (เรียบร้อยแล้ว) และช่อง serial input สำหรับการทำงานของ mozzi synth
พี่ลองทำบางอย่างไปแล้ว แต่พี่คิดว่ามันคงทำงานไม่ค่อยดีกับ Arduino Nano หรือ Uno นะ เพราะ Software serial มันเร็วไม่พอที่จะรับโน้ต MIDI จากคีย์บอร์ด MIDI ได้ อีกทั้งพื้นที่โปรแกรม 2 กิโลไบต์และพื้นที่ตัวแปร Global ก็ไม่พอสำหรับไลบรารี MIDI, serial, software serial, gfx, mozzi... ทั้งหมดหรอก
พี่คงต้องจบโปรเจกต์นี้ลงเพราะปัญหาเรื่องหน่วยความจำโปรแกรม พี่อยากทำอะไรที่มากขึ้น เลยเริ่มหันมาทำงานกับบอร์ด STM32, esp32 (มันดีเพราะมี DAC converter) และ Teensy บ้างแล้ว
คอยติดตามนะ พี่จะกลับมา!
หมายเหตุ: พี่ว่า มันอาจจะใช้เวลาสักพักนึงแหละ
โค้ดและการคอนฟิกนี้ผ่านการทดสอบและทำงานได้อย่างถูกต้องแล้ว
อัพเดท: พี่ทำโปรเจกต์นี้เสร็จแล้ว Arduino Nano มันเร็วไม่พอที่จะจัดการกับงานที่ใหญ่ขึ้น พี่อยากจะเพิ่มการควบคุมอีกแต่ดูเหมือนจะไม่คุ้มค่า พี่จะเริ่มโปรเจกต์ใหม่ด้วย Arduino Mega แทน
เพราะพี่ต้องการสไลด์ฟาเดอร์ ปุ่มกด ไฟฟีดแบ็ค และหน้าจอที่ใหญ่ขึ้น ขณะที่เล่นเครื่องดนตรีหรือทำสตรีม ขอบคุณสำหรับความสนใจนะจ๊ะ อย่างที่พี่บอก คอยติดตามต่อไป! สู้งานนะน้อง!
อัพเดทสำคัญจ้า!
Arduino Nano หรือ Uno มันไม่พอจ่ายแล้วว่ะสำหรับงานแบบ Smoothing สัญญาณ Fader, สร้างเสียง หรือขับจอ
ต้องเปลี่ยนไปใช้ชิป STM32 หรือ ESP แทนแล้ว นั่นแปลว่า... ต้องใช้เวลาอีกนิดนึงน้าา
ถ้าน้องๆ อยากลองแกะลองแปะต่อยอดดู ก็มาแชร์ไอเดียกันได้ที่ GitHub นะ