Wiimote Project » Hardware Support » IR Pens » Dual IR LED IWB Wii Mouse Pen
: [1]
   
: Dual IR LED IWB Wii Mouse Pen  ( 14141 )
0 and 1 Guest are viewing this topic.
*
Karma: +2/-0
: 64
Offline Offline
« : July 03, 2011, 09:20:33 PM »

Hi,

I have constructed a prototype whiteboard IR Pen which can provide left and right mouse button functionality.

The pen uses a bidirectional finger switch to turn on either one, or two IR LEDs.

The LEDs are wired to indicate whether the switch is pressed forward or backward, and this can be mapped to mouse button commands.

A Wii Remote is used to detect the IR LEDs from the pen, and software is used to determine the corresponding mouse command to be issued. I use GlovePie to act as the intermediate software between the pen and the computer application that is driven by the pen mouse.

The basic specification of the mouse pen is as follows.

1. Its made from a Sharpie Pen.

2. It has a fixed pointer IR LED at the tip.

3. It has a second IR LED mounted in the pen body.

4. The pen is ambidexterous for right and left hand users. The second IR LED is mounted in the pen cap so that it can be pulled off and turned to face the other side, so the Wii Remote camera can see it from the other direction.  

5. The IR LED switching is performed through one rocker switch with the Index Finger.

6. The pen is powered with a single 'AAA' 1.5 Volt battery. The battery is removable and replaceable using the battery holder provided. Just pull the cap off, and take the battery out.

7. The pen weighs under 40 grams.

 

« : September 23, 2011, 09:27:57 AM zainey »
*
Karma: +2/-0
: 64
Offline Offline
« #1 : July 03, 2011, 09:32:33 PM »

Hi,

The electrical circuit for the Wii Mouse Pen is basic, but clever in a way.

To provide one or two IR LED functionality from the same 1.5 Volt battery is tricky.

If electronics were used there would be little margin between the battery voltage (1.5V) and the IR LED Forward Voltage (~ 1.25V) for performing logic and getting sufficient voltage and current through the LEDs to make the pen work effectively.

Therefore the switching is perfomed mechanically through a Double Pole - Double Throw (DPDT) switch.

This switch isolates the One LED and Two LED circuits so that they can operate independently, and use the full voltage difference between the battery and IR LED forward voltage to provide bright indication from the IR LEDs.

The Electrical Schematic circuit diagram for the Wii Mouse Pen is attached.

« : July 03, 2011, 09:35:18 PM zainey »
*
Karma: +2/-0
: 64
Offline Offline
« #2 : July 03, 2011, 09:43:30 PM »

Hi,


I have included photos of the mockup, exploded assembly and testing of the IR functionality of the Wii Mouse Pen for your information.


Thanks.
*
Karma: +2/-0
: 64
Offline Offline
« #3 : July 03, 2011, 10:08:23 PM »

Hi,


I am still refining the GlovePie software and the implementation of mouse button commands for the Wii Mouse Pen.

It will basically use the same GlovePie Wii Whiteboard Software I previously wrote.

The calibration of the screen corners will be the same, however some extra camera view area will be required for detecting the other IR Led when its activated. This will depend on the setup of the Interactive Whiteboard and the way the Pen is used.

Essentially, the software needs to detect when one or two LEDs are displayed. The Wii Remote sorts this out already.

The next critical problem is determining the actual pointer LED when two LEDs are activated. This is a fairly simple problem to solve once the general pen orientation is known in the setup.

The main task is to assign the IR LED indications with the required mouse commands, without them interfering with each other.

The basic mouse commands to be assigned are:

Mouse Pointer

Left Button Press
Left Button Click
Left Button Double Click

Right Button Press
Right Button Click
Right Button Double Click

Some of the mouse commands cannot be mapped directly because the IR Pen operates differently to a conventional mouse.

There may be a work around such as using the Right Mouse Button Press on the Pen, as a Left Mouse Button Press - for drag and drop, or cut and paste as the case may be.

Also, the Right Mouse Button Double Click may be used for something as this does not seem to be normally used.



Thanks.

« : July 03, 2011, 10:13:22 PM zainey »
*
Karma: +2/-0
: 64
Offline Offline
« #4 : September 09, 2011, 05:17:41 AM »

Hi,

I have written and tested the final GlovePie software for the Dual IR LED IWB Wii Mouse Pen.

Although this specific Dual IR LED, Rocker Switch, Mouse Pen is required for it to work, the aim is to show that a Dual IR Led Interactive Whiteboard Pen can be made to work.

The software was more complicated to develop than I anticipated, and I am sure others will encounter the same difficulties and challenges to make this basically simple concept work. 

Thanks for your interest.

*
Karma: +2/-0
: 64
Offline Offline
« #5 : September 09, 2011, 05:23:04 AM »

//

// GLOVEPIE INTERACTIVE WHITEBOARD SOFTWARE
// FOR DUAL IR LED ROCKER SWITCH MOUSE PEN (or equivalent) with WII REMOTE SENSOR

// Version 2.0 - Released for Publication
// Friday 9 September 2011
// By M.A.V. Brisbane, Australia

// DUAL IR LED ROCKER SWITCH MOUSE PEN details originally published at:
//   http://www.wiimoteproject.com/ir-pens/dual-ir-led-iwb-wii-mouse-pen/

// PROGRAMMED IN GLOVEPIE VERSION 0.43 WITH 32-bit WINDOWS XP3 ON X86 INTEL PC

// Particular thanks to Carl Kenner (GlovePIE) and Nintendo (Wii Remote)
//   and thanks to the Many Others for your technical contributions and inspirations

// MATHEMATICS OF PERSPECTIVE PROJECTION based on:

// SOURCE 1:
// http://www1.cs.columbia.edu/~belhumeur/courses/compPhoto/heckbert-proj.pdf
// Citation:
// "Fundamentals of Texture Mapping and Image Warping"
// Paul Heckbert
// pp 17-21, Master’s thesis, UCB/CSD 89/516, CS Division, U.C. Berkeley, June 1989.

// SOURCE 2:
// http://www.decew.net/OSS/References/Quadrilateral%20mapping.pdf
// Citation:
// "A Planar Perspective Image Matching using Point Correspondences and Rectangle-to-Quadrilateral Mapping,"
// Dong-Keun Kim, Byung-Tae Jang, Chi-Jung Hwang,
// ssiai, pp.0087, Fifth IEEE Southwest Symposium on Image Analysis and Interpretation, 2002

//NOTE: For consistency with convention, the co-ordinate origin for the Wii IR CAMERA Image and CURSOR Screen, is the TOP LEFT CORNER.
//The X-axis points rightward and the Y-axis is inverted and points downward
//This requires a corrective Y-axis transformation for the wiimote IR Image points:  wiimote.dot1y -> 768 - wiimote.dot1y

// DONE LIST
// DONE - TEST CALIBRATION TARGETS
// DONE - TEST VIEW OF SCREEN CORNERS BY WII REMOTE CAMERA
// DONE - TEST TRACKING AREA UTILISATION
// DONE - TEST BATTERY LEVEL
// DONE - TEST REAL DUAL LED TWO BUTTON MOUSE PEN
// DONE - TEST INTEGRATION OF RIGHT BUTTON and LEFT BUTTON MOUSE COMMANDS USING SINGLE AND DUAL LED INDICATION
// DONE - TEST DRAG & DROP + CUT & PASTE
// DONE - TEST MINIMISING THE GLOVEPIE SET-UP SCREEN TO THE TRAY WITH PEN DOUBLE CLICK
// DONE - MAP OUT THE CONFIGURATION OF THE PEN MOUSE BUTTONS AND ROCKER SWITCH POSITIONS CORRESPONDING TO THE ACTUAL MOUSE OUTPUT COMMANDS
// DONE - TEST DYNAMIC MOUSE CLICK SPEED ADJUSTMENT FROM WINDOWS CONTROL PANEL

// FUTURE LIST
// Future - TEST LEFT HANDED OR RIGHT HANDED PEN SELECTION OPTION USING THE INITIAL CALIBRATION AND SET UP SCREEN

// **** LIMITATIONS ****
// Is is essential that both PEN IR LEDS can be detected by the WII REMOTE CAMERA when in use with the WHITEBOARD or other SCREEN
// The software is set up for RIGHT HANDED PEN USE and for the Wii Remote Camera to be seeing the left side of the pen
// The screen must have sufficient diffuse reflectivity so the TIP LED IR LIGHT is readily reflected and can be detected by the Wii Remote Camera
//  - otherwise use a piece of matte single sided tape loosely stuck to the pen tip to act as a tip led reflection surface - it works well
// Be mindful of the pen button mapping with respect to the mouse button actions - including the timeout delay for the pressed button modes
// The software assumes the Wii Remote Camera and Screen are aligned with no significant horizontal roll angle difference
// The pen mouse click speed (Double Click speed) can be manually adjusted by the slider control in the Mouse section of Windows Control Panel


if starting

// LEFT MOUSE BUTTON COMMANDS
 var.pointermode = false

// RIGHT MOUSE BUTTON COMMANDS
 var.rightpressmode = false

// RIGHT HANDED OR LEFT HANDED PEN OPTION
// for left side view of pen - using pen with right hand and pen pointing left on screen
 var.righthandpen = true

// ALTERNATIVELY - for right side view of pen - using pen with left hand - pointing right on screen
// CHANGE: var.righthandpen from '=true' to '=false'

 var.lastmousecommand = '  none    '

// FRAME BUFFERING VARIABLES FOR LED SWITCHING INDICATION
 var.newvis1 = false

 var.newvis2 = false

 var.vis1 = false

 var.vis2 = false

 var.buffercount = 0


// inside screen margin fraction for point calibration
var.screenXmarginratio = 0.1
var.screenYmarginratio = 0.1

var.macrocount = 0

Cam.BgColour = 0xFFFFFF

// Screen calibration points
Cursor10.Visible = false
Cursor11.Visible = false
Cursor12.Visible = false
Cursor13.Visible = false
Cursor14.Visible = false


//Wiimote corner point extents
Cursor30.Visible = false
Cursor31.Visible = false
Cursor32.Visible = false
Cursor33.Visible = false
Cursor34.Visible = false

// Corner direction pointers
Cursor40.Visible = false
Cursor41.Visible = false
Cursor42.Visible = false
Cursor43.Visible = false
Cursor44.Visible = false


Cursor10.Caption = "Click on Centre"
Cursor11.Caption = "Click on Centre"
Cursor12.Caption = "Click on Centre"
Cursor13.Caption = "Click on Centre"


Cursor10.PermanentCursor = 2
Cursor11.PermanentCursor = 2
Cursor12.PermanentCursor = 2
Cursor13.PermanentCursor = 2


Cursor30.PermanentCursor = 2
Cursor31.PermanentCursor = 2
Cursor32.PermanentCursor = 2
Cursor33.PermanentCursor = 2
Cursor34.PermanentCursor = 2

Cursor41.PermanentCursor = -2
Cursor42.PermanentCursor = -2
Cursor43.PermanentCursor = -2
Cursor44.PermanentCursor = -2

var.visibleflag = 1

     // Set WII IR CAMERA FOR MAXIMUM SENSITIVITY
     // Start of Wiimote IR CAMERA Sensistivy Programming block

     // step 1
     // Enable IR Camera (Send 0x04 to Output Report 0x13)
     WiimoteSend(1, 0x13, 0x04)

     wait 100ms

     // step 2
     //Enable IR Camera 2 (Send 0x04 to Output Report 0x1a)
     WiimoteSend(1, 0x1a, 0x04)

     wait 100ms

     // step 3
     //Write 0x08 to register 0x4b00030
     WiimotePoke(1,0x04b00030, 0x08)

     wait 100ms

    // step 4
    //Write Sensitivity Block 1 to registers at 0x4b00000
     WiimotePoke(1,0x04b00000, 0x02)
     wait 100ms
     WiimotePoke(1,0x04b00001, 0x00)
     wait 100ms
     WiimotePoke(1,0x04b00002, 0x00)
     wait 100ms
     WiimotePoke(1,0x04b00003, 0x00)
     wait 100ms
     WiimotePoke(1,0x04b00004, 0x00)
     wait 100ms
     WiimotePoke(1,0x04b00005, 0x00)
     wait 100ms
     WiimotePoke(1,0x04b00006, 0xFF)
     wait 100ms
     WiimotePoke(1,0x04b00007, 0x00)
     wait 100ms
     // maximimu sensitivity setting - 0xc0
     WiimotePoke(1,0x04b00008, 0xc0)

     wait 100ms

     //step 5
     //Write Sensitivity Block 2
     WiimotePoke(1,0x04b0001a, 0x40)

     wait 100ms
     WiimotePoke(1,0x04b0001b, 0x00)

     wait 100ms
    //step 6
    // Write Mode Number to register 0xb00033
    WiimotePoke(1,0x04b00033, 0x01)

    wait 100ms

    //step 7
    // Write 0x08 to register 0x4b00030 (again)
    WiimotePoke(1,0x04b00030, 0x08)

    wait 100ms
    // END of Wiimote IR CAMERA Sensistivy Programming block


end if  // starting


// DYNAMICALLY ADJUSTIBLE MOUSE CLICK SPEED TIMING
// CHANGE THE MOUSE CLICK SPEED IN THE WINDOWS CONTROL PANEL WHILST THIS PROGRAM IS RUNNING
// Open the VARIABLES Menu in GlovePIE or view the debug box status display to view the current mouse speed setting

// Pen mouse clicking time is set relative to the system mouse clicking time
// so as to lock-in the synchronisation of switching commands in the case structure

// POINTER BUTTON PRESSING NEEDS A NEGATIVE TIME DELAY TO BLOCK INCIDENTAL SINGLE CLICK FIRING IN THE CASE STRUCTURE - DO NOT MAKE POSITIVE
var.pointerinitiatetime = Mouse.DoubleClickTime - 20ms

var.pointerextendtime = Mouse.DoubleClickTime + 750ms


// CONTEXT BUTTON PRESSING NEEDS A NEGATIVE TIME DELAY TO BLOCK INCIDENTAL SINGLE CLICK FIRING IN THE CASE STRUCTURE - DO NOT MAKE POSITIVE
var.rightpressinitiatetime = Mouse.DoubleClickTime - 20ms

var.rightpressextendtime = Mouse.DoubleClickTime + 750ms


// WIIMOTE CAMERA CALIBRATION POINTS Module
// CALIBRATION - FOUR CORNER POINTS - LESS MARGIN

// TOP LEFT SCREEN POINT
if  var.macrocount == 0

Cursor10.Visible = true


var.px0 = Screen.Width  * var.screenXmarginratio
var.py0 = Screen.Height * var.screenYmarginratio


Cursor10.PosX =  var.px0
Cursor10.PosY =  var.py0

         if wiimote.dot1vis == true

               //WIIMOTE POINT 1 CAPTURE

                var.x0 = wiimote.dot1x + 0.5
                var.y0 = 767.5 - wiimote.dot1y

                Cursor10.PermanentCursor = 12
                Cursor10.Caption = "DONE"
                wait 1s
                var.macrocount = 1

                //debug =  var.x0 +  '   '  +  var.y0
                //wait 10s

                wait 0.5s

         end if

end if // point 1 calibrationr


// TOP RIGHT SCREEN POINT
if  var.macrocount == 1

Cursor11.Visible = true

var.px1 = Screen.Width  * (1 - var.screenXmarginratio )
var.py1 = Screen.Height * var.screenYmarginratio

Cursor11.PosX =  var.px1
Cursor11.PosY =  var.py1

        if wiimote.dot1vis == true

            //WIIMOTE POINT 2 CAPTURE

             var.x1 = wiimote.dot1x + 0.5
             var.y1 = 767.5 - wiimote.dot1y

             Cursor11.PermanentCursor = 12
             Cursor11.Caption = "DONE"
             wait 1s
             var.macrocount = 2

             //debug =  var.x1 +  '   '  +  var.y1
             //wait 10s

             wait 0.5s

         end if


end if  // point 2 calibration

// BOTTOM RIGHT SCREEN POINT
if  var.macrocount == 2

Cursor12.Visible = true

var.px2 = Screen.Width  * (1 - var.screenXmarginratio )
var.py2 = Screen.Height * (1 - var.screenYmarginratio )


Cursor12.PosX =  var.px2
Cursor12.PosY =  var.py2

        if wiimote.dot1vis == true

              //WIIMOTE POINT 3 CAPTURE

              var.x2 = wiimote.dot1x + 0.5
              var.y2 = 767.5 - wiimote.dot1y

              Cursor12.PermanentCursor = 12
              Cursor12.Caption = "DONE"
              wait 1s
              var.macrocount = 3

              //debug =  var.x2 +  '   '  +  var.y2
              //wait 10s

              wait 0.5s

          end if

  end if // point 3 calibration


// BOTTOM LEFT SCREEN POINT
if  var.macrocount == 3

Cursor13.Visible = true

var.px3 = Screen.Width  *  var.screenXmarginratio
var.py3 = Screen.Height * (1 - var.screenYmarginratio )


Cursor13.PosX =  var.px3
Cursor13.PosY =  var.py3
  
          if wiimote.dot1vis == true

                //WIIMOTE POINT 4 CAPTURE

                var.x3 = wiimote.dot1x + 0.5
                var.y3 = 767.5 - wiimote.dot1y

                Cursor13.PermanentCursor = 12
                Cursor13.Caption = "DONE"
                wait 1s
                var.macrocount = 4

                //debug =  var.x3 +  '   '  +  var.y3
                //wait 10s

                wait 0.5s

            end if

end if // point 4 calibration

// Terminate Calibration Screen
if  var.macrocount == 4

     var.px4 = Screen.Width/2 - 350
     var.py4 = Screen.height/2 - 200

     Cursor14.PosX =  var.px4
     Cursor14.PosY =  var.py4

     wait 1s
     var.macrocount = 5

     // Screen calibration points
     Cursor10.Visible = false
     Cursor11.Visible = false
     Cursor12.Visible = false
     Cursor13.Visible = false
     Cursor14.Visible = false

     wait 1s

end if // end macrocount 4 : four point calibration complete

//END OF WIIMOTE CAMERA CALIBRATION POINTS Module

« : September 09, 2011, 06:36:18 AM zainey »
*
Karma: +2/-0
: 64
Offline Offline
« #6 : September 09, 2011, 05:25:30 AM »

// HOMOGRAPHY MODULE
// GENERAL NOTE: Glovepie works with row vectors and matrix post-multiplication convention
// [row vectors] = Transpose[column vectors]
// Column vector format: [A][C][D] transpose[vector] <=> Glovepie Row vector format: [vector].transpose[D].transpose[C].transpose[A]


if var.macrocount == 5
// Do homography matrix calculation once

// solving unit square to quadrilateral homography matrix with 4 corresponding point pairs
// row vector format Hs->q = [a d g, b e h, c  f  1 ]

// determining parameters g and h

// coefficients of simultaneous linear equations in g and h

var.xk1 = var.x1 - var.x2

var.xk2 = var.x3 - var.x2

var.xk3 = var.x0 - var.x1 + var.x2 - var.x3


var.yk1 = var.y1 - var.y2

var.yk2 = var.y3 - var.y2

var.yk3 = var.y0 - var.y1 + var.y2 - var.y3

// solving the simultaneous linear equations for g and h using cramers rule

var.g = ( var.xk3 *  var.yk2 -  var.yk3 * var.xk2 ) / (  var.xk1 * var.yk2 -  var.yk1 * var.xk2 )

var.h = ( var.xk1 *  var.yk3 -  var.yk1 * var.xk3 ) / (  var.xk1 * var.yk2 -  var.yk1 * var.xk2 )


// solving remaining linear equations for parameters a to f, given g and h

var.a = var.x1 - var.x0 + var.g * var.x1

var.b = var.x3 - var.x0 + var.h * var.x3

var.c = var.x0

var.d = var.y1 - var.y0 + var.g * var.y1

var.e = var.y3 - var.y0 + var.h * var.y3

var.f = var.y0

//Unit Square to Quadrilateral Homography
// row vector format Hs->q = [a d g, b e h, c  f  1 ]

var.UnitSquareToQuad = [ var.a , var.d , var.g ; var.b , var.e , var.h ; var.c , var.f , 1 ]

// Solving quad to unit square homography by inverting unit square to quadrilateral homography matrix
// CALCULATE ADJOINT MATRIX only and ignore determinant calculation

  var.ADJ =  [0,0,0;0,0,0;0,0,0]


  var.ADJ[1,1] =   var.e - var.f * var.h

  var.ADJ[1,2] =   var.f * var.g - var.d

  var.ADJ[1,3] =   var.d * var.h - var.e * var.g

  var.ADJ[2,1] =   var.c * var.h - var.b

  var.ADJ[2,2] =   var.a - var.c * var.g

  var.ADJ[2,3] =   var.b * var.g - var.a * var.h

  var.ADJ[3,1] =   var.b * var.f - var.c * var.e

  var.ADJ[3,2] =   var.c * var.d - var.a * var.f

  var.ADJ[3,3] =   var.a * var.e - var.b * var.d


// HOMOGRAPHY
// Quadrilateral to Rectangular homography matrix via Unit Square transformation
// row vector format
// Hq->r = [Hs->q]^-1 . [Ss->r] . [Ts->r]


// Calculate unit square to rectangular scaling matrix
// row vector format
// Ss->r = [Sx 0 0, 0 Sy 0, 0  0  1 ]

var.Scale = [1,0,0;0,1,0;0,0,1]

var.Scale[1,1] = Screen.Width * ( 1 - 2* var.screenXmarginratio )

var.Scale[2,2] = Screen.Height * ( 1 - 2 * var.screenYmarginratio )

//okay
//debug = var.Scale

// Calculate origin translation for scaled rectangular matrix
// row vector format
// Ts->r = [1 0 0, 0 1 0, Xs->r  Ys->r  1 ]

var.Translate = [1,0,0;0,1,0;0,0,1]

// translation for new x0,y0 = 0,0

var.Translate[3,1] = Screen.Width * var.screenXmarginratio
var.Translate[3,2] = Screen.Height * var.screenYmarginratio

// Calculate net unit square scaling and translation to rectangle matrix
var.ScaleTranslate = var.Scale * var.Translate

//okay
//debug = var.ScaleTranslate

var.QuadToRect = var.ADJ * var.ScaleTranslate

//okay
//debug = var.QuadToRect


var.macrocount = 6
wait 1s

  end  // end macrocount 5 : homography calculation complete


// RECTANGLE TO QUADRILATERAL MAPPING FOR CORNER POINTS

// Calculate Rectangular to Quadrilateral homography matrix via Unit Square transformation
// row vector format
// Hr->q = [Tr->s].[Sr->s].[Hs->q].


if   var.macrocount == 6

// Calculate origin translation matrix for rectangle to unit square
// row vector format
// Tr->s = Inverse[Ts->r] = [1 0 0, 0 1 0, -(Xs->r) -(Ys->r)  1 ]

var.InverseTranslate = [1,0,0;0,1,0;0,0,1]

// translation for new x0,y0 = 0,0

var.InverseTranslate[3,1] = 0 - ( Screen.Width * var.screenXmarginratio )
var.InverseTranslate[3,2] = 0 - ( Screen.Height * var.screenYmarginratio )



// Calculate scaling matrix for rectangle to unit square
// row vector format
// Sr->s = Inverse[Ss->r] = [ 1/Sx 0 0, 0 1/Sy 0, 0  0  1 ]

var.InverseScale = [1,0,0;0,1,0;0,0,1]

var.InverseScale[1,1] = (1 / ( Screen.Width * ( 1 - 2* var.screenXmarginratio ) )  )

var.InverseScale[2,2] = (1 / ( Screen.Height * ( 1 - 2 * var.screenYmarginratio ) ) )

// Calculate net rectangle to unit square translation and scaling matrix
var.TranslateScale = var.InverseTranslate * var.InverseScale

//debug = var.TranslateScale

var.RectToQuad = var.TranslateScale * var.UnitSquareToQuad

// BACK PLOTTING SCREEN RECTANGLE TO WII CAMERA IMAGE QUADRILATERAL FOR CHECKING SCREEN CORNER POINT VISIBILITY TO WIIMOTE
// TOP-LEFT QUAD CORNER
var.testextent1 = [0 , 0 ,1] *  var.RectToQuad

// TOP-RIGHT QUAD CORNER
var.testextent2 = [Screen.Width , 0 ,1] *  var.RectToQuad
//var.testextent2 = [1280 , 0 ,1] *  var.RectToQuad

// BOTTOM-RIGHT QUAD CORNER
var.testextent3 = [Screen.Width , Screen.Height ,1] *  var.RectToQuad
//var.testextent3 = [1280 , 960 ,1] *  var.RectToQuad

// BOTTOM-LEFT QUAD CORNER
var.testextent4 = [0 , Screen.Height ,1] *  var.RectToQuad
//var.testextent4 = [0 , 960 ,1] *  var.RectToQuad

//NOTE: WII CAMERA VIEW OF CORNER POINTS ARE SHOWN AT ITS NATIVE 4:3 ASPECT RATIO, REGARDLESS OF WIDESCREEN DISPLAY ASPECT RATIO
//NORMALISED TO SCREEN HEIGHT, ASSUMES SQUARE PIXELS AND LANDSCAPE MODE
//Corner Point 1 - Top Left
var.wte1 = var.testextent1[3]
var.ute1 = var.testextent1[1]/var.wte1
var.vte1 = var.testextent1[2]/var.wte1

// debug =  var.ute1 + '   ' + var.vte1

//Cursor31.PosX = var.ute1/1024 * Screen.Width
Cursor31.PosX = var.ute1/1024 * Screen.Height * 4 / 3  + Screen.Width/2 - 2/3 * Screen.Height
Cursor31.PosY = var.vte1/768 * Screen.Height

Cursor31.Caption = "( 0 , 0 )"
Cursor31.roll = 45
Cursor31.Visible = true

//Corner Point 2 - Top Right
var.wte2 = var.testextent2[3]
var.ute2 = var.testextent2[1]/var.wte2
var.vte2 = var.testextent2[2]/var.wte2

//debug =  var.ute2 + '   ' + var.vte2

//Cursor32.PosX = var.ute2/1024 * Screen.Width
Cursor32.PosX = var.ute2/1024 * Screen.Height * 4/3  + Screen.Width/2 - 2/3 * Screen.Height
Cursor32.PosY = var.vte2/768 * Screen.Height

Cursor32.Caption = "( 1 , 0 )"
Cursor32.roll = 45
Cursor32.Visible = true

//Corner Point 3 - Bottom Right
var.wte3 = var.testextent3[3]
var.ute3 = var.testextent3[1]/var.wte3
var.vte3 = var.testextent3[2]/var.wte3

//debug =  var.ute3 + '   ' + var.vte3

//Cursor33.PosX = var.ute3/1024 * Screen.Width
Cursor33.PosX = var.ute3/1024 * Screen.Height * 4/3 + Screen.Width/2 - 2/3 * Screen.Height
Cursor33.PosY = var.vte3/768 * Screen.Height

Cursor33.Caption = "( 1 , 1 )"
Cursor33.roll = 45
Cursor33.Visible = true

//Corner Point 4 - Bottom Left
var.wte4 = var.testextent4[3]
var.ute4 = var.testextent4[1]/var.wte4
var.vte4 = var.testextent4[2]/var.wte4

//debug =  var.ute3 + '   ' + var.vte3

//Cursor34.PosX = var.ute4/1024 * Screen.Width
Cursor34.PosX = var.ute4/1024 * Screen.Height * 4/3 + Screen.Width/2 - 2/3 * Screen.Height
Cursor34.PosY = var.vte4/768 * Screen.Height

Cursor34.Caption = "( 0 , 1 )"
Cursor34.roll = 45
Cursor34.Visible = true


var.diagonalangle = atan( Screen.Height/Screen.Width)

Cursor41.Roll = var.diagonalangle - 90
Cursor42.Roll = 90 - var.diagonalangle
Cursor43.Roll = 90 + var.diagonalangle
Cursor44.Roll = 0 - 90 - var.diagonalangle


var.macrocount = 7
wait 1s

end if  // end macrocount 6


//CHECKING SCREEN CORNER POINT VISIBILITY IN WIIMOTE CAMERA - FOR SINGLE POINTER LED ONLY !!!
if var.macrocount == 7

// testing screen top left corner point visibility

if (var.ute1 < 0) or (var.ute1 > 1024) or (var.vte1 < 0) or (var.vte1 > 768)

    Cursor41.PermanentCursor = -2
    Cursor41.PosX = Screen.Width*0.1
    Cursor41.Posy = Screen.Height*0.1
    Cursor41.Caption = ""

    Cursor41.Visible = true

    var.visibleflag = 0
    wait 0.5s

end if


// testing screen top right corner point visibility

if (var.ute2 < 0) or (var.ute2 > 1024) or (var.vte2 < 0) or (var.vte2 > 768)

    Cursor42.PermanentCursor = -2
    Cursor42.PosX = Screen.Width*0.9
    Cursor42.Posy = Screen.Height*0.1
    Cursor42.Caption = ""

    Cursor42.Visible = true

    var.visibleflag = 0
    wait 0.5s

end if

// testing screen bottom right corner point visibility

if (var.ute3 < 0) or (var.ute3 > 1024) or (var.vte3 < 0) or (var.vte3 > 768)

    Cursor43.PermanentCursor = -2
    Cursor43.PosX = Screen.Width*0.9
    Cursor43.Posy = Screen.Height*0.9
    Cursor43.Caption = ""

    Cursor43.Visible = true

    var.visibleflag = 0
    wait 0.5s

end if

// testing screen bottom left corner point visibility

if (var.ute4 < 0) or (var.ute4 > 1024) or (var.vte4 < 0) or (var.vte4 > 768)

    Cursor44.PermanentCursor = -2
    Cursor44.PosX = Screen.Width*0.1
    Cursor44.Posy = Screen.Height*0.9
    Cursor44.Caption = ""

    Cursor44.Visible = true

    var.visibleflag = 0
    wait 0.5s

end if


var.macrocount = 8
wait 1s

end if // end macrocount 7 : Screen quadrilateral visibilty for wii remote camera


if var.macrocount == 8

if var.visibleflag == 1

    Cursor14.PermanentCursor = -2
    Cursor14.PosX =  Screen.Width/2 - 200
    Cursor14.Caption = "Whiteboard 4 Point Calibration Complete - All corner points of screen are visible to the Wiimote"
    Cursor14.Visible = true

    //Calculate tracking utilisation

    var.diagonal1 = [(var.ute3 - var.ute1),(var.vte3 - var.vte1)]

    var.diagonal2 = [(var.ute4 - var.ute2),(var.vte4 - var.vte2)]

    var.WiiCamQuadPixelArea = 0.5 * | (var. diagonal1 x var. diagonal2) |

    var.WiiCamSensorPixelArea = 1024 * 768

    var.trackutilisation = Int(var.WiiCamQuadPixelArea / var.WiiCamSensorPixelArea * 100 )

    var.batterylevel =  Int(wiimote.Battery/1.92)

    debug = 'Tracking utilisation = ' + var.trackutilisation + ' %     '   +  'Battery Level = ' +  var.batterylevel + ' %     '  +  'Maximum Pen Click Time Interval = ' +  var.pointerinitiatetime + '    (This can be adjusted dynamically with Windows Control Panel open)  '

    wait 10s

    var.macrocount = 9


else

    Cursor14.PermanentCursor = 12
    Cursor14.PosX =  Screen.Width/2 - 400
    Cursor14.Caption = " WARNING  -  The indicated Far Corner Point of screen is out of Camera view.  Please adjust the Wii Remote position and recalibrate."
    Cursor14.Visible = true

    debug = 'Tracking utilisation is NOT APPLICABLE   '   +  'Battery Level = ' +  var.batterylevel + ' %'

    wait 10s

end if //  all corner points visible to IR camera ... proceed to whiteboard


wait 1s

end if // end macrocount 8


if var.macrocount == 9

debug = 'Tracking utilisation = ' + var.trackutilisation + ' %     '   +  'Battery Level = ' +  var.batterylevel + ' %     '  +  'Maximum Pen Click Time Interval = ' +  var.pointerinitiatetime + '    (This can be adjusted dynamically with Windows Control Panel open)  '

Cursor14.PosX =  Screen.Width/2 - 100
Cursor14.Caption = "Double-Click Pen on Screen to minimise GlovePie to tray"

        if DoubleClicked(wiimote.dot1vis)

           Cursor14.Caption = "Minimising GlovePie .... please wait "

           MinimizePie

           // Screen calibration points
           Cursor10.Visible = false
           Cursor11.Visible = false
           Cursor12.Visible = false
           Cursor13.Visible = false
           Cursor14.Visible = false


           //Wiimote corner point extents
           Cursor30.Visible = false
           Cursor31.Visible = false
           Cursor32.Visible = false
           Cursor33.Visible = false
           Cursor34.Visible = false

           // Corner direction pointers
           Cursor40.Visible = false
           Cursor41.Visible = false
           Cursor42.Visible = false
           Cursor43.Visible = false
           Cursor44.Visible = false

           wait 1s

           var.macrocount = 10

           wait 1s

         end if // minimise glovepie

end if // end macrocount 9
« : September 09, 2011, 09:03:47 PM zainey »
*
Karma: +2/-0
: 64
Offline Offline
« #7 : September 09, 2011, 05:36:36 AM »

// DUAL LED MOUSE PEN INDICATION AND CONTROL

if var.macrocount == 10


         // ISOLATE WIIMOTE to one read for case structure
         // may not be necessary
         if wiimote.dot1vis

              var.newvis1 = true

              var.dot1x =  wiimote.dot1x
              var.dot1y =  wiimote.dot1y

          else

              var.newvis1 = false

          end


          if wiimote.dot2vis

              var.newvis2 = true

              var.dot2x =  wiimote.dot2x
              var.dot2y =  wiimote.dot2y


          else

              var.newvis2 = false

          end

          // next frame comparison only
          // visible dots transition detection filter
          if ((delta(var.newvis1) == 0) AND  (delta(var.newvis2) == 0) )


               //to eliminate incompleted intermediate state transitions over more than one frame
               if var.buffercount >= 2

                    var.vis1 =  var.newvis1
                    var.vis2 =  var.newvis2

                    // START of LEFT PEN BUTTON mouse commands  ( SINGLE LED )

                    // LEFT MOUSE BUTTON DOUBLE CLICK
                    if (NOT var.rightpressmode) AND DoubleClicked( var.vis1 AND NOT var.vis2 AND NOT var.pointermode )

                            var.dotvx =  var.dot1x
                            var.dotvy =  var.dot1y

                            var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                            var.wout = var.rectout[3]
                            var.uout = var.rectout[1]/var.wout
                            var.vout = var.rectout[2]/var.wout

                            // no pointer smoothing on clicking
                            mouse.CursorPosX = var.uout
                            mouse.CursorPosY = var.vout

                            // no such function available - DoubleClick(Mouse.LeftButton)
                            Press(Mouse.LeftButton)
                            Release(Mouse.LeftButton)
                            Press(Mouse.LeftButton)
                            Release(Mouse.LeftButton)

                            var.lastmousecommand = 'Double Left click '

                            debug = '1. Last Command  =  ' + var.lastmousecommand


                    // POINTER MODE - TERMINATION
                    else if (NOT var.rightpressmode) AND (var.pointermode AND helddown( Not ( var.vis1 AND NOT var.vis2) , var.pointerextendtime ) )

                           var.pointermode = false

                           var.lastmousecommand = 'Pointer RELEASED'

                           debug = '2. Last Command  =  ' + var.lastmousecommand

                    // POINTER MODE - ACTIVATION
                    else if (NOT var.rightpressmode) AND (var.pointermode OR helddown(  var.vis1 AND NOT var.vis2 , var.pointerinitiatetime ) )

                           var.pointermode = true

                           // Mouse Pointer Only - No Mouse Command issued

                           // FOR POINTER MODE TIMEOUT WITH OVERLAPPING RIGHT PEN BUTTON INDICATION

                           if var.vis1 AND var.vis2

                                if  var.righthandpen  // Wii Camera view to left side of left pointing pen

                                   if  var.dot2x > var.dot1x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // right hand pen use pointer end sensing

                                else  // Wii Camera view to right side of right pointing pen

                                   if var.dot1x > var.dot2x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // left hand pen use pointer end sensing

                                end // pen pointer end sensing from different Wii Camera side view

                           else

                               var.dotvx =  var.dot1x
                               var.dotvy =  var.dot1y

                           end

                           // end pointer LED selection and timeout section

                           var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                           var.wout = var.rectout[3]
                           var.uoutLP = var.rectout[1]/var.wout
                           var.voutLP = var.rectout[2]/var.wout

                           //some smoothing optional
                           mouse.CursorPosX = smooth(var.uoutLP, 1)
                           mouse.CursorPosY = smooth(var.voutLP, 1)

                           var.lastmousecommand = 'Pointer PRESSED'

                           debug = '3. Last Command  =  ' + var.lastmousecommand


                    // LEFT MOUSE BUTTON SINGLE CLICK
                    // NOTE: Pointermode caught before this case - no pointer mode preconditioning required

                    else if (NOT var.rightpressmode) AND SingleClicked( var.vis1 AND NOT var.vis2)

                           var.dotvx =  var.dot1x
                           var.dotvy =  var.dot1y

                           var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                           var.wout = var.rectout[3]
                           var.uout = var.rectout[1]/var.wout
                           var.vout = var.rectout[2]/var.wout

                           // no pointer smoothing on clicking
                           mouse.CursorPosX = var.uout
                           mouse.CursorPosY = var.vout

                           // no such function available - SingleClick(Mouse.LeftButton)
                           Press(mouse.LeftButton)
                           Release(Mouse.LeftButton)

                           var.lastmousecommand = 'Single Left click'

                           debug = '4. Last Command  =  ' + var.lastmousecommand


                    // START of RIGHT PEN BUTTON mouse commands  ( DUAL LED )

                    // RIGHT MOUSE BUTTON DOUBLE CLICK - IS OPTIONAL AS IT IS NOT REALLY NEEDED

                    else if DoubleClicked( var.vis1 AND var.vis2 AND NOT var.rightpressmode )

                           if  var.righthandpen  // Wii Camera view to left side of left pointing pen

                                   if  var.dot2x > var.dot1x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // right hand pen use pointer end sensing

                           else  // Wii Camera view to right side of right pointing pen

                                    if var.dot1x > var.dot2x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // left hand pen use pointer end sensing

                           end // pen pointer end sensing from different Wii Camera side view


                           var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                           var.wout = var.rectout[3]
                           var.uout = var.rectout[1]/var.wout
                           var.vout = var.rectout[2]/var.wout

                           // no pointer smoothing on dounle clicking
                           mouse.CursorPosX = var.uout
                           mouse.CursorPosY = var.vout

                           // no such function available - DoubleClick(Mouse.RightButton)
                           Press(Mouse.RightButton)
                           Release(Mouse.RightButton)
                           Press(Mouse.RightButton)
                           Release(Mouse.RightButton)

                           var.lastmousecommand = 'Double Right click '

                           debug = '5. Last Command  =  ' + var.lastmousecommand

                    // LEFT MOUSE BUTTON PRESS - TERMINATION
                    else if var.rightpressmode AND helddown( Not ( var.vis1 AND var.vis2) , var.rightpressextendtime )

                           var.rightpressmode = false

                           Release(Mouse.LeftButton)

                           var.lastmousecommand = 'Context Button RELEASED'

                           debug = '6. Last Command  =  ' + var.lastmousecommand

                    // LEFT MOUSE BUTTON PRESS - ACTIVATION
                    // ( text and drag/drop modes )
                    else if var.rightpressmode OR helddown(  var.vis1 AND var.vis2 , var.rightpressinitiatetime )

                           if var.vis1 AND var.vis2

                                   if  var.righthandpen  // Wii Camera view to left side of left pointing pen

                                       if  var.dot2x > var.dot1x

                                           var.dotvx =  var.dot1x
                                           var.dotvy =  var.dot1y

                                       else  // led positions swap

                                           var.dotvx =  var.dot2x
                                           var.dotvy =  var.dot2y

                                       end // right hand pen use pointer end sensing

                                   else  // Wii Camera view to right side of right pointing pen

                                       if var.dot1x > var.dot2x

                                          var.dotvx =  var.dot1x
                                          var.dotvy =  var.dot1y

                                       else  // led positions swap

                                          var.dotvx =  var.dot2x
                                          var.dotvy =  var.dot2y

                                       end // left hand pen use pointer end sensing

                                   end // pen pointer end sensing from different Wii Camera side view

                           // ignore single LED detection during right pen button pressmode
                           end


                           var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                           var.wout = var.rectout[3]
                           var.uoutRP = var.rectout[1]/var.wout
                           var.voutRP = var.rectout[2]/var.wout

                           // no pointer smoothing on right pen press mode
                           mouse.CursorPosX = var.uoutRP
                           mouse.CursorPosY = var.voutRP

                           // localise mouse pointer first then issue mouse button press for text highlight or drag modes
                           if not var.rightpressmode

                              Press(Mouse.LeftButton)

                              wait 20ms

                           end if

                           var.rightpressmode = true

                           var.lastmousecommand = 'Context Button PRESSED'

                           debug = '7. Last Command  =  ' + var.lastmousecommand


                    // RIGHT MOUSE BUTTON SINGLE CLICK
                    // NOTE: Rightpress mode caught before this case - no press mode preconditioning required

                    else if SingleClicked( var.vis1 AND var.vis2 )


                           if  var.righthandpen  // Wii Camera view to left side of left pointing pen

                                   if  var.dot2x > var.dot1x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // right hand pen use pointer end sensing

                           else  // Wii Camera view to right side of right pointing pen

                                   if  var.dot1x > var.dot2x

                                       var.dotvx =  var.dot1x
                                       var.dotvy =  var.dot1y

                                   else  // led positions swap

                                       var.dotvx =  var.dot2x
                                       var.dotvy =  var.dot2y

                                   end // left hand pen use pointer end sensing

                           end // pen pointer end sensing from different Wii Camera side view


                           var.rectout = [(var.dotvx + 0.5), (767.5 - var.dotvy), 1] *  var.QuadToRect

                           var.wout = var.rectout[3]
                           var.uout = var.rectout[1]/var.wout
                           var.vout = var.rectout[2]/var.wout

                           // no pointer smoothing on single clicking
                           mouse.CursorPosX = var.uout
                           mouse.CursorPosY = var.vout

                           // no such function available - SingleClick(Mouse.RightButton)
                           Press(Mouse.RightButton)
                           Release(Mouse.RightButton)

                           var.lastmousecommand = 'Single Right click'

                           debug = '8. Last Command  =  ' + var.lastmousecommand


                    end // Left and Right Pen Button command case structure


               else
                    // frame buffer counting for finalising LED indication state

                    var.buffercount = var.buffercount + 1

               end  // LED indication is steady


        else
               // LED indication is transitioning
               var.buffercount = 0

        end // LED transition detection


 end // macro count = 10: this interactive whiteboard macro is normally running


 
// MOUSE BUTTON MAPPING TO LED INDICATION AND PEN ROCKER SWITCH POSITION
//
//Mouse Command -------------------- TIP LED ----- TAIL LED ------ PEN MOUSE EQUIVALENT -------- PEN ROCKER SWITCH POSITION --------
//
//CURSOR POINTER                           X             -              LEFT BUTTON PRESS                  BACKWARD ROCKER PRESS ( ->| )
//
//Left Mouse Button Press                  X             X             RIGHT BUTTON PRESS                 FORWARD ROCKER PRESS  ( |<- )
//
//Left Mouse Button Click                   X             -              LEFT BUTTON CLICK                    BACKWARD ROCKER CLICK  ( -> )
//
//Left Mouse Button Double Click        X             -              LEFT BUTTON DOUBLE CLICK        BACKWARD ROCKER DBL CLICK  ( ->> )
//
//Right Mouse Button Press (Ommitted)   -             -              -                             -
//
//Right Mouse Button Click                  X             X              RIGHT BUTTON CLICK                 FORWARD ROCKER CLICK ( <- )
//
//Right Mouse Button Double Click        X             X             RIGHT BUTTON DOUBLE CLICK     FORWARD ROCKER DBL CLICK ( <<- )
//
//
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//


//
// END OF GLOVEPIE DUAL LED ROCKER SWITCH PEN INTERACTIVE WII REMOTE WHITEBOARD VERSION TWO PROGRAM SCRIPT
//



« : September 09, 2011, 05:44:54 AM zainey »
: [1]
   
 
:  

Clicky Web Analytics