วันอังคารที่ 14 ธันวาคม พ.ศ. 2553

การใช้งาน USB Joystick ด้วย C#

การใช้งาน USB Joystick ด้วย C#

สวัสดีครับ :D ในที่สุดก็ได้เริ่มงานเขียนกันสักทีหลังจากติดภารกิจมานาน สำหรับบทความนี้จะพาผู้อ่านไปใช้ USB Joystick โดยใช้ภาษา C# ร่วมกับ DirectX นะครับ จะเป็นตัวอย่างที่ง่ายมากครับ แล้วก็พื้นฐานที่สุดเพื่อให้โปรแกรมเบาและสามารถนำไปประยุกต์ใช้อย่างหลากหลายนะครับ เรามาเริ่มกันเลยครับ

System Requirement

  1. Windows7 อาจใช้ OS อื่นได้นะครับ แต่ตอนเขียนผมใช้ Windows7 ไม่รู้ว่า Version อื่นจะมีปัญหาอะไรรึเปล่าน่ะครับ
  2. Microsoft Visual C# 2010 Express โหลดฟรีสำหรับนักพัฒนาได้ที่นี่เลยครับ http://www.microsoft.com/express/Downloads/
  3. DirectX SDK โหลดได้ที่นี่เลยครับ http://www.microsoft.com/express/Downloads/ ในที่นี้ผมใช้ เวอร์ชั่น June 2010 DirectX SDK ซึ่งเวอร์ชั่นอื่นก็น่าจะได้เหมือนกันครับ

เริ่มต้นเขียน

1. สร้าง Project แบบ Window Application Form ขึ้นมาใหม่ ตั้งชื่อตามใจชอบ

2. เพิ่ม DirectX เข้าโปรเจ็ค โดยการ คลิกขวาที่ References -> Add Reference

3. เลือก Browse แล้วหาๆฟล์ Microsoft.DirectX.DirectInput โดยปกติจะอยู่ที่ C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0

4. คลิกขวาที่ From1.Designer.cs -> View Code เพื่อแทรก Code

5. ทำการเพิ่ม Code ตามรูป this.Load+=newSystem.EventHandler(this.iJoy_Load);



โดยที่ iJoy_Load เป็นชื่อของ metod



6. ใน Form1 เพิ่ม Code 2 ส่วน ได้แก่ เรียกใช้ namespace DirectX และ code เรียกใช้งาน USB Joystick โดยสามารถ Copy Code จากด้านล่างของบทความนี้

7. เพิ่ม Label แล้วเปลี่ยนชื่อเป็น lbJoystick เพื่อเตรียมตัวใช้แสดงผลการทำงาน


8. เพิ่ม Timer แล้วตั้งค่า Enabled จาก False เป็น True


9. ทำการเพิ่มโค้ดเรียกใช้เมดทอด UpdateJoystick ดังรูป โดยทำการ Double-Click ที่



10. จากนั้นทำการ Save ให้เรียบร้อย จากนั้น สั่ง Complied และ run จะได้โปรอกรมแสดงการทำงานของ USB Joystick

สำหรับการนำไปประยุกต์ก็ไล่โค้ดเอานะครับ เป็น C# ธรรมดาครับ หากมีอะไรสงสัยให้เมล์มาถามได้นะครับที่ ks_bomb@hotmail.com หวังว่าคงมีประโยชน์ต่อผู้อ่านนะครับ แล้วเจอกันใหม่บทความหน้านะครับ บ๊าย บาย …….. :D

+++++++++++++++++++++++++++++++++++++++

ในกรณีเกิด Error

ซึ่งอาจจะเกิดจากหลายสาเหตซึ่งมีวิธีแก้ที่ต่างกันดังนี้

Ø กรณียังไม่มี Application Configuration File สำหรับการใช้งาน CRT 4.0

วิธีแก้

1. เพิ่ม Application Configuration File โดย
คลิกขวาที่โปรเจ็ค
-> Add -> New Item…

2. เลือก Application Configuration File แล้วกด Add

3. ทำการเพิ่ม Code ต่อไปนี้ระหว่าง <configuration>..configuration> ได้แก่

<startup useLegacyV2RuntimeActivationPolicy="true">

<supportedRuntime version="v4.0"/>

</startup>


4. ทำการ Save แล้วลอง Run ใหม่

+++++++++++++++++++++++++++++++++++

Ø กรณีเกิดปัญหา LoaderLock หากมีปัญหาคล้ายดังรูป ให้แก้ดังนี้

วิธีแก้

1. ที่เมนู Debug เลือก Exception… จะมีหน้าต่างดังนี้ pop up ขึ้นมา

2. ทำการขายส่วน (กดเครื่องหมาย +) หน้า Managed Debugging Assistants


3. หาคำว่า แล้ว เอาเครื่องหมายถูก ใน Colum Thrown ออก

4. ทำการ Save แล้วลอง Run ใหม่

+___________________________+


Code ที่ต้องเพิ่มเติม

//iAdd Code for init Joystick
private Device joystick;
private void iJoy_Load(object sender, EventArgs e) //iAdd
{
this.InitDevices();
}
private void InitDevices()
{

//create joystick device.
foreach (
DeviceInstance di in
Manager.GetDevices(
DeviceClass.GameControl,
EnumDevicesFlags.AttachedOnly))
{
joystick = new Device(di.InstanceGuid);
break;
}

if (joystick == null)
{
//Throw exception if joystick not found.
throw new Exception("No joystick found.");
}

//Set joystick axis ranges.
foreach (DeviceObjectInstance doi in joystick.Objects)
{
if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)
{
joystick.Properties.SetRange(
ParameterHow.ById,
doi.ObjectId,
new InputRange(-5000, 5000));
}
}

//Set joystick axis mode absolute.
joystick.Properties.AxisModeAbsolute = true;

//set cooperative level.
joystick.SetCooperativeLevel(
this,
CooperativeLevelFlags.NonExclusive |
CooperativeLevelFlags.Background);
//Acquire devices for capturing.
joystick.Acquire();

}

private void UpdateJoystick()
{
string info = "Joystick: ";

//Get Mouse State.
JoystickState state = joystick.CurrentJoystickState;

//Capture Position.
info += "X:" + state.X + " ";
info += "Y:" + state.Y + " ";
info += "Z:" + state.Z + " ";

//Capture Buttons.
byte[] buttons = state.GetButtons();
for (int i = 0; i < buttons.Length; i++) { if (buttons[i] != 0) { info += "Button:" + i + " "; } } lbJoystick.Text = info; } private void timer1_Tick(object sender, EventArgs e) { UpdateJoystick(); }

+++++++++++++++++++++++++++++++++

เอกสารอ้างอิง

· ตัวอย่าง Code ทีนำมาใช้ http://msdn.microsoft.com/en-us/library/bb153252%28VS.85%29.aspx#dx_DirectInput_creating_device_objects

· แก้ปัญหา CLR http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/5d1186ec-ad55-4929-b1e4-8806cdc758af

· การเพิ่มไฟล์ Config file http://www.devasp.net/net/articles/display/679.html

· แก้ปัญหา LoaderLock http://www.pcreview.co.uk/forums/thread-3741011.php

6 ความคิดเห็น:

  1. ทำการแก้ Code ในส่วนที่ต้องเพิ่มเติมเรียบร้อยแล้วนะครับ
    เนื่องจากมี code หายไปบางส่วนนะครับ
    ยังไงลองทำกันใหม่นะครับ
    สงสัยตรงไหน ก็ถามไว้นะครับ

    บ๊าย บาย

    ตอบลบ
  2. หึหึหึ วันนี้ได้เอาบทความตัวเองมาทำโปรเจ็คส่วนหนึ่งค้นพบว่า ยังคงใช้งานได้ดีอยู่ 555++ ใครมีอะไรสงสัยถามได้นะครับ

    ตอบลบ
  3. ขอบคุณครับ มีประโยชน์มาก ผมเอามาใช้ทำโปรเจคจบเลยครับ

    ผมมีปัญหาอยู่อย่างเดียว คือใช้ code นี้กับ mdi แล้วมันเกิดปัญหา error application อ่ะครับ เช่นพอเรียกฟอร์มลูก(ฟอร์มที่ใช้จอย) ขึ้นมาใช้ก็จะเกิดปัญหาทันทีครับ

    ตอบลบ
  4. ไม่ทราบว่าแก้ไขได้แล้วหรือยังครับ

    ตอบลบ
  5. ขอบคุณครับใช้ได้ดีเลยครับ

    ตอบลบ
  6. ขอบคุณมากครับ ใช้งานได้ดีครับ แต่ของผมเวลาใช้ตรงที่เป็น analog เวลาดึงลงมาแบบเฉียงๆ ค่า x และ y จะมาที่ละค่าครับ

    ตอบลบ