BrianPeek.com

A Compendium of Random Uselessness
in Search

Wiimote and .NET

Update 3/17/07: A new version of the code and assembly is linked from the article below which fixes a bug with the calibration data.

My latest article has been posted on MSDN's Coding4Fun.  This time I have created a fully managed library to use a Nintendo Wiimote (and all current extensions) in C# or VB.NET.  You will find a description of what was done, source code for the fully managed library, a test application, and compiled libraries for you to start using immediately.

As always, if you have questions, problems, feature requests, etc. please contact me and let me know.  If it's a question or comment that could benefit the masses, please create a new post over on the forum and I will reply there.

Head on over and check it out!

Published Mar 14 2007, 04:23 AM by Brian Peek
Filed under: , , ,

Comments

 

Jose Luis Latorre said:

¡¡¡Great job!!!

Just have taken a look at your library and I'm starting to think great things to do with it... we had a mouse cursor with some wii libraries but now we have full 3D control... thik it with WPF and 3D and voila, the first 3D cursor? or shall we say cursors? (with two wiimotes, of course...)

And more on, if you take a look at GlovePie, it is an Open scriptable project for managing 3D gloves and also adapted to the wii... that means something...

Well using your library in order to have a 3D cursor or object moving is one of my next priorities... (before wanted to do that with the cWiilibrary..) so... now is easier XD

Many Thanks!!

Jose

Can contact me through joslat(@)gmail dot net

March 14, 2007 12:51 PM
 

Robert McLaws said:

I'm sure this library took a lot of effort to create, so kudos for putting it together. However, I don't like the design pattern of the library. Instead of having to poll for the state of every button on the OnWiimoteChanged event, why don't you make it so that the button that changed state is a property of the WiimoteChangedEventArgs. That way, the code would look like this:

void wm_OnWiimoteChanged(object sender, WiimoteChangedEventArgs args)

{

   // write out the state of the bitton that was pressed  

   Debug.WriteLine(args.PressedButton.Name);

}

You could then write handler code like this:

void wm_OnWiimoteChanged(object sender, WiimoteChangedEventArgs args)

{

   switch (args.PressedButton.Name)

   {

       case "A":

           //do an action if the A button is pressed.

           break;

       case "B":

           //do an action if the A button is pressed.

           break;

}

IMO, that pattern is a lot more intuitive than the pattern you presented in your article. It would also write code that is drastically cleaner and easy to understand.

Thanks for your hard work!

March 14, 2007 1:46 PM
 

Brian Peek said:

brian said:

Robert,

I have to whole-heartedly disagree with the pattern you suggested.  How would one  handle button combinations, like a user pressing both the A & B buttons on the Wiimote?  I think code that looks like:

void wm_OnWiimoteChanged(object sender, WiimoteChangedEventArgs args)

{

 if(args.ButtonState.A && args.ButtonState.B)

    Debug.WriteLine("A&B pressed");

}

is a lot cleaner than how it would need to be done given the event model you've suggested.  If only one button press is sent at a time, or one accelerometer change, etc. you're going to have TON of events to deal with, and you'll have to manage another state on your own side to determine combination key presses and the like.

This way, on each event, you're given a snapshot of the entire controller and what it looked like at the time that event was created.

I think you'll find most game input libraries use a model like this.  Take a look at the XNA GamePad object and its internal GamePadButtons type.  You'll see a very similar model to mine...

http://msdn2.microsoft.com/en-us/library/microsoft.xna.framework.input.gamepadbuttons_members.aspx

If you care to discuss further, please create a post up in the forum...thanks!

March 14, 2007 2:21 PM
 

Robert McLaws said:

I stand corrected.

March 15, 2007 12:31 AM
 

John Snavely said:

Brian,

You are a tiny god. Fantastic work!

One question:

How you would get the Pitch and Roll data from the Wii?

Many thanks!

March 15, 2007 5:39 PM
 

Brian Peek said:

Hi John,

I deleted my last comment as I'm not sure they answered the question.  I guess you're looking for the angle of pitch/roll.  Here's a link to the WiiLi.org wiki which explains how to calculate what you're looking for.

I'll be sure to add this to the next version of the lib, but for now you should be able to calculate the values using the AccelState parameters.

Hope that helps...if not, post a msg up in the forum so we can more easily discuss.  Thanks!

 

March 15, 2007 5:48 PM
 

John Snavely said:

Your link answers it.

My question was based on a lack of understanding of the Wii. I thought that there were other sensors beyond the buttons, accelerometers, and IR.

Many thanks!

March 15, 2007 6:23 PM
 

Sami said:

Hi, i have a quick question. I have not tried this library yet, for lack of a bluetooth adapter, and would like to know if it is possible for an application written to catch those events to still catch them when it is out of focus.

If not, any idea how one would go about making that work?

My knowledge of Window's event messaging system is close to 0, but, would you need something like a mouse hook but for the bluetooth device?

March 17, 2007 10:51 AM
 

Brian Peek said:

Sami,

Once the handle to the device is opened with the library, you will always get the events sent to your application whether it is in focus or not.

March 17, 2007 1:03 PM
 

Maz said:

GREAT!! YOU ARE THE BEST MAN!!

March 20, 2007 3:25 PM
 

Kimundi said:

If have the problem that it worked the first time as long as the wiimote was connected but since then it allways throw the "Error reading data from Wiimote" exception. Restarting the System, Bluetooth Device or changing the Wiimote doesn't change anything. But it still works with GlovePIE without any problem.

March 25, 2007 10:19 AM
 

Brian Peek said:

Kimundi,

Not sure I have an answer for you.  In my testing, the only time I would get that error was when a) the Wiimote wasn't connected, or b) on machines with an incompatible stack.  In either case, I don't recall it working with GlovePIE but failing with my lib.

I wish I had more info or a better response, but the nature of the error is, unfortunately, very vague.  It's the equivalent of "I found the Wiimote, but I can't read any data from it."

If you look in the Connect() method, try removing the "ReadCalibraton()" call and see if you get any reports back from the Wiimote on its own.  Doubtful, but worth a try.

March 26, 2007 5:08 PM
 

Edward Roha said:

If you are running GlovePIE at the same you will get "Error reading data from Wiimote".

March 26, 2007 9:25 PM
 

Jon-Paul said:

Brian,

Does your library support multiple active wiimotes? I would like to make a simple multiplayer game. Thanks!

March 28, 2007 3:46 PM
 

Brian Peek said:

Jon-Paul,

At the moment, the library will only return the first instance of a Wiimote that it finds.  Multiple Wiimote support is on my todo list but it shouldn't be that hard to implement...you just need to continue the enumeration of HID devices looking for others that match the Wiimote's VID/PID and store the handles off in an array for communication.  I think. :)

March 28, 2007 3:53 PM
 

Jon-Paul said:

Thanks Brian! I'll poke around and see I can get that work.

Do you have any recomendations for writing a screen pointer based on the IR?

March 28, 2007 6:30 PM
 

Brian Peek said:

Cursor mode is also on my "to do" list. :)

The sensor is 1024x768 pixel camera of sorts.  My plan was to take the center point between the two IR points and scale the xy to the screen/window you're capturing the cursor in.

March 28, 2007 8:09 PM
 

Abi said:

First of all, thanks for great library!

I have trouble running multiple wiimotes at the same time. I made minimal modifications to Your code to detect and use as many wiimotes as it finds. But when i try to use any other wiimote than 1st found i get exception "Error reading data from Wiimote" regardless if previous wiimotes were initialized or not. Anyone has similar problems? Any ideas how to initialize many wiimotes?  I'm using D-Link DBT-120 with BlueSoleil and Asus WL-BTD201M with WIDCOMM stack.

April 3, 2007 5:01 PM
 

Brian Peek said:

Abi,

I wish I had some information or guidance for you but I don't.  I haven't had time to attempt multiple Wiimotes yet, but I don't see any reason why it shouldn't work.  Anyone else tried?

April 4, 2007 1:33 AM
 

Abi said:

Found 'solution' to my previous problem! I use CSR ( Cambridge Silicon Radio ) Bluetooth dongle with newest BlueSoleil stack. I've managed to connect tree wiimotes with nunchuck ( all i have ).

April 4, 2007 11:14 AM
 

Sam said:

Looks very interesting.

Has anyone built an application that graphs the 3D (xyz position over time) movement of the wii when thrown? Additional information, such as acceleration, velocity, height, distances, rotation, etc... at points during the flight would also be interesting to use.

Sam

smith.at.lkpd.org

April 6, 2007 1:59 PM
 

Bud said:

Thanks Brian!

For a moderately-skilled programmer like myself, having a simple to use library like this one is fabulous.

I created a [[ManagedWii]] topic on WiiLi wiki, it was a real shame for that community not to have any direct links back to this great work of yours for this beautiful little controller.  I hope you don't mind...

Please, as soon as you can find the time, continue and finish implementing your other ideas for this library.

I'm developing an XNA game, and I'm planning to integrate the Wiimote on the PC at least, right alongside my 360 controller for the PC.

Bud

April 12, 2007 4:34 PM
 

Brian Peek said:

Bud,

Thanks for the link from WiiLi wiki.  I have plenty of new things on the list to add, but I'm swamped on another project for the next few weeks.  I will get a new version up at some point, though...

April 13, 2007 3:17 PM
 

John said:

Hi Brian, great job!! from all the WiiMote Library's around I find yours the easiest one to use!

But I'm having a small problem.....

I'm trying the detect when the WiiMote gets disconnected.

ie: WiiMote is connected, I start the Test application, then I just turn the power off on the Remote.

What hapens is that the Test program seams to "freeze" which i think is normal since there's no more "OnWiimoteChanged" events genereated.

So what I did was put a timer on the form, set it to 2000ms

So I start it at form load, then I had a Timer.stop() just after m.WaitOne() and a Timer.Start() just before m.ReleaseMutex() in the "OnWiimoteChanged"

Basicly the effect I'm going for is that I get a timer tick if the "OnWiimoteChanged" did NOT run for 2 seconds.....

But the Timer tick never seams to occur... If I remove the STOP and START i do get a tick every 2 seconds.....

What am I doing wrong...? Or dod you have an other suggestion on how to detect if the WiiMote is still connected and sending data ?

Thanks

April 16, 2007 9:58 AM
 

Cheng said:

Hi Brain:

I sent a message through the contact system, but it seems you did not receive it.

Anyway, I will ask again.

Does the C# lib support multiple wiimotes? If not, then is there anywhy I can add support for it?

Thank you!

P.S. Thank you very much for the lib, seriously!!

April 17, 2007 11:03 PM
 

Brian Peek said:

John,

I think where you've placed the timer calls is only for the "read data" report type.  Button states and whatnot aren't sent via this report which is why you're not seeing the timer get started/stopped properly.

I think the easiest way would probably to create a timer or maybe another AutoResetEvent in the BeginAsyncRead()/OnReadData() methods.  This is where all data comes in and is handled.  So if you stop getting data, these OnReadData() will never fire, and that would be where the timer would kick in since it's not reset.

Hope that helps...

April 18, 2007 3:31 AM
 

Brian Peek said:

Cheng,

I did respond via email but I guess you didn't receive my reply.

Anyhow, you'll see a comment about multiple Wiimotes above.  It's not currently supported but I plan on adding it.  If you can't wait, see the above comment...the basic idea is to continue enumeration beyond the first found device and keep handles to the devices in an array or List.

I'm swamped through mid-May, so I likely won't have an update before then, unfortunately.

April 18, 2007 3:33 AM
 

Lawrence said:

Hi Brian, another thanks for the fantastic work.

I am having a problem which is slightly different to Abi's.  I am not trying to connect multiple Wiimotes, but I am trying to find out why the Connect() method will no longer detect one of my Wiimotes.  

After some testing with your library I was forced to switch my main Wiimote (the one I test with) to another Wiimote due to flat batteries and lack of replacements.  The backup (second) Wiimote connects without a problem, but now, since I have replaced the batteries in my main Wiimote, the application is no longer detecting the main and only works with my backup.  This has been tested with both my test application and the one provided by yourself.

The other night I tried testing this on my laptop, and found that the application was able to detect my main Wiimote again, but stopped detecting it after a short while.

The Wiimote still works fine with the Nintendo Wii and other applications such as GlovePIE.

Do you have any suggestions as to what may be causing this?

Thanks!

April 21, 2007 4:18 AM
 

Ben Knight said:

Abi,

On April 3rd you said that you were using D-Link DBT-120 with BlueSoleil.  Then on the 4th you replied that you had gotten three wiimotes working, but with a different bluetooth device.  Have you been able to get the one or more wiimotes working with the D-Link DBT-120?  (That's what I have and am hoping to use.)

I've had the wiimote working to a point, I can get it to connect to my computer, but whenever I run the test app I get that it can't find the wiimote, even though it will still sometimes show me button states (though nothing else works).  I'm just using the standard Windows XP SP2 bluetooth stack (I think) since that was what I needed to make my computer also work with my Lego NXT brick.

John, great work!  I anxiously await your mid-May (hopefully sooner) update!

April 21, 2007 7:40 AM
 

Brian Peek said:

Lawrence,

Very strange...no idea why that might happen.  Anyone else see this?

April 22, 2007 7:14 PM
 

Jeremy T said:

Thanks for the awesome library Brian!  I'm glad you recommeded a good bluetooth device also...the Widcomm in my Gateway tablet worked great once but never again since then.

I've spent some time extending your solution for multiple wiimotes and also implementing a cursor solution.  The multiple wiimotes were very straight forward, but the cursor is kind of tricky.

"My plan was to take the center point between the two IR points and scale the xy to the screen/window you're capturing the cursor in."

On the surface this solution seems to suffice, but in practice it only works when the wiimote is held level.  I found that you can compensate for wiimote tilt by calculating the roll angle and rotating the IR points around the center of the screen.  However there are a number of edge cases that make a complete pointer solution more complex, such as when only a single IR point is visible, or when the IR points get flipped (i.e. right is now on the left, etc).

I've done a solution that addresses these cases, but I'm sure there is a better general algorithm for it which has escaped me so far!  Anyway I hope that helps with your endeavors.

May 8, 2007 12:15 PM
 

Brian Peek said:

Jeremy,

Please send over what you have.  You can email me at my first name @ this domain or create an acct in the forum and you can attach a file to a post there.  Thanks!

May 8, 2007 1:00 PM
 

Jeremy T said:

You got it.  Enjoy!

May 10, 2007 12:59 PM
 

Antonie Bouman said:

I would like to use something like this on my Windows Mobile device ? any posiblities ?

Help would be appreciated.. any help for the mater ? programming bluetooth and / or HID devices on a mobile device isn't that easy. A Library like this would be awsome (for me that is because I don't think there is much use for a wiimote connection with a mobile device)

Thanks for helping me out / pointing me in the right direction already ?

May 21, 2007 10:41 AM
 

Brian Peek said:

Antonie,

Check the forums...there were a few people discussing creating a Windows Mobile version.

May 22, 2007 4:03 PM
 

Cheng said:

Hi Brain:

What does the mutex object do in your demonstration code?

I read Microsoft's documentation, but I didn't quite get it.

Sorry for this newbie questions, I am still learning C#.

Thank you!

May 22, 2007 8:37 PM
 

Brian Peek said:

Cheng,

A mutex is used in a multi-threaded environment to synchronize threads.  In essence, the code that's within a mutex block can only be accessed by one thread at a time.  The mutex in my code is used to make sure that only one thread at a time gets to run the OnWiimoteChanged event handler.  Since many events can be fired at once, there's a chance that one event could still be running the method while the next one comes in.  This makes sure that the first event is finished before the next one can run the same method, making sure the data is accurate and ensuring that the same control isn't being modified by two events simultaneously.

May 22, 2007 11:02 PM
 

Cheng said:

Thank you very much Brain!

Your explanation is very helpful!!

May 23, 2007 10:12 PM
 

Dan L said:

Hey, I was getting that Error reading data from wiimote message for the longest time. Using BlueSoleil 1.6.3.1 I did Discovered the wiimote, then Refreshed Services, then Connected. It connected fine, but I was getting that error above during ReadCalibration(). In the end, turns out I had a bad HID Joystick driver somehow. I removed that from my system(using Device Manager) then let my computer connect to MS servers to get the correct driver. After that, it works fine. Moral of the story, if you can't get past ReadCalibration, try reinstalling your HID Joystick drivers.

Oh, and Brian, this library makes you my hero!

June 7, 2007 3:10 AM
 

Mal Lansell said:

Does anyone know of a way to get notification of when a new device connects?  I would like to run the Wiimote code in a service, but it needs to know when a Wiimote device becomes available before trying to connect...

August 9, 2007 6:39 PM
 

Brian Peek said:

Mal,

There is no automatic way to do this.  Much like the autoconnect stuff discussed here:

http://www.brianpeek.com/forums/thread/1642.aspx

it likely will require coding against specific Bluetooth stacks.

My only suggestion is to modify the code to sit in a loop on Connect, and change Connect to now throw and error if a Wiimote isn't found.

August 9, 2007 7:31 PM
 

Mal Lansell said:

Thanks for the link.  I expected there to be nothing useful on the Bluetooth side - until there is one unified API Bluetooth is always going to be a problem on the PC.  I had hoped Windows might have a way to get notifications of new HIDs, but I guess I'll just have to try your suggestion - polling every one or two seconds and see how much CPU it takes.

Mal

August 10, 2007 5:48 AM
 

Jose Luis Latorre said:

Hi!, just to state a new code snippet using Brian's library. This time is a 3D WPF interaction with the wiimote, being able to control a 3D mesh with the 3D controller...

Of course, the sourcecode is included. :)

October 3, 2007 7:31 AM

Leave a Comment

(required)  
(optional)
(required)  
Add

About Brian Peek

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.
Copyright (C) 2008 Brian Peek
Powered by Community Server (Commercial Edition), by Telligent Systems