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.
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 (
- 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.
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
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:
wm.OnWiimoteChanged += new WiimoteChangedEventHandler(wm_OnWiimoteChanged);
void wm_OnWiimoteChanged(object sender,
Now within the event handling, we check the wiimote state from the properties within
if statements and we can then do whatever we want.
So that's a crash course in
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:
- Pause --> Buggy
- Volume Up
- Volume Down
- Fast Forward -->Buggy
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.
private Wiimote wm = new Wiimote();
private WMPYJW wmp = new WMPYJW();
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,
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.
private void Form1_Load(object sender, EventArgs e)
wm.OnWiimoteChanged += new WiimoteChangedEventHandler
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
void wm_OnWiimoteChanged(object sender,
#region Automate Play on WiiA
if (wm.WiimoteState.ButtonState.A && ButtonA != true)
ButtonA = true;
if (ButtonA == true && wm.WiimoteState.ButtonState.A != true)
ButtonA = false;
#region Automate Stop on WiiB
if (wm.WiimoteState.ButtonState.B && ButtonB != true)
ButtonB = true;
if (ButtonB == true && wm.WiimoteState.ButtonState.B != true)
ButtonB = false;
#region Automate Next on WiiUp
if (wm.WiimoteState.ButtonState.Up && ButtonUp != true)
ButtonUp = true;
if (ButtonUp == true && wm.WiimoteState.ButtonState.Up != true)
ButtonUp = false;
#region Automate Previous on WiiDown
if (wm.WiimoteState.ButtonState.Down && ButtonDown != true)
ButtonDown = true;
if (ButtonDown == true && wm.WiimoteState.ButtonState.Down != true)
ButtonDown = false;
#region Automate Volume Up on WiiPlus
if (wm.WiimoteState.ButtonState.Plus && ButtonPlus != true)
ButtonPlus = true;
if (ButtonPlus == true && wm.WiimoteState.ButtonState.Plus != true)
ButtonPlus = false;
#region Automate Volume Down on WiiMinus
if (wm.WiimoteState.ButtonState.Minus && ButtonMinus != true)
ButtonMinus = true;
if (ButtonMinus == true && wm.WiimoteState.ButtonState.Minus != true)
ButtonMinus = false;
#region Automate Volume Mute on WiiMute
if (wm.WiimoteState.ButtonState.One && Button1 != true)
Button1 = true;
if (Button1 == true && wm.WiimoteState.ButtonState.One != true)
Button1 = false;
#region Automate Fast Forward on WiiMute
if (wm.WiimoteState.ButtonState.Right && ButtonRight != true)
ButtonRight = true;
if (ButtonRight == true && wm.WiimoteState.ButtonState.Right != true)
ButtonRight = false;
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.
- 19th January, 2009: Initial post