WiiLAB Example Code - Wiimote Class
Note: MATLAB R2007a or greater is required for this code to run correctly.
Annotations
This is the main MATLAB class file for WiiLAB. It provides all the methods that access and use the WiiLAB COM and WiimoteLib to communicate with the Wiimote.
All of the global functions listed in the previous section use the methods and variables of this Wiimote class to perform their respective tasks. The following links will go over each section of the code in greater detail.
Raw Source Code
The source code is also available as a .m file download at the bottom of the page.
% This script is the main file of the Wiimote Class
% This class provides the main functionality to connect to and interact
% with a wiimote using MATLAB
%
% Version 1.1
%
% Author: Jordan Brindza, University of Notre Dame
% Jessica Szweda, University of Notre Dame
%% Wiimote Class
classdef Wiimote < handle
%% Public properties
properties
% None at this time
end % Public properties
%% Private properties
properties (SetAccess = private)
% Private properties, viewable but not settable by the user
% An int value depending on which wiimote is connected
% 1/2/3/4 - if it is connected to wiimotes 1/2/3/4 respectively
% 0 - if there are no available wiimotes (they are all in use)
% -1 - There are no wiimotes on this computer to connect to
% -2 - Default value before initialization
isConnected = -2;
% LED struct
LEDs = LEDState;
% Rumble
Rumble = false;
% Accel struct:
% [X Y Z]
Accel = AccelState;
% AccelIndicator struct:
% [Enabled refObj dampingCoef vector]
AccelIndicator = struct( 'Enabled', false, ...
'refObj', [], ...
'dampingCoef', 0, ...
'vector', []);
% Buttons stuct:
% [A B Up Right Down Left Plus Minus Home One Two]
Buttons = ButtonState;
% IR struct:
% [source1 source2 source3 source4 midpoint]
% each of these is a IRState struct:
% [found X Y]
IR = IRState;
% Double value from 0-100 representing the percentage of battery
% remaining
Battery
% Nunchuk properties
% Button Struct:
% [C Z]
NunchukButtons = NunchukButtonState;
% Accel struct:
% [X Y Z]
NunchukAccel = AccelState;
% Joystick struct:
% [X Y]
NunchukJoystick = NunchukJoystickState;
% AccelGraph struct:
% [Enabled handle subplots yMin yMax width timer]
AccelGraph = struct( 'Enabled', false, ...
'handle', [], ...
'subplots', 0, ...
'yMin', 0, ...
'yMax', 0, ...
'width', 0, ...
'timer', 0);
end % Private properties
%% Non Accessable properties
properties (Access = private, Hidden = true)
% These properties are not accessable or viewable by the user
% actxserver for the wiimote library
wm
% Raw Wiimote Values
% These variables contain the arrays that are returned from the dll
% These are for internal use and quick access without the need to
% go through the structs
rawLEDs = [false false false false];
rawAccel
rawButtons
rawIR
rawNunchukAccel
rawNunchukButtons
rawNunchukJoystick
end % Non Accessable properties
%% Public methods
methods
%% Constructor
% Constructor
% Initializes the COM sever 'WiiLab.WiiLab'
% @return wiimote object
function wiimote = Wiimote()
wiimote.wm = actxserver('WiiLab.WiiLab');
end % Constructor
%% Connect / Disconnect
% Connect
% Connects to the wiimote and sets the input report type
% @param wiimote The wiimote object
function Connect(wiimote)
if(wiimote.isConnected <= 0)
% Connect to the wiimote
wiimote.isConnected = wiimote.wm.Connect();
if(wiimote.isConnected > 0)
% Set LEDs property
wiimote.SetLEDs((bitand(wiimote.isConnected, 1) > 0), ...
(bitand(wiimote.isConnected, 2) > 0), ...
(bitand(wiimote.isConnected, 4) > 0), ...
(bitand(wiimote.isConnected, 8) > 0));
% Display Connection Message
disp(['Wiimote ' int2str(wiimote.isConnected)...
' Successfully Connected']);
elseif (wiimote.isConnected == 0)
% There are wiimotes connected to this computer but they
% are all in use
disp('All Wiimotes connected to the computer are in use.');
elseif (wiimote.isConnected == -1)
% There are no wiimotes connected to this computer
disp('There are no Wiimotes connected to this computer.');
end
else
disp('The wiimote is already connected.');
end
end % Connect
% CheckConnection
% Attempts to retrieve information from the Wiimote
% This function is a "quick" fix around a Wiimote Read Error that
% will cause Matlab to crash if the Wiimote is Prematurely
% disconnected
% If the connection is bad the function will throw an error and
% halt execution
% If the connection is good the function will return and execution
% will continue
% This method will be called by every function that comunicates
% with the wiimote
function CheckConnection(wiimote)
% Check the connection
if (~wiimote.wm.CheckConnection())
% Tell the user the connectio has been lost
uiwait(msgbox(['The connection to the Wiimote has been lost. ' ...
'Please reconnect the Wiimote'], ...
'Connection Lost', 'error'));
% throw an error to halt the program
error(['The connection to the Wiimote has been lost. '...
'Please reconnect the Wiimote.']);
end
end
% Disconnect
% Disconnects the wiimote
% @param wiimote The wiimote object
function Disconnect(wiimote)
% Check Connection
wiimote.CheckConnection();
% Clean up the Wiimote
% Turn off Rumble if it is on
wiimote.SetRumble(false);
% Set All LEDs On
wiimote.SetLEDs(true, true, true, true);
% temp wiimote id
tempID = wiimote.isConnected;
% Disconnect the wiimote
wiimote.isConnected = ~wiimote.wm.Disconnect();
% Reset Properties
wiimote.ResetProperties();
% Display Disconnect Message
if(~wiimote.isConnected)
disp(['Wiimote ' int2str(tempID) ' Successfully Disconnected']);
else
disp(['Wiimote ' int2str(tempID) ' Not Disconnected']);
wiimote.isConnected = tmpID;
end
end % Disconnect
% DisconnectAllWiimotes
% Attempts to disconnect all the wiimotes connected
% @param wiimote The wiimote object
function DisconnectAllWiimotes(wiimote)
% Disconnect all the Wiimotes
wiimote.wm.DisconnectAll();
% Reset the properties of this Wiimote object
wiimote.isConnected = -2;
wiimote.ResetProperties();
% Inform the user
disp('All Wiimotes Disconnected');
end % DisconnectAllWiimotes
%% Wiimote Feedback
% SetRumble
% @param wiimote wiimote object
% @param on bool value indicating to turn the rumble on or off
function SetRumble(wiimote, on)
% Check Connection
wiimote.CheckConnection();
% Make call to the wiimote
if(wiimote.Rumble ~= on)
wiimote.wm.SetRumble(on);
wiimote.Rumble = on;
end
end % SetRumble
% SetLEDs
% @param wiimote wiimote object
% @param led1 bool value indicating to turn LED 1 on or off
% @param led2 bool value indicating to turn LED 2 on or off
% @param led3 bool value indicating to turn LED 3 on or off
% @param led4 bool value indicating to turn LED 4 on or off
function SetLEDs(wiimote, led1, led2, led3, led4)
% Check Connection
wiimote.CheckConnection();
% Make call to the wiimote if the LEDs have changed
if ( wiimote.rawLEDs(1) ~= led1 ...
|| wiimote.rawLEDs(2) ~= led2 ...
|| wiimote.rawLEDs(3) ~= led3 ...
|| wiimote.rawLEDs(4) ~= led4)
wiimote.LEDs.LED1 = led1;
wiimote.LEDs.LED2 = led2;
wiimote.LEDs.LED3 = led3;
wiimote.LEDs.LED4 = led4;
wiimote.rawLEDs = [led1 led2 led3 led4];
wiimote.wm.SetLEDsBool( led1, led2, led3, led4);
end
end % SetLEDs
%% Wiimote State
% UpdateWiimoteState
% General function that updates all needed data for the wiimote
% probably should be called at the beginning of every loop to
% ensure up to date data
% @param wiimote wiimote object
function UpdateWiimoteState(wiimote)
% Buttons
wiimote.GetButtonsState();
% Accel
wiimote.GetAccelState();
% IR
wiimote.GetIRState();
%Get Nunchuk data
wiimote.UpdateNunchukState();
end % UpdateWiimoteState
% GetButtonsState
% Function that updates the buttons state of the wiimote
% @param wiimote wiimote object
function GetButtonsState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Buttons
buttons = wiimote.wm.GetButtonState();
wiimote.Buttons.A = buttons(1);
wiimote.Buttons.B = buttons(2);
wiimote.Buttons.Up = buttons(3);
wiimote.Buttons.Right = buttons(4);
wiimote.Buttons.Down = buttons(5);
wiimote.Buttons.Left = buttons(6);
wiimote.Buttons.Plus = buttons(7);
wiimote.Buttons.Minus = buttons(8);
wiimote.Buttons.Home = buttons(9);
wiimote.Buttons.One = buttons(10);
wiimote.Buttons.Two = buttons(11);
wiimote.rawButtons = buttons;
end % GetButtonsStates
% GetAccelState
% Function that updates the accel state of the wiimote
% @param wiimote wiimote object
function GetAccelState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Accel
accel = wiimote.wm.GetAccelState() * 9.8;
wiimote.Accel.X = accel(1);
wiimote.Accel.Y = accel(2);
wiimote.Accel.Z = accel(3);
wiimote.rawAccel = accel;
end % GetAccelState
% GetIRState
% Function that updates the IR state of the wiimote
% @param wiimote wiimote object
function GetIRState(wiimote)
% Check Connection
wiimote.CheckConnection();
ir = wiimote.wm.GetIRState();
% sort the array values into the struct
wiimote.IR.source1.found = ir(1,1);
wiimote.IR.source1.x = ir(1,2);
wiimote.IR.source1.y = ir(1,3);
wiimote.IR.source2.found = ir(2,1);
wiimote.IR.source2.x = ir(2,2);
wiimote.IR.source2.y = ir(2,3);
wiimote.IR.source3.found = ir(3,1);
wiimote.IR.source3.x = ir(3,2);
wiimote.IR.source3.y = ir(3,3);
wiimote.IR.source4.found = ir(4,1);
wiimote.IR.source4.x = ir(4,2);
wiimote.IR.source4.y = ir(4,3);
wiimote.IR.midpoint.found = ir(5,1);
wiimote.IR.midpoint.x = ir(5,2);
wiimote.IR.midpoint.y = ir(5,3);
wiimote.rawIR = ir;
end %GetIRState
% GetBatteryState
% Function that updates the Battery state of the wiimote
% @param wiimote wiimote object
function GetBatteryState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Battery
wiimote.Battery = wiimote.wm.GetBatteryState();
end %GetIRState
%% Nunchuk State
% IsNunchukConnected
% @param wiimote wiimote object
% @return isConnected whether or not the Nunchuk is connected
function isConnected = IsNunchukConnected(wiimote)
% Check Connection
wiimote.CheckConnection();
isConnected = wiimote.wm.IsNunchukConnected();
end % IsNunchuckConnected
% UpdateNunchukState
% @param wiimote wiimote object
function UpdateNunchukState(wiimote)
% Buttons
wiimote.GetNunchukButtonsState();
% Accel
wiimote.GetNunchukAccelState();
% Joystick
wiimote.GetNunchukJoystickState();
end % UpdateNunchukState
% GetNunchukButtonsState
% @param wiimote wiimote object
function GetNunchukButtonsState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Buttons
buttons = wiimote.wm.GetNunchukButtonState();
wiimote.NunchukButtons.C = buttons(1);
wiimote.NunchukButtons.Z = buttons(2);
wiimote.rawNunchukButtons = buttons;
end % GetNunchukButtonsState
% GetNunchukAccelState
% @param wiimote wiimote object
function GetNunchukAccelState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Accel
accel = wiimote.wm.GetNunchukAccelState() * 9.8;
wiimote.NunchukAccel.X = accel(1);
wiimote.NunchukAccel.Y = accel(2);
wiimote.NunchukAccel.Z = accel(3);
wiimote.rawNunchukAccel = accel;
end % GetNunchukAccelState
% GetNunchukJoystickState
% @param wiimote wiimote object
function GetNunchukJoystickState(wiimote)
% Check Connection
wiimote.CheckConnection();
% Joystick
joystick = wiimote.wm.GetNunchukJoystickState();
wiimote.NunchukJoystick.X = joystick(1);
wiimote.NunchukJoystick.Y = joystick(2);
wiimote.rawNunchukJoystick = joystick;
end % GetNunchukJoystickState
%% Accel Indicator
% Initialize Accel indicator
function InitializeAccelIndicator(wiimote, obj, velDamping)
% if an indicator is already created then close it
if(wiimote.AccelIndicator.Enabled)
wiimote.CloseAccelIndicator();
end
wiimote.AccelIndicator.refObj = obj;
wiimote.AccelIndicator.dampingCoef = velDamping;
wiimote.AccelIndicator.Enabled = true;
end % InitializeAccelIndicator
% UpdateAccelIndicator
function UpdateAccelIndicator(wiimote)
if(wiimote.AccelIndicator.Enabled)
try
delete(wiimote.AccelIndicator.vector);
catch me %#ok<NASGU>
end
% Find the Center of the object
try
[x1 y1] = getCenter(wiimote.AccelIndicator.refObj);
catch me %#ok<NASGU>
% If the user deletes the AccelIndicatorObj before
% closing the Accel Indicator. We need to close it
wiimote.CloseAccelIndicator();
return;
end
% Calculate the objects center from the acceleration values and velocity damping
x1 = x1 + wiimote.Accel.X * wiimote.AccelIndicator.dampingCoef;
y1 = y1 + -1 * wiimote.Accel.Y * wiimote.AccelIndicator.dampingCoef;
% Calculate the Accel Vector
% -----------------------------------------------------
x2 = x1 + wiimote.Accel.X * 5;
y2 = y1 + -1 * wiimote.Accel.Y * 5;
vector = drawLine(x1, y1, x2, y2, 'black');
indCircle = drawCircle(x2, y2, 2, 'black');
wiimote.AccelIndicator.vector = [vector indCircle];
% -----------------------------------------------------
end
end
% CloseAccelIndicator
function CloseAccelIndicator(wiimote)
if(wiimote.AccelIndicator.Enabled)
wiimote.AccelIndicator.refObj = [];
try
delete(wiimote.AccelIndicator.vector);
catch me %#ok<NASGU>
end
wiimote.AccelIndicator.Enabled = false;
end
end
%% Acceleration Graphing
% Initialize Wiimote Acceleration Graph
% This function creates the graphs and listeners to the Accel
% prop
% @param wiimote wiimote object
function InitWiimoteAccelGraph(wiimote)
if(wiimote.AccelGraph.Enabled)
disp('The Wiimote Accel Graph is already Initialized.');
else
% path of graphing functions in case they were not already
% included
addpath .\WiimoteFunctions\GraphingFunctions;
% initialize variables
xmin = 0;
xmax = 1;
wiimote.AccelGraph.subplots = 3;
wiimote.AccelGraph.yMin = -20;
wiimote.AccelGraph.yMax = 20;
wiimote.AccelGraph.width = xmax-xmin;
tmpSubplots = wiimote.AccelGraph.subplots;
% create a figure containing 3 empty graphs
initializeGraph(tmpSubplots);
% set X- and Y-axis labels
% title of top graph used to hold user instructions
setLabels(1, 'Time (seconds)', 'Acceleration (m/s)', 'X-Acceleration', tmpSubplots);
setLabels(2, 'Time (seconds)', 'Acceleration (m/s)', 'Y-Acceleration', tmpSubplots);
setLabels(3, 'Time (seconds)', 'Acceleration (m/s)', 'Z-Acceleration', tmpSubplots);
% set each graph's axes
for i=1 : tmpSubplots
[ wiimote.AccelGraph.yMin ...
wiimote.AccelGraph.yMax ...
wiimote.AccelGraph.width ] = ...
setAxes(i, xmin, xmax, -20, 20, ...
tmpSubplots, ...
wiimote.AccelGraph.yMin, ...
wiimote.AccelGraph.yMax, ...
wiimote.AccelGraph.width);
end
set(gcf, 'Name', 'Wiimote Acceleration Values');
% Init Time to 0
wiimote.AccelGraph.timer = 0;
wiimote.AccelGraph.handle = gcf;
wiimote.AccelGraph.Enabled = true;
tic;
end
end % initializeWiimoteAccelGraph
% Update Wiimote Acceleration Graph
% This is whats called to update the graphs whenever the Accel
% changes
% @param wiimote wiimote object
function UpdateWiimoteAccelGraph(wiimote, src, evnt) %#ok<INUSD>
if (wiimote.AccelGraph.Enabled)
tmp_hdlCurrentWindow = gcf;
if(wiimote.AccelGraph.handle ~= tmp_hdlCurrentWindow)
set(0,'CurrentFigure', wiimote.AccelGraph.handle);
end
wiimote.AccelGraph.timer = wiimote.AccelGraph.timer + toc;
% plot the current time against acceleration values
for i=1 : wiimote.AccelGraph.subplots
plotData(i, wiimote.AccelGraph.timer, wiimote.rawAccel(i), ...
wiimote.AccelGraph.subplots, ...
wiimote.AccelGraph.yMin, ...
wiimote.AccelGraph.yMax, ...
wiimote.AccelGraph.width);
end
set(0, 'CurrentFigure', tmp_hdlCurrentWindow);
tic;
end
end % UpdateWiimoteAccelGraph
% Close Wiimote Acceleration Graph
% This function closes the graphs and disables the listeners
% @param wiimote wiimote object
function CloseWiimoteAccelGraph(wiimote)
if (wiimote.AccelGraph.Enabled)
tmp_hdlCurrentWindow = gcf;
if(wiimote.AccelGraph.handle ~= tmp_hdlCurrentWindow)
set(0,'CurrentFigure', wiimote.AccelGraph.handle);
end
% Done with these graphs. Don't allow new data to be plotted.
for i=1 : wiimote.AccelGraph.subplots
finished(i, wiimote.AccelGraph.subplots);
end
wiimote.AccelGraph.Enabled = false;
close(wiimote.AccelGraph.handle);
try
set(0, 'CurrentFigure', tmp_hdlCurrentWindow);
catch me %#ok<NASGU>
% Do Nothing, there is no other window
end
end
end % CloseWiimoteAccelGraph
%% Property Set Overrides
% rawAccel
function set.rawAccel(wiimote, newState)
wiimote.rawAccel = newState;
if(wiimote.AccelGraph.Enabled)
wiimote.UpdateWiimoteAccelGraph();
end
if(wiimote.AccelIndicator.Enabled);
wiimote.UpdateAccelIndicator();
end
end % set.rawAccel
end % Public methods
%% Private Methods
methods (Access = private)
% Reset properties
% @param wiimote wiimote object
function ResetProperties(wiimote)
% Clean up the Wiimote (rumble off, leds off)
wiimote.SetRumble(false);
wiimote.SetLEDs(false, false, false, false);
% Set default values for the properties
wiimote.Accel = AccelState;
wiimote.Buttons = ButtonState;
wiimote.IR = IRState;
wiimote.NunchukButtons = NunchukButtonState;
wiimote.NunchukAccel = AccelState;
wiimote.NunchukJoystick = NunchukJoystickState;
% Close the opional functions
try
wiimote.CloseWiimoteAccelGraph();
catch me %#ok<NASGU>
% Do Nothing
end
try
wiimote.CloseAccelIndicator();
catch me %#ok<NASGU>
% Do Nothing
end
end % Reset properties
end % Private Methods
end % Wiimote
--
JordanBrindza - 26 Jun 2008