Click here to Skip to main content
15,883,705 members
Articles / Programming Languages / C#

Wii-ndows Media Player

Rate me:
Please Sign up or sign in to vote.
3.00/5 (4 votes)
19 Jan 2008CPOL5 min read 45.1K   904   31   2
Using Wiimote and WiimoteLib to control Windows Media Player

Introduction

Most of you are familiar to the Nintendo Wii, and if you know the wii you probably know the wiimote (the Wii remote). The Wiimote is one of the most interactive gaming remotes I have put my hands on. After snooping around the net it turned out that using Bluetooth and the wiimote library, you can connect the wii to your PC as an HID and send/receive messages from and to the wiimote. In this project, we will connect the wiimote and then take control of the Windows Media Player, so the wiimote is going to be controlling the Windows Media Player (WMP) as a simple Bluetooth remote.

THIS PROJECT IS CREATED USING VS2008 so it might not work on previous versions.
You can download VS2008 Express edition for free.

Background

You will have to know how to use C# .NET, we will be using libraries (WiimoteLib) and a Library that I created to control the Windows Media Player. It would be good if you know how to basically connect the wiimote to the PC using bluetooth. (It was tested using BlueSoleil application.)

Using the Code

Let's start off talking about the structure of the application. It's made up of 3 parts, 3 projects within one solution.

  • The first part is the Wiimote Library (WiimoteLib)
  • The second part is a class library I created so that you can control the Windows Media Player(WMP). This was a bit tricky since Interoping was required to build this class.
  • The third part is the actual Windows Form Application, and it will be the median between the previous classes.

Part One, WiimoteLib

WiimoteLib is a library that is pre-created and consumes the wiimote rather well. You can search for many examples on how to use it.
I'll give a simple explanation on it.
First of all, to use this library you should create an instance.

C#
Wiimote wm = new Wiimote;

After creating this instance, you should connect to the Wiimote. Make sure the wii is connected to your laptop via Bluetooth.

To connect to the laptop, you should do the following. When using BlueSoliel, turn on bluetooth on the laptop, pick up your wiimote and click buttons 1 and 2 together and that will cause the LEDs on the wii to blink rapidly, now go to Blue Soliel again and search for the wii, when found connect to it. Make sure while you search for the wii and connect that the LEDs are blinking.

Now connecting the wii through the application, you should use wm.Connect();
Of course, if you connect something you should disconnect it, so don't forget to add wm.Disconnect(); when your application terminates.
Now we have a connection ready to send and receive data.

Now we need an event handler for when the wiimote changes its state, and changing its state here is like changing the Button States, or the Accel States (Compas Sensors). In our project, we will only be tracking Button States. So we need to tell the wiimote that by wm.SetReportType(Wiimote.InputReport.ButtonsAccel,true); and that tells it to use the Buttons and Accel.
Now we event handle the changes by the following:

C#
//...Form Load Function...
wm.OnWiimoteChanged += new WiimoteChangedEventHandler(wm_OnWiimoteChanged);
//...
       void wm_OnWiimoteChanged(object sender,
	WiimoteChangedEventArgs args) //Function fires on wiimote change state change
        {
        }

Now within the event handling, we check the wiimote state from the properties within wm.WiimoteState through if statements and we can then do whatever we want.
So that's a crash course in WiimoteLib.

Part Two, WMPControlYJW

WMPControlYJW is the Windows Media Player Controller class, or we can call it the automater. This was the tricky part, I searched the net up and down for a pre-made class to control WMP but no luck, so I had to go back to INTEROP. I know it's a pain but I got no other choice.
By using Spy++ tool and following the commands one by one, I finally created the library. It supports:

  • Play
  • Pause --> Buggy
  • Stop
  • Next
  • Previous
  • Volume Up
  • Volume Down
  • Fast Forward -->Buggy
  • Mute

As you can see, two of the features are marked buggy. Even though I worked very hard and made sure the commands are correct, I still have trouble with both of them.
Pause when called it pauses but when playing again it skips the song and goes to the next.
Fast Forward jumps to the next song and doesn't Fast Forward. Let me know if you can find a way around this.

Now how to use the class:

First you need to connect to the Open Instance of Windows Media Player by calling the --.Connect() then simply call the methods you want to use, PLAY, STOP or whatever you can see using VS's Built in intellisense.

Part Three, The GUI, The Median

What does the Median mean? It's the application that picks up the wiimote state change and sends it to the WMPControlYJW Library that sends it to the WMP and controls it.
I'll place parts of the code and explain them.

C#
//Create Wiimote instance and WMPYjw Control
private Wiimote wm = new Wiimote();
private WMPYJW wmp = new WMPYJW();
//

//Bools to track previous state of buttons
private bool ButtonA = false;
private bool ButtonB = false;
private bool ButtonUp = false;
private bool ButtonDown = false;
private bool ButtonPlus = false;
private bool ButtonMinus = false;
private bool Button1 = false;
private bool ButtonRight = false;
////

The first two lines of code are creating instances of both libraries, Wiimote and WMPControlYJW.
What are all those bools? They are there to hold the previous state of the wiimote button so as to prevent constant firing of the IF branch for the current button within the event handler.

C#
private void Form1_Load(object sender, EventArgs e)
       {
           wmp.ConnectWMP(); // Connect to the Open Windows Media Player
           wm.Connect(); //Connect to Wiimote
           wm.SetReportType(Wiimote.InputReport.ButtonsAccel,true); //Set Needed
                           //tracking of wii
           wm.OnWiimoteChanged += new WiimoteChangedEventHandler
       (wm_OnWiimoteChanged); // Set event for Wiimote change
       }

This is the Form Load, the Projects form. When it runs, it connects to the WMP, then connects to the Wiimote. After that, as explained before, it tells the wii which inputs we want to use.
Now we have the wii event and tell it where the function to target is. When the wii state changes, it goes to the wm_OnWiimoteChanged function.

C#
void wm_OnWiimoteChanged(object sender, 
	WiimoteChangedEventArgs args) //Function fires on wiimote change state change
{
    #region Automate Play on WiiA
    if (wm.WiimoteState.ButtonState.A && ButtonA != true) //Checks to prevent multi-firing
    {
        wmp.Play(); // Send play command thru WMPControlYJW
        ButtonA = true; //To prevent Multi-Firing
    }
    if (ButtonA == true && wm.WiimoteState.ButtonState.A != true)//To prevent Multi-Firing
    {
        ButtonA = false;//To prevent Multi-Firing
    }
    #endregion
    #region Automate Stop on WiiB
    if (wm.WiimoteState.ButtonState.B && ButtonB != true)
    {
        wmp.Stop();// Send Stop command thru WMPControlYJW
        ButtonB = true;
    }
    if (ButtonB == true && wm.WiimoteState.ButtonState.B != true)
    {
        ButtonB = false;
    }
    #endregion
    #region Automate Next on WiiUp
    if (wm.WiimoteState.ButtonState.Up && ButtonUp != true)
    {
        wmp.Next();// Send Next command thru WMPControlYJW
        ButtonUp = true;
    }
    if (ButtonUp == true && wm.WiimoteState.ButtonState.Up != true)
    {
        ButtonUp = false;
    }
    #endregion
    #region Automate Previous on WiiDown
    if (wm.WiimoteState.ButtonState.Down && ButtonDown != true)
    {
        wmp.Previous();// Send Previous command thru WMPControlYJW
        ButtonDown = true;
    }
    if (ButtonDown == true && wm.WiimoteState.ButtonState.Down != true)
    {
        ButtonDown = false;
    }
    #endregion
    #region Automate Volume Up on WiiPlus
    if (wm.WiimoteState.ButtonState.Plus && ButtonPlus != true)
    {
        wmp.Volume_Up();// Send Volume Up command thru WMPControlYJW
        ButtonPlus = true;
    }
    if (ButtonPlus == true && wm.WiimoteState.ButtonState.Plus != true)
    {
        ButtonPlus = false;
    }
    #endregion
    #region Automate Volume Down on WiiMinus
    if (wm.WiimoteState.ButtonState.Minus && ButtonMinus != true)
    {
        wmp.Volume_Down();// Send Volume Down command thru WMPControlYJW
        ButtonMinus = true;
    }
    if (ButtonMinus == true && wm.WiimoteState.ButtonState.Minus != true)
    {
        ButtonMinus = false;
    }
    #endregion
    #region Automate Volume Mute on WiiMute
    if (wm.WiimoteState.ButtonState.One && Button1 != true)
    {
        wmp.Mute();// Send Mute command thru WMPControlYJW
        Button1 = true;
    }
    if (Button1 == true && wm.WiimoteState.ButtonState.One != true)
    {
        Button1 = false;
    }
    #endregion
    #region Automate Fast Forward on WiiMute
    if (wm.WiimoteState.ButtonState.Right && ButtonRight != true)
    {
        wmp.Fast_Forward();	// Send Mute command thru WMPControlYJW 
			// Still Causing Trouble
        ButtonRight = true;
    }
    if (ButtonRight == true && wm.WiimoteState.ButtonState.Right != true)
    {
        ButtonRight = false;
    }
    #endregion
}

The previous code is how the wii change is handled. It is commented and pretty straight forward.
Just to put to the point that the bools are used here to prevent multi-firing.

Points of Interest

Within this project, we have seen how to basically use Wiimote with .NET.
Imagine the Infinite possibilities of projects that can be created using this technology.
The best thing in the Wiimote is the IR Camera that can catch up to 4 different IR instances (IR Infrared).
This can help HIC Developers in creating amazing interactive applications.

History

  • 19th January, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Genesis Jo
Jordan Jordan
- German Jordanian University
Computer Engineering Software Systems
German Jordanian University IT_CLUB President
Genesis Jo Software Arch. and Eng.
Microsoft Student Partner
Microsoft ImagineCup Jordan Champion
Microsoft ImagineCup 2nd Place Regional

- .Net Developer
ASP.NET 3.5
Silverlight (Advanced)
Robotics Studies
3D Virtual Machine Studies



Comments and Discussions

 
GeneralMy vote of 5 Pin
Shinigamae7-Oct-10 3:07
Shinigamae7-Oct-10 3:07 
GeneralNice implementation Pin
ctorob20-Jan-08 3:20
ctorob20-Jan-08 3:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.