Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Managed Library for Nintendo's Wiimote

  In this article, Brian Peek demonstrates how to connect to and use the Nintendo Wiimote from C# and VB.NET. The final output is an easy-to-use managed API for the Wiimote that can be used in any managed application.
ASPSOFT, Inc.

Difficulty: Intermediate
Time Required: 1-3 hours
Cost: Less Than $50 (Free if you already own a Wiimote)
Software: Visual C# or Visual Basic 2008 Express Editions
Hardware: Nintendo Wii Remote (Wiimote), a compatible PC Bluetooth adapter and stack
Download: CodePlex
 

Updates

1/19/09 - Version 1.7 now up at CodePlex.

6/15/08 – Version 1.5.2 is now up at CodePlex.  The Balance Board should really work this time….

6/12/08 - Version 1.5.1 has been removed from CodePlex...it has proven to be too buggy for most users (though it continues to work just fine for me).  Look for version 1.5.2 soon...

6/11/08 – Version 1.5.1 posted at CodePlex.  Fixed a bug with the Balance Board…  UPDATE:  It appears some people are still having issues with this build as well due to some Balance Boards being a bit finicky in their response times.  Stay tuned for build 1.5.2 soon…

6/9/08 – Version 1.5 posted at CodePlex.  The Wii Fit Balance Board is now supported.

6/3/08 – New version 1.4 posted at the download link above.  The big change is multiple Wiimotes are now finally supported.

5/27/08 - New version 1.3 posted at the download link above.  Lots of changes, so be sure to read the included docs!

1/29/08 - New version 1.2.1.0 posted at the download link above.  The only change for this release is adding support for IR3 and IR4 since I've gotten so many questions about it.

10/22/07 - New version 1.2.0.0 posted at the download link above.  There are a variety of fixes and new features added.  The source code and binary releases are now hosted at CodePlex.  A .chm help file is also included documenting the API itself.  Please note that a license is now included with the library which explicitly defines how the library can be used.  For 99% of you, this won't change anything, but I've received tons of emails asking about restrictions, so now there's something official attached.  Check out the readme.txt and license.txt in the docs directory included with the official distribution for more information.

6/12/07 - New version 1.1.0.0 posted at the download link above.  This fixes several issues, adds an alternate writing method which may help those with troubled bluetooth stacks/adapters, adds Vista/XP x64 support, and a Microsoft Robotics Studio service version of the library.  See the included readme.txt for more information.  Additionally, see my new article on using the new MSRS service to create a Wiimote-controlled car!

3/17/07 - New version 1.0.1.0 posted at the download link above.  This fixes a bug with the calibration data being stored by the API.  Thanks to James Darpinian for the catch!

Introduction

Nintendo's Wii Remote (forever known as the Wiimote) is a fantastic little controller for the Nintendo Wii system.  Because it uses Bluetooth to communicate with the Wii, it can be connected to and used by practically any Bluetooth capable device.

If you care to just use the library and are not concerned with the implementation details, skip down to the usage section.

Before we get started, there are two websites that one should peruse before reading the code contained here.  These two sites have done 99% of the work of figuring out the data that is sent and received with the Wiimote.  I am not going to repeat most of this information here since both of the these sites explain the protocol so thoroughly.  Without the work of the people posting to these sites, none of this would have been possible.

Getting Connected

This will likely be the biggest sticking point.  The Wiimote will not pair and communicate successfully with every Bluetooth device and stack on the planet.   There's little I can do to help get you connected if the following steps do not work.  Either it's going to work, or it isn't.  Cross your fingers...

  1. Start up your Bluetooth software and have it search for a device.
  2. Hold down the 1 and 2 buttons on the Wiimote.  You should see the LEDs at the bottom start flashing.  Do not let go of these buttons until this procedure is complete.  If pairing the Wii Fit Balance Board, open the battery cover on the underside of the balance board and hold the little red sync button.
  3. Wiimotes should show up in the list of devices found as Nintendo RVL-CNT-01.  Balance Boards will show up as Nintendo RVL-WBC-01.  If it's not there, start over and try again.
  4. Click Next to move your way through the wizard.  If at any point you are asked to enter a security code or PIN, leave the number blank or click Skip.  Do not enter a number.
  5. You may be asked which service to use from the Wiimote.  Select the keyboard/mouse/HID service if prompted (you should only see one service available).
  6. Finish the wizard.

That's it.  The LEDs at the bottom should continue to flash and you should see the device listed in your list of connected Bluetooth devices.  If you run the test application included with the source code and you see the numbers change, you are all set.  If you don't see them change or you get an error, try the above again.  If it continues to not function, you are likely stuck with an incompatible device or stack.

The Exciting World of HID and P/Invoke

When the Wiimote is paired with your PC, it will be identified as a HID-compliant device.  Therefore, to connect to the device, we must use the HID and Device Management Win32 APIs.  Unfortunately there is no built-in support for these APIs in the current .NET runtime, so we must enter the realm of P/Invoke.  These APIs are defined in the Windows Driver Kit (WDK) so if you wish to see the original C header files or read the API documentation, you will need to download and install the latest WDK.

P/Invoke, as you probably know, allows one to directly call methods of the Win32 API from .NET.  The difficulty of this is finding the right method signatures and structure definitions which will properly marshal the data through to Win32.  A great resource for these signatures is the P/Invoke wiki.  Almost all of the methods used in this project were defined by this resource.  For this project, all P/Invoke'd methods live in the HIDImports class.

The process to begin communication with the Wiimote is as follows:

  1. Get the GUID of the HID class defined by Windows
  2. Get a handle to the list of all devices which are part of the HID class
  3. Enumerate through those devices and get detailed information about each
  4. Compare the Vendor ID and Product ID of each device to the known Wiimote's VID and PID
  5. When found, create a FileStream to read/write to the device
  6. Clean up the device list

 

In code, the process is as follows (shortened from the original code for space):

VB

' read/write handle to the device
Private mHandle As SafeFileHandle

' a pretty .NET stream to read/write from/to
Private mStream As FileStream
Private found As Boolean = False
Private guid As Guid
Private index As UInteger = 0

' 1. get the GUID of the HID class
HIDImports.HidD_GetHidGuid(guid)

' 2. get a handle to all devices that are part of the HID class
Dim hDevInfo As IntPtr = HIDImports.SetupDiGetClassDevs(guid, Nothing, IntPtr.Zero, HIDImports.DIGCF_DEVICEINTERFACE) ' | HIDImports.DIGCF_PRESENT);

' create a new interface data struct and initialize its size
Dim diData As HIDImports.SP_DEVICE_INTERFACE_DATA = New HIDImports.SP_DEVICE_INTERFACE_DATA()
diData.cbSize = Marshal.SizeOf(diData)

' 3. get a device interface to a single device (enumerate all devices)
Do While HIDImports.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, guid, index, diData)
' create a detail struct and set its size
Dim diDetail As HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA = New HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA()
diDetail.cbSize = 5 'should be: (uint)Marshal.SizeOf(diDetail);, but that's the wrong size

Dim size As UInt32 = 0

' get the buffer size for this device detail instance (returned in the size parameter)
HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, diData, IntPtr.Zero, 0, size, IntPtr.Zero)

' actually get the detail struct
If HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, diData, diDetail, size, size, IntPtr.Zero) Then
' open a read/write handle to our device using the DevicePath returned
mHandle = HIDImports.CreateFile(diDetail.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, HIDImports.EFileAttributes.Overlapped, IntPtr.Zero)

' 4. create an attributes struct and initialize the size
Dim attrib As HIDImports.HIDD_ATTRIBUTES = New HIDImports.HIDD_ATTRIBUTES()
attrib.Size = Marshal.SizeOf(attrib)

' get the attributes of the current device
If HIDImports.HidD_GetAttributes(mHandle.DangerousGetHandle(), attrib) Then
' if the vendor and product IDs match up
If attrib.VendorID = VID AndAlso attrib.ProductID = PID Then
' 5. create a nice .NET FileStream wrapping the handle above
mStream = New FileStream(mHandle, FileAccess.ReadWrite, REPORT_LENGTH, True)
Else
mHandle.Close()
End If
End If
End If

' move to the next device
index += 1
Loop

' 6. clean up our list
HIDImports.SetupDiDestroyDeviceInfoList(hDevInfo)

C#

// read/write handle to the device
private SafeFileHandle mHandle;

// a pretty .NET stream to read/write from/to
private FileStream mStream;
bool found = false;
Guid guid;
uint index = 0;

// 1. get the GUID of the HID class
HIDImports.HidD_GetHidGuid(out guid);

// 2. get a handle to all devices that are part of the HID class
IntPtr hDevInfo = HIDImports.SetupDiGetClassDevs(ref guid, null, IntPtr.Zero, HIDImports.DIGCF_DEVICEINTERFACE);// | HIDImports.DIGCF_PRESENT);

// create a new interface data struct and initialize its size
HIDImports.SP_DEVICE_INTERFACE_DATA diData = new HIDImports.SP_DEVICE_INTERFACE_DATA();
diData.cbSize = Marshal.SizeOf(diData);

// 3. get a device interface to a single device (enumerate all devices)
while(HIDImports.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref guid, index, ref diData))
{
// create a detail struct and set its size
HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA diDetail = new HIDImports.SP_DEVICE_INTERFACE_DETAIL_DATA();
diDetail.cbSize = 5; //should be: (uint)Marshal.SizeOf(diDetail);, but that's the wrong size

UInt32 size = 0;

// get the buffer size for this device detail instance (returned in the size parameter)
HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref diData, IntPtr.Zero, 0, out size, IntPtr.Zero);

// actually get the detail struct
if(HIDImports.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref diData, ref diDetail, size, out size, IntPtr.Zero))
{
// open a read/write handle to our device using the DevicePath returned
mHandle = HIDImports.CreateFile(diDetail.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, HIDImports.EFileAttributes.Overlapped, IntPtr.Zero);

// 4. create an attributes struct and initialize the size
HIDImports.HIDD_ATTRIBUTES attrib = new HIDImports.HIDD_ATTRIBUTES();
attrib.Size = Marshal.SizeOf(attrib);

// get the attributes of the current device
if(HIDImports.HidD_GetAttributes(mHandle.DangerousGetHandle(), ref attrib))
{
// if the vendor and product IDs match up
if(attrib.VendorID == VID && attrib.ProductID == PID)
{
// 5. create a nice .NET FileStream wrapping the handle above
mStream = new FileStream(mHandle, FileAccess.ReadWrite, REPORT_LENGTH, true);
}
else
mHandle.Close();
}
}

// move to the next device
index++;
}

// 6. clean up our list
HIDImports.SetupDiDestroyDeviceInfoList(hDevInfo);

CreateFile and SafeFileHandles

If you read through the above code, you may have noticed that the handle to the Wiimote is opened using Win32's CreateFile function instead of directly using a FileStream object or some other managed way.  This is required due to the way that the handle needs to be created.  The DevicePath member of the detail struct contains a non-file system path that Win32 can use to open a handle to the device.  The .NET methods for performing this action will only allow file system paths, so we must use the Win32 method instead.

You will also notice that we use the SafeFileHandle object to wrap the handle returned from the call to CreateFile.  The SafeFileHandle object wraps a native Win32 handle and allows one to safely manage the native type and cleanly close things up at the end of the application.  One could just as easily use an IntPtr, but I have found that this is a much cleaner method for dealing with the native type.

Wiimote I/O and HID Reports

In the world of HID, data is sent and received as "reports".  Simply, it is a data buffer of a pre-defined length with a header that determines the report contained in the buffer.  The Wiimote will send and can receive various reports, all of which are 22 bytes in length, and all of which are explained at the links above.  Given the number and complexity, I suggest you read through the wikis above if you wish to know more about the Wiimote's reports and the data they contain.

Now that we have a a FileStream on which to communicate with the Wiimote, we can start communication.  Because reports will be sent and received almost constantly, it is essential that asynchronous I/O operations are used.  In .NET, this is quite simple.  The process is to start an asynchronous read operation and provide a callback method to be run when the buffer is full.  When the callback is run, the data is handled and the process is repeated.

VB 

' sure, we could find this out the hard way using HID, but trust me, it's 22
Private Const REPORT_LENGTH As Integer = 22

' report buffer
Private mBuff As Byte() = New Byte(REPORT_LENGTH - 1){}

Private Sub BeginAsyncRead()
' if the stream is valid and ready
If mStream.CanRead Then
' create a read buffer of the report size
Dim buff As Byte() = New Byte(REPORT_LENGTH - 1){}

' setup the read and the callback
mStream.BeginRead(buff, 0, REPORT_LENGTH, New AsyncCallback(AddressOf OnReadData), buff)
End If
End Sub

Private Sub OnReadData(ByVal ar As IAsyncResult)
' grab the byte buffer
Dim buff As Byte() = CType(ar.AsyncState, Byte())

' end the current read
mStream.EndRead(ar)

' start reading again
BeginAsyncRead()

' handle data....
End Sub

C#

// sure, we could find this out the hard way using HID, but trust me, it's 22
private const int REPORT_LENGTH = 22;

// report buffer
private byte[] mBuff = new byte[REPORT_LENGTH];

private void BeginAsyncRead()
{
// if the stream is valid and ready
if(mStream.CanRead)
{
// create a read buffer of the report size
byte[] buff = new byte[REPORT_LENGTH];

// setup the read and the callback
mStream.BeginRead(buff, 0, REPORT_LENGTH, new AsyncCallback(OnReadData), buff);
}
}

private void OnReadData(IAsyncResult ar)
{
// grab the byte buffer
byte[] buff = (byte[])ar.AsyncState;

// end the current read
mStream.EndRead(ar);

// start reading again
BeginAsyncRead();

// handle data....
}

That's it!

You may not believe it, but that code is enough to open and start communicating with the Wiimote.  The rest of the code involves parsing the data sent from the Wiimote and writing properly formed data to the Wiimote.  As I said, I'm not going to go into the detail of the reports as the sites above will do a much better job than I, but one can write any command to the Wiimote simply by doing the following:

VB


mStream.Write(mBuff, 0, REPORT_LENGTH)

C#


mStream.Write(mBuff, 0, REPORT_LENGTH);

Reading is done with the async code you see above.  When a report of 22 bytes is received, the OnReadData method is called, and the data can be properly parsed and used.

Usage of the API

If you don't care about the implementation details, you've likely skipped down to this section to learn how to use the API in your own application.  The easiest way to learn how it all works is to look at the WiimoteTest application included with the source code.

captured_Image.png

First, you will need to add a reference to the WiimoteLib.dll included with the source code.  Next, you will need to pull the namespace into your application with the standard using/Imports statement.  With that in place, you can now create an instance of the Wiimote class and start using it.  Simply instantiate a new instance of the Wiimote class, setup events if you wish to use them, setup the report type of the data you want to be returned, and call the Connect method.

VB

Imports WiimoteLib

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
' create a new instance of the Wiimote
Dim wm As Wiimote = New Wiimote()

' setup the event to handle state changes
AddHandler wm.WiimoteChanged, AddressOf wm_WiimoteChanged

' setup the event to handle insertion/removal of extensions
AddHandler wm.WiimoteExtensionChanged, AddressOf wm_WiimoteExtensionChanged

' connect to the Wiimote
wm.Connect()

' set the report type to return the IR sensor and accelerometer data (buttons always come back)
wm.SetReportType(Wiimote.InputReport.IRAccel, True)
End Sub


Private Sub wm_WiimoteExtensionChanged(ByVal sender As Object, ByVal args As WiimoteExtensionChangedEventArgs)
If args.Inserted Then
wm.SetReportType(Wiimote.InputReport.IRExtensionAccel, True) ' return extension data
Else
wm.SetReportType(Wiimote.InputReport.IRAccel, True) ' back to original mode
End If
End Sub

Private Sub wm_OnWiimoteChanged(ByVal sender As Object, ByVal args As WiimoteChangedEventArgs)
' current state information
Dim ws As WiimoteState = args.WiimoteState

' write out the state of the A button
Debug.WriteLine(ws.ButtonState.A)
End Sub

C#

using WiimoteLib;

private void Form1_Load(object sender, EventArgs e)
{
// create a new instance of the Wiimote
Wiimote wm = new Wiimote();

// setup the event to handle state changes
wm.WiimoteChanged += wm_WiimoteChanged;

// setup the event to handle insertion/removal of extensions
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;

// connect to the Wiimote
wm.Connect();

// set the report type to return the IR sensor and accelerometer data (buttons always come back)
wm.SetReportType(Wiimote.InputReport.IRAccel, true);
}


void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
if(args.Inserted)
wm.SetReportType(Wiimote.InputReport.IRExtensionAccel, true); // return extension data
else
wm.SetReportType(Wiimote.InputReport.IRAccel, true); // back to original mode
}

void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
// current state information
WiimoteState ws = args.WiimoteState;

// write out the state of the A button
Debug.WriteLine(ws.ButtonState.A);
}

If you wish to use multiple Wiimotes, instantiate a WiimoteCollection object, call the FindAllWiimotes method to initialize it, and then use each individual Wiimote object in the collection as a separate instance.

VB

Dim wc As New WiimoteCollection()
wc.FindAllWiimotes()

For Each wm As Wiimote In wc
AddHandler wm.WiimoteChanged, AddressOf wm_WiimoteChanged
AddHandler wm.WiimoteExtensionChanged, AddressOf wm_WiimoteExtensionChanged

wm.Connect()
wm.SetReportType(InputReport.IRAccel, True)
Next wm

C#

WiimoteCollection wc = new WiimoteCollection();
wc.FindAllWiimotes();

foreach(Wiimote wm in wc)
{
wm.WiimoteChanged += wm_WiimoteChanged;
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;

wm.Connect();
wm.SetReportType(InputReport.IRAccel, true);
}

Data can be retrieved from the API in two ways:  events and polling.  In event mode, one must subscribe to the WiimoteChanged event as shown above.  Then, when data is sent from the Wiimote to the PC, an event will be posted to your event handler for processing in your application.  If you elect to not use the event model, you may simply retrieve state information at any time from the WiimoteState property of the Wiimote class.

Report Types

The library currently supports only a handful of the many report types the Wiimote is capable of producing, however the ones that are implemented are enough to get all required data for the Wiimote and all current extensions.  Specifically, these reports are:

  • Buttons - Button data only
  • ButtonsAccel - Button and accelerometer data
  • IRAccel - Button, accelerometer and IR data
  • ButtonsExtension – Button and extension data
  • ExtensionAccel - Button, accelerometer and extension data
  • IRExtensionAccel - Button, accelerometer, extension and IR data

The report type can be set by calling the SetReportType method using the appropriate report type and whether or not you would like the data to be sent continuously or only when the state of the controller has changed.

Extensions

There are currently three Wii extensions supported by the library: the Nunchuk, the Classic Controller, and the Guitar Hero controller.  If you wish to use these, you must setup an event handler for the WiimoteExtensionChanged event.  When this event is called, you can check the event argument to determine if an extension was inserted or removed, and what type extension was inserted.  In this event handler, you will need to change the report type with the SetReportType method to one that supports extension data, otherwise the data will not be returned to you.

If you are using a strictly polled method, you may also check the Extension and ExtensionType parameters of the WiimoteState property to determine when an extension has been inserted or removed.

The Wii Fit Balance Board will show up as a Wiimote controller with an extension attached.  The report type is set internally and any attempt to set a new report type on this device will be ignored.  The power button maps to the Wiimote's A button, and the LED maps to the Wiimote's LED1.  The rest of the Wiimote's properties are ignored.  The remainder of the balance board information can be found in the BalanceBoard struct inside the WiimoteState object.

State Information

The heart of the entire library is contained in the WiimoteState object.  Check the download's included .chm help file for the full set of properties available. 

To Do...

At the moment, usage of the speaker on the Wiimote is not supported.  I will likely add this in a future update.  Additionally, there are several report types which are not implemented, however the reports which are implemented return all necessary information.  I would also like to add some "higher level" functionality that will return pitch/roll angles, mouse cursor position for the IR sensor, etc.  Check this article and my blog for information on updates to the library.

Conclusion

And there we have it.  A fully functional managed library for the Wiimote.  Give it a try and integrate it into your existing applications or build something new!  I'm looking forward to some creative uses of the library...

If you have any issues using the library, or have any feature requests (other than sound), please don't hesitate to contact me directly or post a message in my forum dedicated to the project.

Enjoy!

Links

Bio

Brian is a Microsoft C# MVP who has been actively developing in .NET since its early betas in 2000, and who has been developing solutions using Microsoft technologies and platforms for even longer. Along with .NET, Brian is particularly skilled in the languages of C, C++ and assembly language for a variety of CPUs. He is also well-versed in a wide variety of technologies including web development, document imaging, GIS, graphics, game development, and hardware interfacing. Brian has a strong background in developing applications for the health-care industry, as well as developing solutions for portable devices, such as tablet PCs and PDAs. Additionally, Brian has co-authored the book "Debugging ASP.NET" published by New Riders, and is currently co-authoring a book titled "10 Coding4Fun Projects with .NET for Programmers, Hobbyists, and Game Developers" to be published by O'Reilly in late 2008. Brian also writes for MSDN's Coding4Fun website, contributing articles on a monthly basis.

Tags:

Follow the Discussion

  • Richard LalancetteRichard Lalancette

    Looks like the DELL M6400 won't let me skip the code part. So I cannot pair with the wii remote with the current software.

    I wonder if there would be another software I could use to setup bluetooth pairing on my precision M6400.

    I managed to pair with my mac mini, but the mini allowed me to not use a passcode in one of the options... what  a bummer.

  • JoshJosh

    Great article, I'm fooling around with my own code now.

    You could simplify the math a bit by using x^3. That takes care of the sign problem. How do you know the period should be 0.1? I assume this is seconds? Would it be better to capture the actual time?

  • Clint RutkasClint I'm a "developer"

    @Richard Lalancette, could always try another bluetooth dongle.

  • SarfrazSheikhSarfraz​Sheikh

    Excellent Library.

    The only problem I faced  is re-pairing the wii remote every time once wii remote is disconnect.

    I could also see issue reported by couple of other users DarinHIggins and BermudaLamb about the same issue. I wonder if this is fixable or a issue in bluetooth stack.

    Thanks,

    Sarfraz

  • Clint RutkasClint I'm a "developer"

    @SarfrazSheikh, the Wiimote doesn't properly support auto-pairing, so you must manually re-connect each time.  Yes, it's a pain...

  • Clint RutkasClint I'm a "developer"

    @Ikneedaname re: ipod, no

  • Clint RutkasClint I'm a "developer"

    @Ikneedaname we don't control that, the Wiimote to work on a PC is a hack and not all bluetooth adapters work on it.  You may want to try http://www.bluesoleil.com/ to get it working but no promises there.

    http://wiibrew.org/wiki/List_of_Working_Bluetooth_Devices are known working adapters

  • IkneedanameIkneedaname

    also, do you have anything for the ipod touch/ iphone?

  • IkneedanameIkneedaname

    I am using a Bluetooth device bought @ wall mart. (bad idea.) the wizard doesn't allow skip. is there a code that will allow me to connect to the wiimote with a passcode that my bt dongle would like. heres the url:

    http://www.iogear.com/support/dm/driver/GBU421#display

    i dont have enough money for another dongle. any ideas?

  • Clint RutkasClint I'm a "developer"

    @hackhack, check out the code in the example!  Brian shows off what the Wiimote sees in a picture box, you should be able to tweak that code into a text file.

  • hackhackhackhack

    Does anyone know how to extract the LED position values as they are updated into something like a text file? what code do you use and where do you add it?????? please help me out, ive been stuck on this forever!!!!

  • Shane SellingShane Selling

    Okay i have been using the Wii library very successfully in many of my programs as a mouse and/or controller. using the library is not my problem its just annoying me that i have to keep the wiimote flat in order to have the mouse move correctly.  i would like some help with trying to make the curser point straight in front of the remote as it does on the wii no matter the rotation of the remote. any help would greatly appreciated.  Its not a big deal but it would be cool if it worked.  

    Thanks to whoever helps me.

  • BauerMECHBauerMECH

    Ikneedaname - If you're running Windows 7 you can simply use the generic win driver for Bluetooth... you'll be given the option to pair w/o passkey.  Do not install the manufacturer's drivers for your dongle. Hope that helps.

  • Clint RutkasClint I'm a "developer"

    @Shane, one of the easiest ways to do this is to simply use a single IR point. You only need 2 or the midpoint if you want rotation.  In your case you just want the x/y position, so just use a single IR source as your pointer position.

  • AlphasuedeAlphasuede

    @CODING4FUN  Are you sure that using a single IR source is a good idea?

    The wiimotes report the IR position in "wiimote space" not world space.  You need to convert these numbers back into world space.  Since the accelerometers get affected by rapid movement, you will need to rotate the IR positions to world space using the angle between the two IR dots.

    You will probably need to use the accelerometers to disambiguate between various situations.

  • Clint RutkasClint I'm a "developer"

    @Shane, @Alphasuede - that's what I get for replying and not reading closely enough.  Yes, @Alphasuede is entirely correct.  If you want the rotation of the Wiimote to not affect the reported x/y position, you need to get the roll/pitch of the Wiimote and use that to map the coordinates back to something meaningful.  Here's a link with some more information:

    http://wiibrew.org/wiki/Wiimote/Pointing

  • MarschalMarschal

    Hi.

    First of all thx for the lib.

    I've connected my wiimote to my PC an tried the wiimotetest.exe. This worked great. But i want to code my own programm and i want to use this dll. My problem is that i don't know how tu use the dll, or how to use the functions of the dll.

    Btw i'm using cpp.

    Would be nice if s.o. could help me in this case;)

  • Clint RutkasClint I'm a "developer"

    @Marschal, to use C++, you'll have to use Managed C++.  But doing the rest is semi on you.  Add in the reference to the DLL and it should work just like c# or VB.Net

  • WeeblBullWeeblBull

    Thanks for the great API - I'm eager to use it.

    One question though - I don't recall seeing pitch/roll/yaw values and wondered if these can be derived somehow?  I know that roll (and pitch to an extent) can be taken from the IR sensor but is there an easy way for me to get the angles that the wiimote is held at?

    WiiMouse is a great app that is able to use the angle to move the mouse (if 2 is held) so I'm guessing this is possible?

    Thanks!

  • Clint RutkasClint I'm a "developer"

    @WeeblBull, you can't really get a true yaw value out of the Wiimote unless you use the IR source and the Wiimote is held parallel to the ground.  Even then it's not very accurate.  The Wiimote itself contains accelerometers, not gyros, and without gyros, you can't determine all 3 axes of rotation.  That's where the MotionPlus comes in, which the next version of WiimoteLib will have better support for.

  • Clint RutkasClint I'm a "developer"

    @prabhakar pal, to do finger tracking, add little reflectors to the end of your fingers.  Johnny Lee has a good example using the WiiMote lib.  http://johnnylee.net/projects/wii/

  • prabhakar palprabhakar pal

    how i  made tracking  fingers  using wiimote how i got tutorial abt that plz send me information about that as soon as possible....

  • robWiimoterobWiimote

    Great job!!

    This is an application that uses your lib for high speed robots:

    http://www.youtube.com/watch?v=vxZ5n2tnqOU

  • TJTJ

    If you inconsistently get the error: "Error reading data from wiimote ... is it connected" .. Try changing the batteries..

    After about %40 the signal got choppy, and the error messages got more frequent using the MS stack. Hope This saves some one time!

  • PabloPablo

    Hello. Excelent library !

    I have an issue when I'm trying to run my own application.

    My application can't recognize the Wiimote and it throws an exception:

    if(!mStatusDone.WaitOne(3000, false))

     throw new WiimoteException("Timed out waiting for status report");

    Has anyone have had the same problem?

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.