ผลต่างระหว่างรุ่นของ "การติดต่อกับบอร์ด MCU ผ่าน USB ด้วย Arduino"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
 
(ไม่แสดง 32 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
แถว 1: แถว 1:
: ''วิกินี้เป็นส่วนหนึ่งของรายวิชา [[01204223]]''
+
#REDIRECT [[การติดต่อกับบอร์ดไมโครคอนโทรลเลอร์ผ่านพอร์ท USB ด้วย Arduino]]
 
 
ที่ผ่านมานั้นเราใช้พอร์ท USB เป็นเพียงแหล่งจ่ายพลังงานและโปรแกรมเฟิร์มแวร์เท่านั้น วิกินี้อธิบายถึงขั้นตอนและตัวอย่างการพัฒนาเฟิร์มแวร์ภายใต้สภาพแวดล้อมของ Arduino เพื่อให้บอร์ดไมโครคอนโทรลเลอร์จำลองตัวเองเป็นอุปกรณ์ USB ความเร็วต่ำ สำหรับสื่อสารกับแอพลิเคชันที่ทำงานบนเครื่องคอมพิวเตอร์ได้
 
 
 
==ไลบรารีและเครื่องมือที่จำเป็น==
 
ให้แน่ใจว่าได้ติดตั้งไลบรารีและเครื่องมือที่จำเป็นตามที่ได้อธิบายไว้ในวิกิด้านล่าง ก่อนเริ่มทำตามขั้นตอนในวิกินี้
 
* [[การใช้ Arduino Makefile]]
 
* [[การติดตั้งไลบรารี V-USB สำหรับ Arduino]]
 
* [[การติดตั้งไลบรารี PyUSB]]
 
 
 
==การใช้งานไลบรารี V-USB==
 
การเขียนโค้ดเพื่อเรียกใช้งานไลบรารี V-USB ภายใต้สภาพแวดล้อมของ Arduino มีขั้นตอนหลัก ๆ ดังนี้
 
* สร้างไฟล์ <tt>usbconfig.h</tt> เพื่อบอกไลบรารี V-USB ถึงคุณลักษณะของอุปกรณ์ USB ที่เราต้องการให้บอร์ด MCU จำลองตัวเองขึ้นมา เนื่องจากการตั้งค่าต่าง ๆ ถูกระบุไว้ในรูปมาโครเป็นจำนวนมาก วิธีที่สะดวกและเสี่ยงต่อความผิดพลาดน้อยที่สุดคือคัดลอกเนื้อหามาจากไฟล์ <tt>usbconfig-prototype.h</tt> ที่อยู่ในไดเรคตอรี <tt>usbdrv</tt> ที่ได้จากการติดตั้ง V-USB ตามขั้นตอนก่อนหน้านี้ การตั้งค่าหลัก ๆ ที่สำคัญได้แก่
 
** <code>USB_CFG_VENDOR_ID</code> และ <code>USB_CFG_DEVICE_ID</code> ใช้กำหนดค่า Vendor ID (VID) และ Product ID (PID) ให้กับอุปกรณ์ USB ตัวเลขคู่นี้จะถูกตีความโดยระบบปฏิบัติการว่าเป็นอุปกรณ์ USB ประเภทใด เช่นเครื่องพิมพ์ เมาส์ คียบอร์ด ฯลฯ เพื่อที่ตัวระบบปฏิบัติการจะได้จัดหาตัวขับเคลื่อนอุปกรณ์ (device driver) มาใช้งานได้อย่างเหมาะสม ในตัวอย่างนี้มีการกำหนดค่า VID และ PID ให้เป็น 0x16c0 และ 0x05dc ตามลำดับ ซึ่งเป็นการไม่ระบุประเภทอุปกรณ์ ดูข้อมูลเพิ่มเติมจากหัวข้อ [[#เกี่ยวกับหมายเลข VID/PID]]
 
** <code>USB_CFG_VENDOR_NAME</code> ใช้กำหนดชื่อผู้ผลิตอุปกรณ์ที่จะปรากฏให้เห็นผ่านระบบปฏิบัติการ ระบุในรูปรายการอักขระคั่นด้วยคอมม่า พร้อมทั้งระบุความยาวชื่อให้กับมาโคร <code>USB_CFG_VENDOR_NAME_LEN</code> ในที่นี้เราจะกำหนดชื่อผู้ผลิตเป็น <tt>cpe.ku.ac.th</tt> เพื่อให้สอดคล้องกับแนวปฏิบัติของไลบรารี V-USB
 
** <code>USB_CFG_DEVICE_NAME</code> ใช้กำหนดชื่อของอุปกรณ์ที่จะปรากฏให้เห็นผ่านระบบปฏิบัติการ ระบุในรูปรายการอักขระคั่นด้วยคอมม่า พร้อมทั้งระบุความยาวชื่อให้กับมาโคร <code>USB_CFG_DEVICE_NAME_LEN</code> ในที่นี้ให้กำหนดชื่อในรูป <tt>ID xxxxxxxxxx</tt> โดยที่ <tt>xxxxxxxxxx</tt> แทนรหัสนิสิตของตน
 
* สร้าง Arduino Sketch ขึ้นมาใหม่ แล้วพิมพ์คำสั่งต่อไปนี้ที่ส่วนหัวของไฟล์
 
<syntaxhighlight lang="C">
 
extern "C" {
 
#include "usbdrv.h"
 
}
 
</syntaxhighlight>
 
:คำสั่งข้างต้นเป็นการเรียกไลบรารี V-USB มาใช้งาน แต่เนื่องจากไลบรารี V-USB ออกแบบไว้ใช้กับภาษา C ในขณะที่โค้ด Arduino เป็นภาษา C++ จึงต้องครอบไว้ด้วยคำสั่ง <tt>extern</tt> ดังที่เห็น
 
* นิยามฟังก์ชัน <tt>setup()</tt> เพื่อกำหนดหน้าที่ของขาอินพุทเอาท์พุทตามปกติ และเพิ่มโค้ดสำหรับสั่งไลบรารี V-USB ให้เตรียมการเบื้องต้นลงไปด้วยดังนี้
 
<syntaxhighlight lang="C">
 
void setup()
 
{
 
  // ตั้งค่าอินพุท/เอาท์พุทตามปกติ
 
  // :
 
 
 
  // สั่งให้ V-USB เตรียมตัวขั้นต้น
 
  usbInit();
 
  usbDeviceDisconnect();
 
  delay(300);
 
  usbDeviceConnect();
 
}
 
</syntaxhighlight>
 
* นิยามฟังก์ชัน <tt>loop()</tt> ให้มีการเรียกใช้ฟังก์ชัน <tt>usbPoll()</tt> ของไลบรารี V-USB โดยให้แน่ใจว่าฟังก์ชันนี้ต้องถูกเรียกซ้ำ ๆ ภายในระยะเวลาไม่เกิน 50 มิลลิวินาทีอย่างต่อเนื่อง ไม่เช่นนั้นอุปกรณ์จะตอบสนองต่อคำร้องขอจากโฮสท์ไม่ทันและมีผลทำให้โฮสท์ตัดการเชื่อมต่อในที่สุด
 
<syntaxhighlight lang="C">
 
void loop()
 
{
 
  // ประมวลผลตามต้องการ แต่ต้องให้แล้วเสร็จภายใน 50 มิลลิวินาที
 
  // :
 
 
 
  // สั่ง V-USB ให้เฝ้าดูสัญญาณการร้องขอจากโฮสท์
 
  usbPoll();
 
}
 
</syntaxhighlight>
 
* เมื่อพบว่ามีคำร้องขอจากโฮสท์ ไลบรารี V-USB จะเรียกหาฟังก์ชัน <tt>usbFunctionSetup()</tt> เพื่อประมวลผลคำร้องขอนั้น เป็นหน้าที่ของเราที่ต้องสร้างฟังก์ชันนี้ขึ้นมา
 
<syntaxhighlight lang="C">
 
usbMsgLen_t usbFunctionSetup(uint8_t data[8])
 
{
 
  usbRequest_t *rq = (usbRequest_t*)data;
 
 
 
  // ประมวลผลข้อมูลภายในคำร้องขอผ่านทางตัวแปร rq
 
  // :
 
}
 
</syntaxhighlight>
 
* เนื่องจาก Arduino IDE ยังไม่สามารถคอมไพล์โค้ดที่เรียกใช้งานไลบรารี V-USB โดยตรงได้ ให้คอมไพล์เฟิร์มแวร์ด้วย Arduino-Makefile โดยการสร้างไฟล์ <tt>Makefile</tt> ไว้ในที่เดียวกันกับที่เก็บ Arduino Sketch แล้วเรียกใช้คำสั่ง <tt>make</tt> หรือ <tt>make ispload</tt> จากเทอร์มินัล
 
 
 
==ตัวอย่างโปรแกรม==
 
ดาวน์โหลดตัวอย่างโปรแกรม [http://www.cpe.ku.ac.th/~cpj/223 usb_generic.tgz] แล้วแตกเอาไว้ในไดเรคตอรีที่เก็บ sketch ของ Arduino
 
 
 
===เฟิร์มแวร์สำหรับฝั่งดีไวซ์===
 
ซอร์สโค้ดหลัก
 
 
 
===แอพลิเคชันฝั่งโฮสท์===
 
 
 
 
 
== เกี่ยวกับหมายเลข VID/PID ==
 
ชุดตัวเลข VID/PID ที่กำหนดให้กับอุปกรณ์ USB ไม่ควรตั้งเอาเองตามใจชอบเนื่องจากระบบปฏิบัติการจะอาศัยตัวเลขคู่นี้ในการเลือกซอฟต์แวร์ไดรเวอร์ที่จะมาควบคุมอุปกรณ์ โดยทั่วไปการจะได้มาซึ่งเลข VID/PID เพื่อใช้กับอุปกรณ์ที่เราสร้างขึ้นจำเป็นต้องสมัครเป็นสมาชิกของ [http://www.usb.org USB Implementers Forum] (ค่าสมาชิกปีละ 4,000 เหรียญสหรัฐ) หรือซื้อตัวเลข VID มาจากผู้ที่เป็นสมาชิกอีกทีหนึ่ง
 
 
 
อย่างไรก็ตาม Object Development ผู้พัฒนาไลบรารี V-USB ได้เตรียมชุดตัวเลข VID/PID ไว้ให้เราใช้งานโดยไม่เสียค่าใช้จ่าย ค่า <tt>16C0:xxxx</tt> ที่เราเลือกนำมาใช้งานก็ได้มาจากตัวเลขในชุดดังกล่าว รายละเอียดเพิ่มเติมเกี่ยวกับการกำหนดค่า VID และ PID ให้กับอุปกรณ์ USB รวมถึงหลักเกณฑ์การปฏิบัติในการผลิตอุปกรณ์ USB สู่สาธารณะ สามารถศึกษาเพิ่มเติมได้จากเนื้อหาในไฟล์ <tt>USB-ID-FAQ.txt</tt> และไฟล์ <tt>USB-IDs-for-free.txt</tt> ในไดเรคตอรี <tt>usbdrv</tt> ที่ได้จากการติดตั้งไลบรารี V-USB รวมถึงเอกสาร [http://www.voti.nl/docs/usb-pid.html How to obtain an USB VID/PID for your project]
 

รุ่นแก้ไขปัจจุบันเมื่อ 11:17, 10 ตุลาคม 2558