<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Wiet-Lie--Chris-Nederpelt/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Wiet-Lie--Chris-Nederpelt/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Wiet-Lie--Chris-Nederpelt/Posts</link>
    <language>en</language>
    <pubDate>Sun, 19 May 2013 11:02:02 GMT</pubDate>
    <lastBuildDate>Sun, 19 May 2013 11:02:02 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>1</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Impersonating the Mouse with a Wiimote</title>
      <description><![CDATA[
<p><span id="c4fmetadata">
<table cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td>
<p><span class="entry_description">Once upon a time ... Nintendo, a game maker, innovates the world game experiences with a totally new concept: get physical (as to prevent you from getting ‘finger/thumb-RSI'). This striking new phenomenon is the nowadays well
 known Wii game, played with its remote objects, the Wii Remote (a.k.a Wiimote) and its companion, the Nunchuk.
</span></p>
<p><span class="entry_description">As time goes by, clever people discover other possibilities for, in this case, the Wiimote. With some dedicated software you can turn it into a PC device, impersonating the standard mouse.
</span></p>
</td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Wiet Lie &amp; Chris Nederpelt</div>
<div class="entry_company"><a href=""></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
Less than 1 hour</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input">MS VisualStudio 2005 / C#, WiimoteLib library from Brian Peek (http://www.brianpeek.com/)
</span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input">Nintendo Wii Remote (RVL-CNT-01) Bluetooth dongle plus software</span></div>
<div class="entry_details"><b>Download: </b><a href="http://channel9.msdn.com/ShowPost.aspx?PostID=370362">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span></p>
<p>The feature that will be discussed in this article. </p>
<p>The project uses the following attributes:<br>
•&nbsp;&nbsp;&nbsp; Wiimote: Nintendo RVL-CNT-01<br>
•&nbsp;&nbsp;&nbsp; Bluetooth USB dongle<br>
•&nbsp;&nbsp;&nbsp; BlueSoleil bluetooth stack (using version 2.3.0)<br>
•&nbsp;&nbsp;&nbsp; Software library ‘WiimotLib', (courtesy Brian Peek)<br>
•&nbsp;&nbsp;&nbsp; Software development: MS-Visual C# 2005 </p>
<p><b><u>The Hard Stuff</u></b> </p>
<p>The soul of the Wiimote machine is a device called MEMS. </p>
<p>What are MEMS? These tiny devices, sizing micro to nanometers, are small integrated devices, combining electrical and mechanical components, hence the naming of
<i>Micro Electro Mechanical Systems</i>. </p>
<p>For those interested in the history of the MEMS, please read the next article:
<i>“MicroELectroMechanical Systems (MEMS) by Salvatore A. Vittorio – web link: <a href="http://www.csa.com/discoveryguides/mems/overview.php">
http://www.csa.com/discoveryguides/mems/overview.php</a>”</i> </p>
<p>By making all those fantastic movements possible, the MEMS device has found its way into the mass (gaming, a.o.) market.
</p>
<p>The following is an excerpt from <i>“memsnet.org”</i>, explaining the MEMS in a nutshell:
</p>
<p><i>“Micro-Electro-Mechanical Systems (MEMS) is the integration of mechanical elements, sensors, actuators, and electronics on a common silicon substrate through microfabrication technology. While the electronics are fabricated using integrated circuit (IC)
 process sequences, the micromechanical components are fabricated using compatible &quot;micromachining&quot; processes that selectively etch away parts of the silicon wafer or add new structural layers to form the mechanical and electromechanical devices.”</i>
</p>
<p>The following is a view of the ‘internals' of a MEMS device: (courtesy of <i><a href="http://www.silicondesigns.com">www.silicondesigns.com</a></i>)
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_2.jpg"><img height="178" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_thumb.jpg" width="322" border="0"></a></p>
<p>&nbsp;</p>
<p>&nbsp; <a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_5B4_5D.jpg">
<img height="246" alt="clip_image002[4]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_5B4_5D_thumb.jpg" width="262" border="0"></a>&nbsp;&nbsp;
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_5B6_5D.jpg">
<img height="207" alt="clip_image002[6]" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_5B6_5D_thumb.jpg" width="206" border="0"></a></p>
<p>Nintendo's Wiimote motion detection is sensed and controlled by the ADXL330 MEMS accelerometer device from Analog Devices:
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_2.gif"><img height="294" alt="clip_image002" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/clip_image002_thumb.gif" width="526" border="0"></a>
</p>
<p>(iMEMS: Integrated Microelectromechanical System) </p>
<p>Having covered the hardware stuff, we will elaborate on the soft part: </p>
<p>Browsing the Internet learns that there are several Wiimote applications floating around – the one we needed, a basic PC mouse functionality also exists, it's called ‘<i>WiinRemote</i>', hosted at the site
<i><a href="http://onakasuita.org/wii/index-e.html">http://onakasuita.org/wii/index-e.html</a></i>., and is built with the Borland Delphi 6 Pro development framework.
</p>
<p>Alas, living in a non-Delphi habitat, it forces us to either convert the WiinRemote to, or start from scratch with VisualStudio. Both are unfavorable. A middle way was chosen: use the WiinRemote as a reference and build the mouse application based on Brian
 Peek's Wiimotelib library. </p>
<p>That's how it all started ... . </p>
<p><b><u>Implementation</u></b> </p>
<p>First off, we are confronted with the mechanical behavior of the Wiimote, in particular how the human complex movements translates to MEMS data, got converted in the chip into voltages and ultimately arrives at our VisualStudio development screen as hex
 values. </p>
<p>Then there is the choice between using the Wii IR LED bar array or not; using this method has the advantage of an easier interface algorithm. The drawback is: yet another device, plus its power supply, to incorporate in the scene. So we decided not to use
 it and go for the Wiimote only. </p>
<p>The Wiimote outputs, as described in the ADXL330 data sheet, three voltages, representing the x,y and z axis, covering 6-DOF (Degrees Of Freedom).
</p>
<p>These accelerometer data, can then be worked out in a Motion Control system, which can be depicted as follows:
</p>
<p><b><u>Human Visualization:</u></b> </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_4.png"><img height="280" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_thumb_1.png" width="448" border="0"></a>
</p>
<p>Figure 1 depicts the trivial situation where a user wants to move the cursor from point A to point T, by manipulating the Wiimote.
</p>
<p>While the user is moving the Wiimote around in a kind of intuitive manner, the system should response with a dynamic behavior: starting swiftly, moving smoothly and a full-stop when the user ceases the activity.
</p>
<p>The start-stop functions contains a kind of <i>contradictio-in-termino</i>: it has to start immediately and come to a full stop at once, which in fact is ‘not possible' because a user's hand is
<i>never</i> completely at rest, it'll always have some minor, high frequency, ‘movement' (a.k.a vibration).
</p>
<p>To solve this problem we have to enter the Motion Control domain. </p>
<p>A setup of the Motion Control (<i>I-type gain</i>) is depicted in Figure 2. </p>
<p>In here the human factor is included in the closed loop; by doing so, the unwanted ‘jitter' (resulting in a ‘nervous' cursor behavior) can be taken into account and will be suppressed as much as possible.
</p>
<p>The Wiimote as such, is used as a <i>gravity sensor</i>, because it is highly influenced by the gravity force; the data sent out to the receiver is leading for its current angular state in space. Therefore only the X and Y components are of relevance.
</p>
<p>Explaining the control loop: </p>
<p><b><u>Technical Visualization:</u></b> </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_2.png"><img height="157" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_thumb.png" width="507" border="0"></a>
</p>
<p>In the feed forward path we see, from left to right, the human brain block as the initiator of all activities: it triggers the cursor movement (from point A to target T) by igniting neurons, sending muscle movement commands to the hand holding the Wiimote.
</p>
<p>This will produce the user-activity, <i>‘ua'</i> input signal for the Bluetooth control block, which comprises of: the Wiimote Controller → Bluetooth USB Dongle → Bluetooth Driver Software.
</p>
<p>At this stage we are actually <i>in-the-PC</i>; signal <i>‘b'</i> will be processed by our Control Function, outputting the
<i>‘c'</i> signal which in turn will be passed through an Integrator. </p>
<p>The <i>Control Function</i> is a non-linear function called <i>‘Signed Square'</i>, with one variable.
</p>
<p>Why this particular function? </p>
<p>The human intuitive movement consists of a uniformly accelerated and decelerated motion; for this type of movements we have a quadratic mechanical relation between distance and speed.
</p>
<p>The quadratic function is to achieve a swift, dynamic behavior of the Wiimote cursor at ‘large' distances (e.g. when starting the motion), and a sluggish one when approaching the target spot.
</p>
<p>The Integrator enables us to realize the relative positioning on the screen. </p>
<p>Another benefit of the <i>SignedSquare</i> function is the existence of the so-called
<i>‘dead zone'</i>, around the target position (see graph, Figure 3). This dead zone is particularly necessary because the human hand is never steady, completely at rest. It will always show some kind of
<i>‘vibration'</i> which will trigger the Wiimote event, resulting in a nervous, unsteady cursor positioning behavior.
</p>
<p>Within this region the cursor isn't allowed to move (it acts like the differences between the target and actual positions and speed are zero), beyond this region it should react immediately.
</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_6.png"><img height="233" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_thumb_2.png" width="299" border="0"></a>
</p>
<p>The <i>Signed Square</i> function in its general form: </p>
<p><i>f(x) = a.x</i><i><sup>2</sup></i> </p>
<p>A complicating issue is the fact that the Wiimote delivers positive as well as negative values while performing its duty in the real world; we have to take this into account in the formula and maintain its current working quadrant space signature. To achieve
 this, the <i>‘a'</i>-term should carry the right sign, accordingly to the Wiimote data values.
</p>
<p>Mathematical derivation of the sign function: </p>
<p>s<i>ign = </i>√<i> x</i><i><sup>2</sup></i><i> / x {1}</i> </p>
<p><i>f(x) = sign </i><i>× x</i><i><sup>2</sup></i><i> {2}</i> </p>
<p><i>(Remark: in the logical C# solution, the sign factor will be taken care of by the built-in ‘Math.Sign' method. Also, the possibility of a division by zero is covered as well. )</i>
</p>
<p>Putting {1} and {2} together gives us the wanted result: </p>
<p><i>f(x) = </i><i>x</i><i><sup>2</sup> </i><i>× ( </i>√<i> x</i><i><sup>2</sup></i><i> / x)</i><i></i>
</p>
<p><i><b>f(x) = </b><b>x </b></i><b><i></i></b><b><i>×</i></b><b> √<i> x</i></b><b><i><sup>2</sup></i></b>
</p>
<p>which gives the following results for the positive and negative values of x: </p>
<p>for <i>x </i><i>› 0</i> then <i>f(x) = x</i><i><sup>2</sup></i> </p>
<p>for <i>x </i><i>‹ 0</i> then <i>f(x) = -x </i><i>× </i>√<i> (-x)</i><i><sup>2</sup></i><i> = -x
</i><i>× </i>√<i> x</i><i><sup>2</sup></i> </p>
<p><i>f(x)</i> = -<i> x</i><i><sup>2</sup></i> </p>
<p>The integrator accumulates the ∆X, ∆Y movements; the output <i>‘y'</i>, is formally the wanted X,Y coordinates of the targeted position – however, it has to pass the ‘Screen Limitation' block to avoid excessive off-screen coordinate values which otherwise
 will result in an annoying cursor-hysteresis behavior (: cursor goes off-screen and ‘takes-a-while' before coming into vision when the Wiimote movement direction is reversed).
</p>
<p>The Screen Limitations block outputs the <i>‘ny'</i> cursor position signal which is then feedbacked into the control loop, closing the loop.
</p>
<p>As can be seen from Figure 3, the transfer function inhibits any movement around the ‘dead-zone' (around zero area), thus preventing any cursor vibrations to occur when at rest or at a full-stop moment.
</p>
<p><b>The Coding Stuff</b> </p>
<p>As said in the introduction, the main scheme of this project is not completely new; it refers for a great deal onto the
<i>‘WiinRemote'</i> application. Differences exists, for example in the number of Timer threads used, and mainly the motion control approach of the project (although I'm not sure whether WiinRemote also utilized it – the site doesn't carry any documentation,
 takes too much time to reverse-engineer/debug it). </p>
<p>The Code structure:</p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_8.png"><img height="666" alt="image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/6984678/image_thumb_3.png" width="472" border="0"></a>&nbsp;</p>
<p>In C# syntax: </p>
<p>Retrieve the button mapping between the Wiimote and the (impersonated-) mouse by reading the XML configuration file – App.config:
</p>
<div>
<div>
<pre><span>   1:</span> <span>&lt;?</span><span>xml</span> <span>version</span><span>=&quot;1.0&quot;</span> <span>encoding</span><span>=&quot;utf-8&quot;</span> ?<span>&gt;</span></pre>
<pre><span>   2:</span> <span>&lt;</span><span>configuration</span><span>&gt;</span></pre>
<pre><span>   3:</span>   <span>&lt;</span><span>appSettings</span><span>&gt;</span></pre>
<pre><span>   4:</span>     <span>&lt;!--These are the WiiMote to Mouse button assignments:--&gt;</span></pre>
<pre><span>   5:</span>     <span>&lt;</span><span>add</span> <span>key</span><span>=&quot;WiiMote_A&quot;</span> <span>value</span><span>=&quot;MOUSE_LEFT&quot;</span><span>/&gt;</span></pre>
<pre><span>   6:</span>     <span>&lt;</span><span>add</span> <span>key</span><span>=&quot;WiiMote_B&quot;</span> <span>value</span><span>=&quot;MOUSE_RIGHT&quot;</span><span>/&gt;</span></pre>
<pre><span>   7:</span>   <span>&lt;/</span><span>appSettings</span><span>&gt;</span></pre>
<pre><span>   8:</span>   </pre>
<pre><span>   9:</span> <span>&lt;/</span><span>configuration</span><span>&gt;</span></pre>
<pre><span>  10:</span>&nbsp; </pre>
</div>
</div>
<p>And assign it to the relevant variables:</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> ReadButtonAssignment</pre>
<pre><span>   2:</span> <span>// Here we ask for the button mapping of the WiiMote wrt the Mouse functions</span></pre>
<pre><span>   3:</span> <span>// Get the info from the XML-configuration file (App.Config):</span></pre>
<pre><span>   4:</span>&nbsp; </pre>
<pre><span>   5:</span> <span>private</span> <span>void</span> ReadButtonAssignment()</pre>
<pre><span>   6:</span> {</pre>
<pre><span>   7:</span>     strButtonA = ConfigurationManager.AppSettings[<span>&quot;WiiMote_A&quot;</span>];</pre>
<pre><span>   8:</span>     strButtonB = ConfigurationManager.AppSettings[<span>&quot;WiiMote_B&quot;</span>];</pre>
<pre><span>   9:</span> }</pre>
<pre><span>  10:</span> <span>#endregion</span> ReadButtonAssignment</pre>
</div>
</div>
<p>We retrieve the Wiimote data through the event scheme – therefore we need an event handler to react on such an occasion.
</p>
<p>The <i>wm_OnWiimoteChanged</i> event handler is responsible for handling the Wiimote events, occurring when it is moved.
</p>
<p>Executing Brian's method asynchronously, we receives the Wiimote's raw acceleration data for the x, y and z directions.</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> wm_OnWiimoteChanged</pre>
<pre><span>   2:</span> <span>void</span> wm_OnWiimoteChanged(<span>object</span> sender, WiimoteChangedEventArgs args)</pre>
<pre><span>   3:</span> {</pre>
<pre><span>   4:</span>     m.WaitOne();</pre>
<pre><span>   5:</span>     WiimoteState ws = args.WiimoteState;</pre>
<pre><span>   6:</span>&nbsp; </pre>
<pre><span>   7:</span>     <span>// Display the WiiMote energy state:</span></pre>
<pre><span>   8:</span>     BeginInvoke((MethodInvoker)<span>delegate</span>()</pre>
<pre><span>   9:</span>     {pbBatteryLevel.Value = (ws.Battery &gt; 0xC8 ? 0xC8 : (<span>int</span>)ws.Battery); });</pre>
<pre><span>  10:</span>      <span>float</span> f = ((<span>float</span>)(ws.Battery / 192.0f) * 100.0f);</pre>
<pre><span>  11:</span>     BeginInvoke((MethodInvoker)<span>delegate</span>()</pre>
<pre><span>  12:</span>     { lblBatteryLevel.Text = <span>&quot;Energy Level: &quot;</span>&#43;f.ToString(<span>&quot;F&quot;</span>)&#43; <span>&quot; %&quot;</span>; });</pre>
<pre><span>  13:</span>&nbsp; </pre>
<pre><span>  14:</span>     <span>// Information needed for Mouse movements ....:</span></pre>
<pre><span>  15:</span>     BeginInvoke((MethodInvoker)<span>delegate</span>()</pre>
<pre><span>  16:</span>     { lblAx.Text = ws.AccelState.X.ToString(); });</pre>
<pre><span>  17:</span>     BeginInvoke((MethodInvoker)<span>delegate</span>()</pre>
<pre><span>  18:</span>     { lblAy.Text = ws.AccelState.Y.ToString(); });</pre>
<pre><span>  19:</span>     BeginInvoke((MethodInvoker)<span>delegate</span>()</pre>
<pre><span>  20:</span>     { lblAz.Text = ws.AccelState.Z.ToString(); });</pre>
<pre><span>  21:</span>&nbsp; </pre>
<pre><span>  22:</span>     AnalyzeButton(ws);<span>//Read &#43; interpret WiiMote data, acquired via Bluetooth</span></pre>
<pre><span>  23:</span>&nbsp; </pre>
<pre><span>  24:</span>     m.ReleaseMutex();</pre>
<pre><span>  25:</span> }</pre>
<pre><span>  26:</span> <span>#endregion</span> wm_OnWiimoteChanged</pre>
</div>
</div>
<p>Knowing what the button is doing, we proceed and perform the event:</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> ButtonEvent</pre>
<pre><span>   2:</span> <span>// ButtonEvent prepares the actual event performing, providing the event</span></pre>
<pre><span>   3:</span> <span>// method with the necessary input: which_button, what_event_type and whether</span></pre>
<pre><span>   4:</span> <span>// it's a click or dragging event.</span></pre>
<pre><span>   5:</span>&nbsp; </pre>
<pre><span>   6:</span> <span>private</span> <span>void</span> ButtonEvent(<span>int</span> Button, <span>int</span> EventType, <span>ref</span> ButtonState</pre>
<pre><span>   7:</span>                          ButtonState)</pre>
<pre><span>   8:</span> {</pre>
<pre><span>   9:</span>     <span>if</span> (((EventType == nWII_EVENT_UP) &amp;&amp; ButtonState.PushFlag)||</pre>
<pre><span>  10:</span>        ((EventType == nWII_EVENT_DOWN)&amp;&amp; !(ButtonState.PushFlag)))</pre>
<pre><span>  11:</span>     {</pre>
<pre><span>  12:</span>         <span>switch</span> (Button)             <span>// Which button are we dealing with ...</span></pre>
<pre><span>  13:</span>         {</pre>
<pre><span>  14:</span>             <span>case</span> (nWII_BUTTON_A):</pre>
<pre><span>  15:</span>                 {</pre>
<pre><span>  16:</span>                     bRepeatFlag = <span>false</span>;</pre>
<pre><span>  17:</span>                     PerformEvent(strButtonA,EventType,bRepeatFlag);</pre>
<pre><span>  18:</span>                     <span>break</span>;</pre>
<pre><span>  19:</span>                 }</pre>
<pre><span>  20:</span>             <span>case</span> (nWII_BUTTON_B):</pre>
<pre><span>  21:</span>                 {</pre>
<pre><span>  22:</span>                     bRepeatFlag = <span>false</span>;</pre>
<pre><span>  23:</span>                     PerformEvent(strButtonB, EventType, bRepeatFlag);</pre>
<pre><span>  24:</span>                     <span>break</span>;</pre>
<pre><span>  25:</span>                 }</pre>
<pre><span>  26:</span>             <span>default</span>: <span>break</span>;</pre>
<pre><span>  27:</span>         }</pre>
<pre><span>  28:</span>     }</pre>
<pre><span>  29:</span>     <span>// Administer the PushFlag:</span></pre>
<pre><span>  30:</span>     <span>if</span> (EventType == nWII_EVENT_DOWN) ButtonState.PushFlag = <span>true</span>;</pre>
<pre><span>  31:</span>     <span>if</span> (EventType == nWII_EVENT_UP) ButtonState.PushFlag = <span>false</span>;</pre>
<pre><span>  32:</span> }</pre>
<pre><span>  33:</span> <span>#endregion</span> ButtonEvent</pre>
</div>
</div>
<p>The actual event-performing code: </p>
<p>Due to lack of HID (HUMAN INTERFACE DEVICE) support in this .NET framework, we have to ask for assistance from the good old WIN32 API and reach it through the P/Invoke, set available by the Runtime.InteropServices.</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> PerformEvent</pre>
<pre><span>   2:</span> <span>// Method performing the Mouse activities, based on the WIN32-API calls</span></pre>
<pre><span>   3:</span> <span>// (P/Invoke):</span></pre>
<pre><span>   4:</span>&nbsp; </pre>
<pre><span>   5:</span> <span>private</span> <span>void</span> PerformEvent(<span>string</span> ButtonAssignType, <span>int</span> EventType,</pre>
<pre><span>   6:</span>                           <span>bool</span> RepeatFlag)</pre>
<pre><span>   7:</span> {</pre>
<pre><span>   8:</span>     <span>if</span> ((EventType == nWII_EVENT_DOWN)&amp;&amp;(RepeatFlag == <span>false</span>))</pre>
<pre><span>   9:</span>                                     nLastPushTime = DateTime.Now; ;</pre>
<pre><span>  10:</span>&nbsp; </pre>
<pre><span>  11:</span>     <span>// Do the Mouse Event ...:</span></pre>
<pre><span>  12:</span>     <span>if</span> (ButtonAssignType == <span>&quot;MOUSE_LEFT&quot;</span>)</pre>
<pre><span>  13:</span>         <span>switch</span> (EventType)</pre>
<pre><span>  14:</span>         {</pre>
<pre><span>  15:</span>             <span>case</span> nWII_EVENT_DOWN:</pre>
<pre><span>  16:</span>                 Win32.mouse_event(Win32.MouseEventType.MOUSEEVENTF_LEFTDOWN,</pre>
<pre><span>  17:</span>                                  0,0,0,0);</pre>
<pre><span>  18:</span>                 <span>break</span>;</pre>
<pre><span>  19:</span>             <span>case</span> nWII_EVENT_UP:</pre>
<pre><span>  20:</span>                 Win32.mouse_event(Win32.MouseEventType.MOUSEEVENTF_LEFTUP,</pre>
<pre><span>  21:</span>                                  0,0,0,0);</pre>
<pre><span>  22:</span>                 <span>break</span>;</pre>
<pre><span>  23:</span>             <span>default</span>: <span>break</span>;</pre>
<pre><span>  24:</span>         }</pre>
<pre><span>  25:</span>&nbsp; </pre>
<pre><span>  26:</span>     <span>if</span> (ButtonAssignType == <span>&quot;MOUSE_RIGHT&quot;</span>)</pre>
<pre><span>  27:</span>         <span>switch</span> (EventType)</pre>
<pre><span>  28:</span>         {</pre>
<pre><span>  29:</span>             <span>case</span> nWII_EVENT_DOWN:</pre>
<pre><span>  30:</span>                 Win32.mouse_event(Win32.MouseEventType.MOUSEEVENTF_RIGHTDOWN,</pre>
<pre><span>  31:</span>                                  0, 0, 0, 0);</pre>
<pre><span>  32:</span>                 <span>break</span>;</pre>
<pre><span>  33:</span>             <span>case</span> nWII_EVENT_UP:</pre>
<pre><span>  34:</span>                 Win32.mouse_event(Win32.MouseEventType.MOUSEEVENTF_RIGHTUP,</pre>
<pre><span>  35:</span>                                  0, 0, 0, 0);</pre>
<pre><span>  36:</span>                 <span>break</span>;</pre>
<pre><span>  37:</span>             <span>default</span>: <span>break</span>;</pre>
<pre><span>  38:</span>         }</pre>
<pre><span>  39:</span> }</pre>
<pre><span>  40:</span> <span>#endregion</span> PerformEvent</pre>
</div>
</div>
<p>All the stuff above is useless if the event-catching and notifying mechanism isn't functioning ... .
</p>
<p>This is the responsibility of the two timer threads, started up at program loading.
</p>
<p>The <i><u>CursorMotionTimer</u></i> task is to trigger the cursor movement; it periodically (default = 10 msec) fetches the X and Y acceleration data from the Wiimote and process it according to the motion control scheme.</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> CursorMotionTimer_Tick</pre>
<pre><span>   2:</span> <span>private</span> <span>void</span> CursorMotionTimer_Tick(<span>object</span> sender, EventArgs e)</pre>
<pre><span>   3:</span> {</pre>
<pre><span>   4:</span>   <span>// Some information: the WiiMote utilize the ADXL330 (3-axis, &#43;/- 3g MEMS Accelerometer)</span></pre>
<pre><span>   5:</span>   <span>// from Analog Devices. It is a complete 3-axis accelerometer with signal conditioned</span></pre>
<pre><span>   6:</span>   <span>// voltage outputs, measuring position, motion, tilt, shock and vibration.</span></pre>
<pre><span>   7:</span>   <span>// Operating voltage: 1.8 to 3.6V</span></pre>
<pre><span>   8:</span>   <span>//</span></pre>
<pre><span>   9:</span>   <span>// The Motion Control is currently based on a Singular Signed Quadratic form with one</span></pre>
<pre><span>  10:</span>   <span>// variable, in its general form: F(x) = ax^2. However, since we have to deal with the</span></pre>
<pre><span>  11:</span>   <span>// WiiMote which delivers positive and negative values, the formula has to be adapted,</span></pre>
<pre><span>  12:</span>   <span>// otherwise the negative values will be lost due to the squaring.</span></pre>
<pre><span>  13:</span>   <span>// Ultimately the working implentation form is:</span></pre>
<pre><span>  14:</span>   <span>// sign = sqrt(x^2) / x     (1)  (the code will use the built-in Math.Sign function)</span></pre>
<pre><span>  15:</span>   <span>// f(x) = sign * x^2        (2)</span></pre>
<pre><span>  16:</span>   <span>// putting (1) and (2) together gives the working algorithm implemented in this version:</span></pre>
<pre><span>  17:</span>   // f(x) = x * sqrt(x^2)</pre>
</div>
</div>
Managing the X-space:
<div>
<div>
<pre><span>   1:</span> <span>//---------- POSITION_X:------------------------------------------</span></pre>
<pre><span>   2:</span> dWiiMoteSetSpeedX=Convert.ToDouble(lblAx.Text)-dWiiOffsetX;<span>//CURRENT position X from WiiMote</span></pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span> <span>// Using the Signed Square function:</span></pre>
<pre><span>   5:</span> nSign = Math.Sign(dWiiMoteSetSpeedX);    <span>// Mind the Wiimote directions ...</span></pre>
<pre><span>   6:</span> dWiiMoteSSXQuadratic = Math.Pow(dWiiMoteSetSpeedX,2.0) * nSign;</pre>
<pre><span>   7:</span>&nbsp; </pre>
<pre><span>   8:</span> dWiiMotePosX=(dWiiMotePosX&#43;(dWiiMoteSSXQuadratic*dSamplePeriod)*nSpeedGain); <span>// INTEGRATOR</span></pre>
<pre><span>   9:</span>&nbsp; </pre>
<pre><span>  10:</span> <span>// Do some limitations ...</span></pre>
<pre><span>  11:</span> <span>if</span> (dWiiMotePosX &gt;= 1) dWiiMotePosX = 1;</pre>
<pre><span>  12:</span> <span>if</span> (dWiiMotePosX &lt;= -1) dWiiMotePosX = -1;</pre>
<pre><span>  13:</span> dMousePosX = dWiiMotePosX;</pre>
<pre><span>  14:</span>&nbsp; </pre>
<pre><span>  15:</span> MousePosXFiltered = (MaxScreenX / 2)*(dMousePosX &#43; 1);   <span>// Mid screen</span></pre>
</div>
</div>
And the Y-space:
<div>
<div>
<pre><span>   1:</span> <span>//---------- POSITION_Y:------------------------------------------</span></pre>
<pre><span>   2:</span> dWiiMoteSetSpeedY=Convert.ToDouble(lblAy.Text)-dWiiOffsetY;<span>// CURRENT position Y from WiiMote</span></pre>
<pre><span>   3:</span>&nbsp; </pre>
<pre><span>   4:</span> <span>// Using the Signed Square function:</span></pre>
<pre><span>   5:</span> nSign = Math.Sign(dWiiMoteSetSpeedX);    <span>// Mind the Wiimote directions ...</span></pre>
<pre><span>   6:</span> dWiiMoteSSYQuadratic = Math.Pow(dWiiMoteSetSpeedY,2.0) * nSign;</pre>
<pre><span>   7:</span>&nbsp; </pre>
<pre><span>   8:</span> dWiiMotePosY=(dWiiMotePosY&#43;(dWiiMoteSSYQuadratic*dSamplePeriod)*nSpeedGain);   <span>// INTEGRATOR</span></pre>
<pre><span>   9:</span>&nbsp; </pre>
<pre><span>  10:</span> <span>// Do some limitations ...</span></pre>
<pre><span>  11:</span> <span>if</span> (dWiiMotePosY &gt;= 1) dWiiMotePosY = 1;</pre>
<pre><span>  12:</span> <span>if</span> (dWiiMotePosY &lt;= -1) dWiiMotePosY = -1;</pre>
<pre><span>  13:</span> dMousePosY = dWiiMotePosY;</pre>
<pre><span>  14:</span>&nbsp; </pre>
<pre><span>  15:</span> MousePosYFiltered = (MaxScreenY / 2) * (dMousePosY &#43; 1);   // Mid screen</pre>
</div>
</div>
<p>Having sorted out all those stuff, we can now address the cursor:</p>
<div>
<div>
<pre><span>   1:</span> <span>//----------------- MOVING THE CURSOR: ----------------------------</span></pre>
<pre><span>   2:</span>     Win32.SetCursorPos((<span>int</span>)MousePosXFiltered, (<span>int</span>)MousePosYFiltered);</pre>
<pre><span>   3:</span> }</pre>
<pre><span>   4:</span> <span>#endregion</span> CursorMotionTimer_Tick</pre>
</div>
</div>
<p>Our cursor should now arrive at the targeted position. </p>
<p><u>The <i>DragMouseTimer</i> method:</u> </p>
<p>Moving the mouse is one activity, click on something and drag it is another thing. We will cope with this action variety in the following manner:
</p>
<p>If it senses that the button is being held down for a certain period of time -in this case more than 800 msec (value from WiinRemote)- the event will be set to the EVENT_DOWN type, hence if the Wiimote is moved, it will drag the object it is clicked on.</p>
<div>
<div>
<pre><span>   1:</span> <span>#region</span> DragMouseTimer_Tick</pre>
<pre><span>   2:</span> <span>// Method performing the Mouse dragging while the Left or Right button is held down.</span></pre>
<pre><span>   3:</span> <span>// It has a 'pondering' window of 800 msec - beyond this, the RepeatFlag will signal</span></pre>
<pre><span>   4:</span> <span>// the ButtonEvent method that it shouldn't execute a subsequent mouse event,</span></pre>
<pre><span>   5:</span> <span>// instead maintain the current one, while the user is still holding down the key.</span></pre>
<pre><span>   6:</span>&nbsp; </pre>
<pre><span>   7:</span> <span>private</span> <span>void</span> DragMouseTimer_Tick(<span>object</span> sender, EventArgs e)</pre>
<pre><span>   8:</span> {</pre>
<pre><span>   9:</span>     TimeSpan Duration = DateTime.Now - nLastPushTime;</pre>
<pre><span>  10:</span>     <span>if</span> ( myButtons.ButtonA.PushFlag &amp;&amp; Duration.TotalMilliseconds&gt;800)</pre>
<pre><span>  11:</span>     {</pre>
<pre><span>  12:</span>         bRepeatFlag = <span>true</span>;</pre>
<pre><span>  13:</span>         PerformEvent(strButtonA,nWII_EVENT_DOWN,bRepeatFlag);</pre>
<pre><span>  14:</span>     }</pre>
<pre><span>  15:</span>&nbsp; </pre>
<pre><span>  16:</span>     <span>if</span> (myButtons.ButtonB.PushFlag &amp;&amp; Duration.TotalMilliseconds &gt; 800)</pre>
<pre><span>  17:</span>     {</pre>
<pre><span>  18:</span>         bRepeatFlag = <span>true</span>;</pre>
<pre><span>  19:</span>         PerformEvent(strButtonB, nWII_EVENT_DOWN, bRepeatFlag);</pre>
<pre><span>  20:</span>     }</pre>
<pre><span>  21:</span> }</pre>
<pre><span>  22:</span> <span>#endregion</span> DragMouseTimer_Tick</pre>
</div>
</div>
<p><b>How it works:</b> </p>
<p>Running the executable will produce a minimized WinForm on the Taskbar; the PC cursor is by now taken over by the Wiimote. You can use it with the A-button as a Left mouse button and the B-button as t he Right mouse button. To return the cursor control to
 the standard mouse, you have to kill the application. </p>
<p><b>Epilogue:</b> </p>
<p><b></b></p>
<p>That's all there is, for the moment; the movement control is still under investigation and is far from a finished state!
</p>
<p>If time permits and enlightened ideas pop-ups, we'll surely improve the device movement behavior (or somebody else can jump in the code).
</p>
<p><b>DISCLAIMER:</b> </p>
<p>The software is in a “work-in-progress” state – not fully tested – contains flaws – subject to changes.
</p>
<p>Use it with care. </p>
<p><b>Wiet's Bio:</b> </p>
<p>Wiet's experience covers both the hard and software framework. Started as an electrotechnical engineer designing computer boards and completing it with software programming (from Assembly via PL/M to C#) to let the hardware to come alive. Hard- and software
 interaction is his favorite working area. </p>
<p>Currently he is working for Philips Healthcare, a Dutch founded international company, carrying out his contribution to the firm from within the X-Ray Predevelopment department.
</p>
<p>You can reach Wiet via: <a href="mailto:wietlie@hotmail.com">wietlie@hotmail.com</a>
</p>
<p><b>Chris' Bio:</b> </p>
<p>Chris is an enthusiastic puzzler on real world problems. His knowledge is control theory and interfacing all kinds of contrasting areas of technology, such as analog-digital, hardware-software, sensor-actuator, human-machine. His fascination is the art of
 problem conversion to other domains, where they can be solved, followed by the back translation to its original domain to implement the solution. His programming experience covers various languages like LabView, Java(script), C#, HTML.
</p>
<p>Currently he works in the same predevelopment department as Wiet. </p>
<p>Chris can be reached at: <a href="mailto:space4chris@hotmail.com">space4chris@hotmail.com</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Wiet-Lie--Chris-Nederpelt/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:7d456d5a6af24e6ca66f9e7600d09f0a">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Impersonating-the-Mouse-with-a-Wiimote</comments>
      <itunes:summary>




&amp;nbsp;

Once upon a time ... Nintendo, a game maker, innovates the world game experiences with a totally new concept: get physical (as to prevent you from getting ‘finger/thumb-RSI&#39;). This striking new phenomenon is the nowadays well
 known Wii game, played with its remote objects, the Wii Remote (a.k.a Wiimote) and its companion, the Nunchuk.
 
As time goes by, clever people discover other possibilities for, in this case, the Wiimote. With some dedicated software you can turn it into a PC device, impersonating the standard mouse.
 




Wiet Lie &amp;amp; Chris Nederpelt


Difficulty: Intermediate
Time Required: 
Less than 1 hour
Cost: Free
Software: MS VisualStudio 2005 / C#, WiimoteLib library from Brian Peek (http://www.brianpeek.com/)

Hardware: Nintendo Wii Remote (RVL-CNT-01) Bluetooth dongle plus software
Download: Download







 
The feature that will be discussed in this article.  
The project uses the following attributes:
•&amp;nbsp;&amp;nbsp;&amp;nbsp; Wiimote: Nintendo RVL-CNT-01
•&amp;nbsp;&amp;nbsp;&amp;nbsp; Bluetooth USB dongle
•&amp;nbsp;&amp;nbsp;&amp;nbsp; BlueSoleil bluetooth stack (using version 2.3.0)
•&amp;nbsp;&amp;nbsp;&amp;nbsp; Software library ‘WiimotLib&#39;, (courtesy Brian Peek)
•&amp;nbsp;&amp;nbsp;&amp;nbsp; Software development: MS-Visual C# 2005  
The Hard Stuff  
The soul of the Wiimote machine is a device called MEMS.  
What are MEMS? These tiny devices, sizing micro to nanometers, are small integrated devices, combining electrical and mechanical components, hence the naming of
Micro Electro Mechanical Systems.  
For those interested in the history of the MEMS, please read the next article:
“MicroELectroMechanical Systems (MEMS) by Salvatore A. Vittorio – web link: 
http://www.csa.com/discoveryguides/mems/overview.php”  
By making all those fantastic movements possible, the MEMS device has found its way into the mass (gaming, a.o.) market.
 
The following is an excerpt from “memsnet.org”, explaining the MEMS in a nutshell:
 
“Micro-Electro-Mechanical Systems (MEMS) is the integration of m</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Impersonating-the-Mouse-with-a-Wiimote</link>
      <pubDate>Fri, 04 Jan 2008 21:30:11 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Impersonating-the-Mouse-with-a-Wiimote</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/6984678_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/6984678_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Wiet Lie &amp; Chris Nederpelt</dc:creator>
      <itunes:author>Wiet Lie &amp; Chris Nederpelt</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Impersonating-the-Mouse-with-a-Wiimote/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>