Wiimote Witheboard(Virtual Touch Screen)
All tutorials created in C# to be posted in here.
6 posts
Page 1 of 1
This is a tutorial that you can connect your wiimote and with a infrared pen used like if your screen
were touch,That with an infrared pen emulate that its a touch screen and the cursor goes where the infrared pen goes because the wiimote locates the cordenades of the infraredpen and sendit by bluetooth to the computer and makes the cursor goes to the location.
you will need:
1)Infrared pen(Bellow i will show you how to do your own)
2)Wiimote controller
3)PC With bluetooth
4)Wiimote Lib Pack(http://www.fileden.com/files/2009/6/29/ ... %20Lib.zip)
How to make your infrared pen
you can Buy it in Radioshack but also you can do it
You will Need
1.Infrared led
2.Push Switch
3.Batery Holder
4.Wire
Here to make your own infra red pen:

How to do the Software
2 forms
Form 1 name =Form1
Form 2 Name = CalibrationForm
First you need in form1:
3 Pictureboxes(1.Calibrate the Ir pen,3.Restart form to search wiimote it have to be at big as the form, 2.Close app)
1 Check box
1 Progressbar
1 Label


Form2:
1 Picturebox (named "pbCalibrate")

Code for Form 1 (This go ON TOP of all Code)
Form1 All code
Code of Form2(Calibrationform(This Go ON THE TOP of the code))
Form 2 (Calibrationform) All code
Here I let you The EXE


This file is hosted off-site.
Here I let you the Source Code


This file is hosted off-site.
were touch,That with an infrared pen emulate that its a touch screen and the cursor goes where the infrared pen goes because the wiimote locates the cordenades of the infraredpen and sendit by bluetooth to the computer and makes the cursor goes to the location.
you will need:
1)Infrared pen(Bellow i will show you how to do your own)
2)Wiimote controller
3)PC With bluetooth
4)Wiimote Lib Pack(http://www.fileden.com/files/2009/6/29/ ... %20Lib.zip)
How to make your infrared pen
you can Buy it in Radioshack but also you can do it
You will Need
1.Infrared led
2.Push Switch
3.Batery Holder
4.Wire
Here to make your own infra red pen:

How to do the Software
2 forms
Form 1 name =Form1
Form 2 Name = CalibrationForm
First you need in form1:
3 Pictureboxes(1.Calibrate the Ir pen,3.Restart form to search wiimote it have to be at big as the form, 2.Close app)
1 Check box
1 Progressbar
1 Label


Form2:
1 Picturebox (named "pbCalibrate")

Code for Form 1 (This go ON TOP of all Code)
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;//for firing keyboard and mouse events (optional)
using System.IO;//for saving the reading the calibration data
using WiimoteLib;
Form1 All code
Code: Select all
//instance of the wii remote
Wiimote wm = new Wiimote();
bool cursorControl = false;
int screenWidth = 1024;//defaults, gets replaced by actual screen size
int screenHeight = 768;
int calibrationState = 0;
float calibrationMargin = .1f;
CalibrationForm cf = null;
Warper warper = new Warper();
float[] srcX = new float[4];
float[] srcY = new float[4];
float[] dstX = new float[4];
float[] dstY = new float[4];
//declare consts for mouse messages
public const int MOUSEEVENTF_MOVE = 0x01;
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;
public const int MOUSEEVENTF_MIDDLEDOWN = 0x20;
public const int MOUSEEVENTF_MIDDLEUP = 0x40;
public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
//declare consts for key scan codes
public const byte VK_TAB = 0x09;
public const byte VK_MENU = 0x12; // VK_MENU is Microsoft talk for the ALT key
public const byte VK_LEFT =0x25;
public const byte VK_UP =0x26;
public const byte VK_RIGHT =0x27;
public const byte VK_DOWN =0x28;
public const int KEYEVENTF_EXTENDEDKEY = 0x01;
public const int KEYEVENTF_KEYUP = 0x02;
//for firing mouse and keyboard events
//imports mouse_event function from user32.dll
[DllImport("user32.dll")]
private static extern void mouse_event(
long dwFlags, // motion and click options
long dx, // horizontal position or change
long dy, // vertical position or change
long dwData, // wheel movement
long dwExtraInfo // application-defined information
);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(int X, int Y);
//imports keybd_event function from user32.dll
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void keybd_event(byte bVk, byte bScan, long dwFlags, long dwExtraInfo);
WiimoteState lastWiiState = new WiimoteState();//helps with event firing
//end keyboard and mouse input emulation variables----------------------------------------
Mutex mut = new Mutex();
public Form1()
{
screenWidth = Screen.GetBounds(this).Width;
screenHeight = Screen.GetBounds(this).Height;
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//add event listeners to changes in the wiiremote
//fired for every input report - usually 100 times per second if acclerometer is enabled
wm.OnWiimoteChanged += new WiimoteChangedEventHandler(wm_OnWiimoteChanged);
//fired when the extension is attached on unplugged
wm.OnWiimoteExtensionChanged += new WiimoteExtensionChanged(wm_OnWiimoteExtensionChanged);
pictureBox2.Hide();
try
{
//connect to wii remote
wm.Connect();
//set what features you want to enable for the remote, look at Wiimote.InputReport for options
wm.SetReportType(Wiimote.InputReport.IRAccel, true);
//read the battery
wm.GetBatteryLevel();
//set wiiremote LEDs with this enumerated ID
int count = wm.GetNumConnectRemotes();
switch (count)
{
case 1:
wm.SetLEDs(true, false, false, false);
break;
case 2:
wm.SetLEDs(false, true, false, false);
break;
case 3:
wm.SetLEDs(false, false, true, false);
break;
case 4:
wm.SetLEDs(false, false, false, true);
break;
case 5:
wm.SetLEDs(true, false, false, true);
break;
case 6:
wm.SetLEDs(false, true, false, true);
break;
case 7:
wm.SetLEDs(false, false, true, true);
break;
case 8:
wm.SetLEDs(true, false, true, true);
break;
case 9:
wm.SetLEDs(false, true, true, true);
break;
case 10:
wm.SetLEDs(true, true, true, true);
break;
default:
wm.SetLEDs(false, false, false, false);
break;
}
}
catch (Exception x)
{
MessageBox.Show("Exception: " + x.Message);
pictureBox2.Show();
}
loadCalibrationData();
}
void wm_OnWiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
//if extension attached, enable it
if(args.Inserted)
wm.SetReportType(Wiimote.InputReport.IRExtensionAccel, true);
else
wm.SetReportType(Wiimote.InputReport.IRAccel, true);
}
void wm_OnWiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
mut.WaitOne();
//extract the wiimote state
WiimoteState ws = args.WiimoteState;
if (ws.IRState.Found1)//move cursor
{
int x = ws.IRState.RawX1;
int y = ws.IRState.RawY1;
float warpedX = x;
float warpedY = y;
warper.warp(x, y, ref warpedX, ref warpedY);
if ((x != lastWiiState.IRState.RawX1) || (y != lastWiiState.IRState.RawY1))
{
// Cursor.Position = new Point((int)warpedX, (int)warpedY);
// mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 64*x, 64*y, 0, 0);
if (cursorControl)
SetCursorPos((int)warpedX, (int)warpedY);
}
if (!lastWiiState.IRState.Found1)
{//mouse down
lastWiiState.IRState.Found1 = ws.IRState.Found1;
//need to wait for the cursor move event to be processed before doing mouse down
//it would be better to insert it properly in the event queue,but i couldn't get it working right
Thread.Sleep(25);
if (cursorControl)
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
switch (calibrationState)
{
case 1:
srcX[calibrationState - 1] = x;
srcY[calibrationState - 1] = y;
calibrationState = 2;
doCalibration();
break;
case 2:
srcX[calibrationState - 1] = x;
srcY[calibrationState - 1] = y;
calibrationState = 3;
doCalibration();
break;
case 3:
srcX[calibrationState - 1] = x;
srcY[calibrationState - 1] = y;
calibrationState = 4;
doCalibration();
break;
case 4:
srcX[calibrationState - 1] = x;
srcY[calibrationState - 1] = y;
calibrationState = 5;
doCalibration();
break;
default:
break;
}
}
}
else
{
if (lastWiiState.IRState.Found1)//mouse up
{
lastWiiState.IRState.Found1 = ws.IRState.Found1;
if (cursorControl)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
}
if (!lastWiiState.ButtonState.A && ws.ButtonState.A)
{
BeginInvoke((MethodInvoker)delegate() { btnCalibrate.PerformClick(); });
}
lastWiiState.ButtonState.A = ws.ButtonState.A;
if (!lastWiiState.ButtonState.Up && ws.ButtonState.Up)
keybd_event(VK_UP, 0x45, 0, 0);
if (lastWiiState.ButtonState.Up && !ws.ButtonState.Up)
keybd_event(VK_UP, 0x45, KEYEVENTF_KEYUP, 0);
lastWiiState.ButtonState.Up = ws.ButtonState.Up;
if (!lastWiiState.ButtonState.Down && ws.ButtonState.Down)
keybd_event(VK_DOWN, 0x45, 0, 0);
if (lastWiiState.ButtonState.Down && !ws.ButtonState.Down)
keybd_event(VK_DOWN, 0x45, KEYEVENTF_KEYUP, 0);
lastWiiState.ButtonState.Down = ws.ButtonState.Down;
if (!lastWiiState.ButtonState.Left && ws.ButtonState.Left)
keybd_event(VK_LEFT, 0x45, 0, 0);
if (lastWiiState.ButtonState.Left && !ws.ButtonState.Left)
keybd_event(VK_LEFT, 0x45, KEYEVENTF_KEYUP, 0);
lastWiiState.ButtonState.Left = ws.ButtonState.Left;
if (!lastWiiState.ButtonState.Right && ws.ButtonState.Right)
keybd_event(VK_RIGHT, 0x45, 0, 0);
if (lastWiiState.ButtonState.Right && !ws.ButtonState.Right)
keybd_event(VK_RIGHT, 0x45, KEYEVENTF_KEYUP, 0);
lastWiiState.ButtonState.Right = ws.ButtonState.Right;
lastWiiState.IRState.Found1 = ws.IRState.Found1;
lastWiiState.IRState.RawX1 = ws.IRState.RawX1;
lastWiiState.IRState.RawY1 = ws.IRState.RawY1;
lastWiiState.IRState.Found2 = ws.IRState.Found2;
lastWiiState.IRState.RawX2 = ws.IRState.RawX2;
lastWiiState.IRState.RawY2 = ws.IRState.RawY2;
lastWiiState.IRState.Found3 = ws.IRState.Found3;
lastWiiState.IRState.RawX3 = ws.IRState.RawX3;
lastWiiState.IRState.RawY3 = ws.IRState.RawY3;
lastWiiState.IRState.Found4 = ws.IRState.Found4;
lastWiiState.IRState.RawX4 = ws.IRState.RawX4;
lastWiiState.IRState.RawY4 = ws.IRState.RawY4;
//draw battery value on GUI
BeginInvoke((MethodInvoker)delegate() { pbBattery.Value = (ws.Battery > 0xc8 ? 0xc8 : (int)ws.Battery); });
float f = (((100.0f * 48.0f * (float)(ws.Battery / 48.0f))) / 192.0f);
BeginInvoke((MethodInvoker)delegate() { lblBattery.Text = f.ToString("F"); });
//check the GUI check boxes if the IR dots are visible
String irstatus = "Visible IR dots: ";
if (ws.IRState.Found1)
irstatus += "1 ";
if (ws.IRState.Found2)
irstatus += "2 ";
if (ws.IRState.Found3)
irstatus += "3 ";
if (ws.IRState.Found4)
irstatus += "4 ";
BeginInvoke((MethodInvoker)delegate() { lblIRvisible.Text = irstatus; });
mut.ReleaseMutex();
}
public void loadCalibrationData()
{
// create reader & open file
try
{
TextReader tr = new StreamReader("calibration.dat");
for (int i = 0; i < 4; i++)
{
srcX[i] = float.Parse(tr.ReadLine());
srcY[i] = float.Parse(tr.ReadLine());
}
// close the stream
tr.Close();
}
catch (System.IO.FileNotFoundException)
{
//no prexsting calibration
return;
}
warper.setDestination( screenWidth * calibrationMargin,
screenHeight * calibrationMargin,
screenWidth * (1.0f-calibrationMargin),
screenHeight * calibrationMargin,
screenWidth * calibrationMargin,
screenHeight * (1.0f - calibrationMargin),
screenWidth * (1.0f - calibrationMargin),
screenHeight * (1.0f - calibrationMargin));
warper.setSource(srcX[0], srcY[0], srcX[1], srcY[1], srcX[2], srcY[2], srcX[3], srcY[3]);
warper.computeWarp();
cursorControl = true;
BeginInvoke((MethodInvoker)delegate() { cbCursorControl.Checked = cursorControl; });
}
public void saveCalibrationData()
{
TextWriter tw = new StreamWriter("calibration.dat");
// write a line of text to the file
for (int i = 0; i < 4; i++)
{
tw.WriteLine(srcX[i]);
tw.WriteLine(srcY[i]);
}
// close the stream
tw.Close();
}
public void doCalibration(){
if (cf == null)
return;
int x = 0;
int y = 0;
int size = 25;
Pen p = new Pen(Color.Red);
switch (calibrationState)
{
case 1:
x = (int)(screenWidth * calibrationMargin);
y = (int)(screenHeight * calibrationMargin);
cf.showCalibration(x, y, size, p);
dstX[calibrationState - 1] = x;
dstY[calibrationState - 1] = y;
break;
case 2:
x = screenWidth - (int)(screenWidth * calibrationMargin);
y = (int)(screenHeight * calibrationMargin);
cf.showCalibration(x, y, size, p);
dstX[calibrationState - 1] = x;
dstY[calibrationState - 1] = y;
break;
case 3:
x = (int)(screenWidth * calibrationMargin);
y = screenHeight -(int)(screenHeight * calibrationMargin);
cf.showCalibration(x, y, size, p);
dstX[calibrationState - 1] = x;
dstY[calibrationState - 1] = y;
break;
case 4:
x = screenWidth - (int)(screenWidth * calibrationMargin);
y = screenHeight -(int)(screenHeight * calibrationMargin);
cf.showCalibration(x, y, size, p);
dstX[calibrationState - 1] = x;
dstY[calibrationState - 1] = y;
break;
case 5:
//compute warp
warper.setDestination(dstX[0], dstY[0], dstX[1], dstY[1], dstX[2], dstY[2], dstX[3], dstY[3]);
warper.setSource(srcX[0], srcY[0], srcX[1], srcY[1], srcX[2], srcY[2], srcX[3], srcY[3]);
warper.computeWarp();
cf.Dispose();
cf = null;
calibrationState = 0;
cursorControl = true;
BeginInvoke((MethodInvoker)delegate() { cbCursorControl.Checked = cursorControl; });
saveCalibrationData();
break;
default:
break;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//disconnect the wiimote
wm.Disconnect();
}
private void cbCursorControl_CheckedChanged(object sender, EventArgs e)
{
cursorControl = cbCursorControl.Checked;
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (cf == null)
{
cf = new CalibrationForm();
cf.Show();
}
if (cf.IsDisposed)
{
cf = new CalibrationForm();
cf.Show();
}
calibrationState = 1;
doCalibration();
}
private void cb_CheckedChanged(object sender, EventArgs e)
{
cursorControl = cbCursorControl.Checked;
}
private void pictureBox2_Click(object sender, EventArgs e)
{
Application.Restart();
}
private void pictureBox3_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Code of Form2(Calibrationform(This Go ON THE TOP of the code))
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
Form 2 (Calibrationform) All code
Code: Select all
Bitmap bCalibration;
Graphics gCalibration;
int screenWidth = 1024;//defaults
int screenHeight = 768;
public CalibrationForm()
{
Rectangle rect = new Rectangle();
rect = Screen.GetWorkingArea(this);
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.Left = 0;
this.Top = 0;
this.Size = new Size(rect.Width, rect.Height);
this.Text = "Calibration - Working area:" + Screen.GetWorkingArea(this).ToString() + " || Real area: " + Screen.GetBounds(this).ToString();
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyPress);
screenHeight = rect.Height;
screenWidth = rect.Width;
bCalibration = new Bitmap(screenWidth, screenHeight, PixelFormat.Format24bppRgb);
gCalibration = Graphics.FromImage(bCalibration);
pbCalibrate.Left = 0;
pbCalibrate.Top = 0;
pbCalibrate.Size = new Size(rect.Width, rect.Height);
gCalibration.Clear(Color.White);
BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image = bCalibration; });
}
private void OnKeyPress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if ((int)(byte)e.KeyCode == (int)Keys.Escape)
{
this.Dispose(); // Esc was pressed
return;
}
}
public void drawCrosshair(int x, int y, int size, Pen p, Graphics g){
g.DrawEllipse(p, x - size / 2, y - size / 2, size, size);
g.DrawLine(p, x-size, y, x+size, y);
g.DrawLine(p, x, y-size, x, y+size);
}
public void showCalibration(int x, int y, int size, Pen p){
gCalibration.Clear(Color.White);
drawCrosshair(x,y,size, p, gCalibration);
BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image = bCalibration; });
}
private void CalibrationForm_Load(object sender, EventArgs e)
{
}
}
}
Here I let you The EXE


This file is hosted off-site.
Here I let you the Source Code


This file is hosted off-site.
Last edited by nequito on Sat Apr 30, 2011 7:07 pm, edited 2 times in total.
In a few houers I will Upload A video So you can see how it works
You can get most of that source code here: http://cwiimote.googlecode.com/svn/!svn ... imoteTest/
Also what wavelength does the IR diode have to be at?
Also what wavelength does the IR diode have to be at?
Nicely done! My class needed to make the IR pens for a project in school last year.
And mandai, i think any wavelength works, as long as it is IR
And mandai, i think any wavelength works, as long as it is IR
Yes it any wavelength works i have tested with 3 of them but the best is the IR383
6 posts
Page 1 of 1
Copyright Information
Copyright © Codenstuff.com 2020 - 2023