กลับไปหน้ารวมไฟล์
arduino-continuous-midi-controller-keyboard-cc2269.md

ในบทสอนนี้ เราจะมาสร้าง MIDI controller / คีย์บอร์ดแบบ Continuous กัน หลักการง่ายๆ คือใช้ Capacitive sensing ควบคู่กับการสื่อสาร MIDI และซอฟต์แวร์สังเคราะห์เสียง อยากเห็นตัวอย่างเร็วๆ ดูวิดีโอสั้นๆ ด้านล่างได้เลย หรือจะดูวิดีโออธิบายยาวๆ ครึ่งชั่วโมงเพื่อเข้าใจการทำงานแบบละเอียดก็จัดไปวัยรุ่น

Demostration of KeyBoard

วิดีโออธิบายรายละเอียดการทำงาน:

Details on KeyBoard

1: พื้นหลัง

การเล่นโน้ตแบบต่อเนื่อง (Continuous notes) เป็นส่วนสำคัญของดนตรี Hindustani มาก ซึ่งต้องการการแสดงออกหลายแบบ เครื่องดนตรีอย่างไวโอลิน, ซิตาร์, หรือฟลูต สามารถทำได้ ส่วนคีย์บอร์ดทั่วไปเล่นได้แค่โน้ตแบบไม่ต่อเนื่อง (discrete notes) เท่านั้น ในคีย์บอร์ดระดับสูงอาจมีล้อ Pitch bend ที่สามารถดัดเสียงได้ประมาณ 2 semitones ซึ่งก็ไม่ค่อยเป็นธรรมชาติเท่าไหร่ ในตลาดมีคีย์บอร์ดแบบพิเศษอย่าง Haken Continuum Board, ROLI seaboard ที่ทำได้ดีมาก ลองไปหาข้อมูลเพิ่มเติมจากเว็บไซต์ของเครื่องดนตรีเหล่านั้นดูได้

ด้วยแรงบันดาลใจจากเครื่องดนตรีเหล่านั้น พี่เคยลองทำคีย์บอร์ดสัมผัสแบบง่ายๆ ด้วย Arduino มาก่อน โครงการเก่าใช้แผ่นสัมผัสประมาณ 14 แผ่น (ความแม่นยำต่ำ) และสร้างเสียงด้วยไลบรารี Tone ของ Arduino ซึ่งเสียงเป็นแค่คลื่นสี่เหลี่ยม (square wave) ฟังแล้วไม่เพราะเลยน้องเอ๊ย

นี่คือบทเรียนจากโปรเจกต์เก่าที่พี่พยายามปรับปรุงในโปรเจกต์นี้:

  • เสียงจากไลบรารี Tone แย่มาก ดังนั้นในโปรเจกต์นี้พี่ใช้ MIDI messages เพื่อคุณภาพเสียงที่ดีขึ้น
  • ความแม่นยำในการระบุตำแหน่งต่ำ เพราะแผ่นใหญ่และมีจำนวนน้อย ที่นี่พี่เพิ่มจำนวนแผ่นสัมผัสเกือบสามเท่า และลดความกว้างของแผ่นลงครึ่งหนึ่ง
  • โปรเจกต์เก่าไม่ได้ใช้ข้อมูลความกด (pressure) เพราะไลบรารี Tone ควบคุมความดังไม่ได้ การใช้ MIDI เปิดโอกาสให้ทำสิ่งเหล่านี้ได้
  • Capacitive sensing ไม่ใช่วิธีที่เสถียรที่สุด มันอาจถูกกระทบจากระบบกราวด์, ความชื้นที่ไม้ดูดซับ, หรือแม้แต่รองเท้าที่เราใส่ตอนเล่น แต่วิธีอื่นๆ มันซับซ้อนและ/หรือแพงเกินไป ก็ต้องอยู่กับมันไปนะตัวนี้

2: แนวคิด

ขั้นตอนการทำงานโดยรวมเป็นแบบนี้:

Sensing (การตรวจจับ):

พี่เจอสองวิธีที่พอทำได้ วิธีแรกใช้เซ็นเซอร์ Hall effect (แบบที่ Haken Continuum ใช้) ซึ่งแม่นยำมากแต่ค่อนข้างซับซ้อน ต้องมีกลไกที่ละเอียดอ่อน แต่วิธีที่พี่พบว่าสะดวกคือการใช้ Capacitive sensing ถ้าใช้วิธีนี้เราไม่ต้องมีเซ็นเซอร์เป็นชิ้นส่วนเพิ่ม แค่ต่อแผ่นโลหะเข้ากับขา Arduino ขานั้นก็กลายเป็นเซ็นเซอร์วัดความจุไฟฟ้าแล้ว มีไลบรารีสำเร็จรูปให้ใช้ด้วย โดยสรุป วิธีนี้ตรวจสอบเวลาที่แผ่นโลหะใช้ในการชาร์จจาก 0V ถึง 5V ผ่านตัวต้านทาน (Resistor) ค่าเวลานี้แทนค่าความจุไฟฟ้า (capacitance) ข้อดีอีกอย่างคือเราวัดความกด (pressure) ได้จากข้อมูลนี้ ยิ่งกดแรง พื้นที่ผิวสัมผัสของนิ้วกับแผ่นก็ยิ่งมาก ความจุไฟฟ้าก็เพิ่มขึ้น ดังนั้นเราไม่ได้แค่รู้ว่ามีอะไรมาสัมผัส แต่ยังรู้ด้วยว่า "กดแรงแค่ไหน"

Processing the data (ประมวลผลข้อมูล):

Arduino จะอ่านและประมวลผลข้อมูล จากค่าที่ตั้งไว้ มันจะคำนวณตำแหน่งสัมผัสและค่าความกด รวมทั้งปรับค่าให้เรียบ (smoothing) MIDI messages ก็คือข้อมูลแบบอนุกรม (serial) ที่เราต้องเขียนส่งออกไป Arduino จะควบคุมสัญญาณหลักสี่แบบ สองแบบแรกคือการเปิด (Note ON) และปิด (Note OFF) โน้ต อีกสองแบบคือ pitch bend และ pressure value ซึ่งจะถูกคำนวณและส่งออกไปอย่างต่อเนื่องขณะที่โน้ตกำลังเปิดอยู่

Sound Generation (สร้างเสียง):

ข้อมูลจาก Arduino จะถูกส่งไปยัง FL studio เพื่อสร้างเสียง ซึ่งต้องใช้ซอฟต์แวร์หลายตัวมาช่วยเชื่อมต่อสัญญาณ MIDI เข้าไปใน FL studio

3: เตรียมฮาร์ดแวร์

ขั้นตอนการทำสามารถทำตามจากโปรเจกต์เก่าของพี่ได้เลย

Previously made continuous keyboard

แต่มีบางจุดที่ต้องปรับเปลี่ยนเวลาทำ ความกว้างของแผ่นลดลงเหลือ 6mm (จากเดิม 12 mm) เหตุผลคือเมื่อเราสัมผัสพื้นผิวด้วยแรงกดเบาๆ พื้นที่สัมผัสจะอยู่ที่ประมาณ 8-9mm ดังนั้นเวลาสัมผัสคีย์ใดๆ นิ้วจะแตะแผ่นอย่างน้อยสองแผ่นเสมอ

ที่นี่พี่ต้องการครอบคลุม 2 ออคเทฟ และแต่ละคีย์ประกอบด้วยแผ่นอะลูมิเนียมฟอยล์สองแผ่น รวมแล้วต้องการแผ่นทั้งหมด 48 แผ่น ห้ามช็อตนะตัวนี้

Electrical Connection (การต่อวงจร):

จากรูปด้านบน จะเห็นว่าแต่ละแผ่นต่อกับขาร่วม (common pin) ขาที่ 13 และต่อกับขาแต่ละขาผ่านตัวต้านทาน ไม่มีข้อจำกัดว่าจะต้องต่อแผ่นสัมผัสกับขาแบบไหน เพราะทั้งขาแอนะล็อกและดิจิตอลรองรับ capacitive sensing ทั้งคู่ แต่น้องต้องแก้โค้ดให้ตรงกับการต่อสายของน้องเอง

หมายเหตุ:

ตอนตัดแผ่นหรือบัดกรี ต้องมั่นใจว่าแผ่นทุกแผ่นแยกจากกันทางไฟฟ้า ไม่มีใครแตะต้องใคร

4: ซอฟต์แวร์/โค้ด Arduino

  • ประกาศแผ่นทั้งหมดเป็น capacitive sensor และแมปการต่อสายให้ถูกต้องในโค้ด สำหรับพี่ ขา 13 เป็นขาร่วม
CapacitiveSensor   p1 = CapacitiveSensor(13,12); CapacitiveSensor   p2 = CapacitiveSensor(13,11); 
CapacitiveSensor p3 = CapacitiveSensor(13,10);
.
.
.
CapacitiveSensor p48 = CapacitiveSensor(13,9);

2. อ่านค่าความจุไฟฟ้าจากเซ็นเซอร์ทั้งหมดเริ่มต้น ฟังก์ชัน "raw_cap()" จะอ่านค่าและเก็บไว้ในอาร์เรย์ที่ประกาศไว้ระดับ global

void raw_cap(){
raw[1]=p1.capacitiveSensor(resolution);
raw[2]=p2.capacitiveSensor(resolution);
raw[3]=p3.capacitiveSensor(resolution);
.
.
raw[48]=p48.capacitiveSensor(resolution);
}

3. เมื่อได้ข้อมูลครบแล้ว ฟังก์ชัน "data_process()" จะทำงาน ฟังก์ชันนี้ไม่เพียงแต่ประมวลผลข้อมูล แต่ยังส่ง MIDI message ไปยังคอมพิวเตอร์ด้วย ขั้นตอนเป็นดังนี้

  • หาคีย์ที่มีค่าสัญญาณสูงสุด (max amplitude)
  • คำนวณตำแหน่งสัมผัสที่แน่นอนโดยพิจารณาคีย์ก่อนหน้าและคีย์ถัดไปจากค่าสูงสุด (นี่คือเหตุผลที่ต้องให้นิ้วสัมผัสอย่างน้อยสองคีย์ตลอดเวลา)
  • เก็บค่าตำแหน่งคีย์และค่าความกดล่าสุด 30 ค่า
  • ถ้าค่าความกดเกินค่าที่กำหนดไว้ (threshold) Arduino จะส่งข้อมูลเพื่อเปิดโน้ต (Note ON)
  • ขณะที่โน้ตเปิดอยู่ Arduino จะส่งค่าการดัดเสียง (pitch bend) และค่าความกด (pressure) อย่างต่อเนื่อง
  • ถ้าปล่อยคีย์ (Key releases) มันจะส่งสัญญาณเพื่อปิดโน้ต (Note OFF)

โค้ดนี้ยังมีฟีเจอร์ "snap" ตำแหน่งคีย์ด้วย เช่น ถ้าน้องสัมผัสที่ตำแหน่ง 7.25 (ขวาเล็กน้อยของคีย์ 7) มันจะเล่นเฉพาะคีย์ 7 (โน้ตบริสุทธิ์) และระหว่างที่สัมผัสอยู่นั้น ค่านี้จะเป็นค่าฐานสำหรับการสไลด์ ฟีเจอร์นี้ทำให้การเล่นโน้ตบริสุทธิ์ทำได้ง่าย ถ้าไม่มีฟีเจอร์นี้ การเล่นโน้ตบริสุทธิ์จะยากมากๆ

โค้ดเต็มสามารถดาวน์โหลดได้ ถ้าน้องวางแผนจะทำของคล้ายๆ กัน น้องอาจต้องใช้เวลาปรับแต่งโค้ดและค่าต่างๆ (เช่น resolution และ touch threshold) ไม่น้อยเลย สู้งานนะน้อง

สำหรับความเข้าใจเกี่ยวกับ MIDI message น้องสามารถหาข้อมูลเพิ่มเติมได้จากแหล่งข้อมูลทั่วไป

Musical Instrument Digital Interface (MIDI)

โปรเจคนี้จะเปลี่ยนฮาร์ดแวร์อินพุตพื้นฐาน ให้กลายเป็นเครื่องดนตรีระดับโปรหรือคอนโทรลเลอร์ในสตูดิโอเลยทีเดียว

  • Continuous Control (CC): เฟิร์มแวร์จะแปลงค่าจากเซนเซอร์แบบ capacitive ให้อยู่ในช่วงมาตรฐาน MIDI 7-bit (0-127) เพื่อส่งเป็นข้อความ pitch bend และ pressure (aftertouch)
  • USB-MIDI Class Compliance: ด้วยการใช้บอร์ดอย่าง Arduino Pro Micro หรือ Leonardo (ATmega32U4) อุปกรณ์ของเราจะปรากฏเป็น MIDI keyboard แบบ "Plug-and-Play" ให้กับคอม Windows, Mac, หรือ Linux ทุกเครื่องเลย ไม่ต้องพึ่ง serial-to-MIDI bridge ให้วุ่นวายในบางการตั้งค่า

5: การสร้างเสียง (Sound Generation)

ต้องมีซอฟต์แวร์ 3 ตัวนี้ถึงจะได้ยินเสียงออกมานะน้อง:

1. Hairless MIDI: ตัวนี้คือสะพานเชื่อม serial ไปหา MIDI ข้อมูลอะไรที่อาร์ดุยโน่ส่งออกมาก็จะถูกจับไว้โดยซอฟต์แวร์นี้

2. LoopMIDI: ซอฟต์แวร์ตัวนี้จะมาจับข้อมูลจาก HairlessMIDI อีกที แล้วทำตัวเป็นอุปกรณ์ MIDI ให้กับ FL studio (หรือ DAW ตัวอื่นที่น้องใช้)

3. FL studio: ในตั้งค่าของ FL studio น้องอาจต้องเลือก LoopMIDI เป็นอุปกรณ์นะ โค้ดนี้โดยดีฟอลต์จะให้ค่า pitch bend อยู่ในช่วง +8 ถึง -8 semitones (ค่าเริ่มต้นในซอฟต์แวร์มักเป็น +2 ถึง -2) ตรงนี้ต้องไปตั้งค่าเองในเครื่องดนตรี (instrument) ที่เลือกด้วย นอกจากนั้นก็ต้องไป map ค่า pressure ให้ควบคุมความดัง (volume) อีกที ตั้งค่าให้ดีนะจะได้ไม่เพี้ยน

การใช้งานในสตูดิโอ (Studio Integration)

  • DAW Compatibility: ใช้งานร่วมกับ DAW ตัวดังอย่าง Ableton Live, FL Studio, หรือ Logic Pro ได้ลื่นไหลมาก
  • Latency Optimization: โค้ดถูกออกแบบมาให้โพลข้อมูลแบบ serial ด้วยความเร็วสูง เพื่อลด latency ให้ต่ำสุด เวลาแสดงสดจะได้ไม่กระตุก ต้องลื่นปรื๊ดๆ

6: ปัญหาที่พบบ่อย (Common Issues)

นี่คือลิสต์ปัญหาที่พี่เจอตอนทำโปรเจค รับรองว่ามีประโยชน์แน่นอน

  • ปัญหาคลาสสิคของ capacitive sensing ก็คือเรื่องการกราวด์นั่นแหละ ความไวจะเพิ่มขึ้นถ้าผู้ใช้สัมผัสกราวด์ด้วยเท้าเปล่า (จัดไปวัยรุ่น) หรือถ้าเสียบแล็ปท็อปเข้ากับปลั๊กไฟ แต่ว่าการเปิดชาร์จเจอร์อาจเพิ่มสัญญาณรบกวน (noise) เข้ามาได้ ดังนั้น ถ้าน้องตั้งค่า threshold ไว้สำหรับสภาวะหนึ่ง มันอาจจะใช้ไม่ได้กับอีกสภาวะก็ได้ ต้องทดลองเยอะๆ
  • การเชื่อมต่อระหว่างแผ่นอลูมิเนียมฟอยล์เป็นจุดอ่อนและหลุดง่ายมาก บางทีอุปกรณ์ทำงานแปลกๆ ก็เพราะจุดต่อนี้หลุดนี่แหละ ตรวจสอบให้ดี
  • การสัมผัสโดนแผ่นโลหะ, สายไฟ หรือขา PIN โดยตรงอาจให้ข้อมูลที่ผิดเพี้ยนไปเลย และยังทำให้อัตราการสุ่มตัวอย่าง (sampling rate) ตกอีก เวลาเล่น ควรสัมผัสเฉพาะส่วนที่หุ้มด้วยพลาสติกเท่านั้น โลหะทุกจุดที่โผล่ออกมาต้องหุ้มฉนวนให้มิดชิด ป้องกันการสัมผัสโดยไม่ได้ตั้งใจ ห้ามช็อตนะตัวนี้!
  • ถ้าน้องติดอลูมิเนียมฟอยล์ลงบนบล็อกไม้ด้วยกาวน้ำ (water-based adhesive) มันอาจใช้เวลาหลายชั่วโมงหรือเป็นวันถึงจะแห้งสนิท ถ้ายังเปียกชื้นอยู่ มันจะให้ผลลัพธ์ผิดเพี้ยน เพราะแผ่นฟอยล์จะเชื่อมต่อกันผ่านทางช่องน้ำนั่นเอง สู้งานนะน้อง

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

apps:
  - "1x FL studio"
  - "1x LoopMIDI"
  - "1x Arduino IDE"
  - "1x HairlessMIDI"
author: "abhilashpatel121"
category: "Audio & Sound"
components:
  - "1x Aluminium Foil"
  - "50x Through Hole Resistor, 500 kohm"
  - "1x Balsa wood Block"
  - "1x Arduino Mega 2560"
description: "คีย์บอร์ด Expression ตัวนี้จะพาน้องๆ ไปเปิดโลกใหม่ของการเล่นโน้ตแบบต่อเนื่องราบรื่น ไม่มีสะดุด งานง่ายแต่หล่อ มาลองจัดไปกันเลยวัยรุ่น!"
difficulty: "Intermediate"
documentationLinks: []
downloadableFiles:
  - "https://projects.arduinocontent.cc/bb68e117-c30d-45db-91fb-91f5c0ae40f3.ino"
encryptedPayload: "U2FsdGVkX18qc0a649ERNIYiq1/04sV9yTh3Otg2oxDOeZY5RQy5+qgOa0AkgnLQP03In0KtlfPxqoEf/3rkWqi8ywG9m7kWFySZcepbpFlqChNQ+jL4S0uPQwQB4hXMEelV5sf40gsKAVCoF4oz+0z1hCUhEYbixGhdssnrdOg="
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/arduino-continuous-midi-controller-keyboard-cc2269_cover.jpg"
lang: "en"
likes: 13
passwordHash: "871d514a134b3a2f108c3c19683b2cf969d6d9bc4cc1a5756b41bf8253107abe"
price: 200
seoDescription: "Arduino Continuous MIDI Controller / Keyboard project. Use this expression keyboard to play continuous notes for expressive music performance."
tags:
  - "midi"
  - "music"
  - "continuum"
title: "Arduino MIDI Keyboard สุดตึง! เล่นได้แบบ Continuous ราบรื่นเวอร์"
tools: []
videoLinks:
  - "https://www.youtube.com/embed/7dZatrW8Ex8"
  - "https://www.youtube.com/embed/rCsI5uUBG3o"
  - "https://www.youtube.com/embed/vX1ChDaV6Uc"
views: 14373