IR Mouse Control

Created By Kristopher Bahar and David Akhigbe on 10-13-2011

GaTech ECE 4180: Embedded Systems Design

Introduction

This project takes in user data from 3 IR sensors, and uses that data to control the cursor pushbuttons as well as controlling left click functionality. Depending on height the user holds his/her hand the cursor will move up and down and depending on the vertical coordinate the cursor will move left or right. An accuracy control was implemented using a push button. This control slowed the cursor down in order to get more finely tuned controls. Another pushbutton represented a left button click.

Parts Required

1 Mbed

2 Pushbuttons using pull-up resistor configuration (10kOhms Resistors are used in the Demo)

3 Sharp Distance Sensors P/N (2Y0A21)

3 IR Distance Adapters P/N 1101

5V Power Supply

Connections

3 Pin Distance Sensor Out Connector -> 3 Pin IR Distance Adapter In Connector

IR Distance Adapter VCC ( Middle Pin) -> 5V Power Supply

IR Distance Adapter Ground (Right Pin) -> Ground

IR Distance Adapter Out (Left Pin)-> Analog In

Pushbuttons ->General Purpose Digital I/O

Demo Video

Other Resources

In creating the C# program which interoperates the data sent to the serial port from the Mbed and in turn controls the mouse functionality, we did not create the software for setting up the serial port; This software was built off a template written by Noah Coad :

http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx

We added in functions to control the serial information sent to computer and changed some of the layout of the GUI.

MBED Code

/* ----------------------------------------------------------------------------------------
Lab 3 - IR Touchpad Design

For this demo, we made a IR mouse sensor that can be controlled with hand gestures.
For our initial testing we would like to use 3 distance sensors in the following locations:

          ^          ^          ^
          |          |          |       Distance Sensors are Facing Upwards
          |          |          |
          |          |          |
      ---------  ---------  ---------
      |  p17  |  |  p18  |  |  p19  | 
      ---------  ---------  ---------

----------------------------------------------------------------------------------------
From this design, we should be able to have relatively unique mouse input with out the need to touch
any surfaces.

This design will use a relative locations to move the mouse.  For example, then your hand is only being
middle sensor and is halfway between the distance maximum of the sensor's capabilites, the mouse will not move.
When your hand moves away from the middle point, it will change the mouse location accordingly.

The Hardware setup for this design is relatively simple, there are three analog distance sensors connected to the MBed's 
Analog input pins as well as two pushbuttons connected to GPIO/DigitalIn pins.  The Three analog distance sensors are 
used to change the position of the mouse, one pushbutton1 is used to control the accuracy of the mouse, and pushbutton2
is used as a left mouse click.

The value of the analog sensors (assuming a static voltage of 0-3.3V) will be set in this program
to have a value 0-1 (represented as a float value).  Thus, in order to get a proper distance for a computer,
we will multiply the values by 100, changing our applicable range to 0-100.

Finally, we created a secondary C# program to handle the serial output sent from the Mbed device.  Regarding this application,
we should note that we did not create the software for setting up the serial port; This software was built off a template written 
by Noah Coad (http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx).
We added in functions to control the serial information sent to computer and changed some of the layout of the GUI.
---------------------------------------------------------------------------------------- */

#include "mbed.h"
AnalogIn    Sen1(p17);
AnalogIn    Sen2(p18);
AnalogIn    Sen3(p19);
DigitalIn   PB1(p21);
DigitalIn   PB2(p22);
DigitalOut  led1(LED1);
DigitalOut  led2(LED2);
Serial      pc(USBTX, USBRX);
float       _Sen1 = 0;
float       _Sen2 = 0;
float       _Sen3 = 0;
int         x=0;        
int         y=0;
int         z=0;
int         PB1Val=0;
int         PB2Val=0;
int         i;

int main() {
    pc.printf("Program Starting!");
    while (1){
    
        x = int(Sen1*100);
        y = int(Sen2*100);
        z = int(Sen3*100);
        PB1Val = PB1;
        PB2Val = PB2;
        
        if(y >= 22)
        {
            if((x >= 22)&&(z <= 22))
            {    
                pc.printf("Sensor 1 and 2 Detected (%u, %u, 0) PB1=%u, PB2=%u\r\n", x, y,PB1Val,PB2Val);
                pc.printf("VAL%u,1,%u,%u\r\n", y,PB1Val,PB2Val);
            }
            else if((z >= 22)&&(x <= 22))
            {
                pc.printf("Sensor 2 and 3 Detected (0, %u, %u) PB1=%u, PB2=%u\r\n", y, z,PB1Val,PB2Val);
                pc.printf("VAL%u,3,%u,%u\r\n", y,PB1Val,PB2Val);
            }
            else
            {
                pc.printf("Sensor 2 Detected Only (0, %u, 0) PB1=%u, PB2=%u\r\n", y,PB1Val,PB2Val);
                pc.printf("VAL%u,0,%u,%u\r\n", y,PB1Val,PB2Val);
            }
        }
        else if(x >= 22)
        {
            pc.printf("Sensor 1 Detected Only (%u, 0, 0) PB1=%u, PB2=%u\r\n", x,PB1Val,PB2Val);
            pc.printf("VAL%u,2,%u,%u\r\n", x,PB1Val,PB2Val);
        }
        else if(z >= 22)
        {
            pc.printf("Sensor 3 Detected Only (0, 0, %u) PB1=%u, PB2=%u\r\n", z,PB1Val,PB2Val);
            pc.printf("VAL%u,4,%u,%u\r\n", z,PB1Val,PB2Val);
        }
        else
        {
            pc.printf("No Input Detected PB1=%u, PB2=%u\r\n",PB1Val,PB2Val);
            pc.printf("VAL00,0,%u,%u\r\n",PB1Val,PB2Val);
        }
        
        _Sen1 = 0;                
        _Sen2 = 0;
        _Sen3 = 0;
        
        if(PB1Val == 0){   //Check the logic level of the digital input (dip switch)
            led1 = 1;      //if "off", turn LED off
        }
        else{
            led1 = 0;      //if "on", turn LED on
        }
        
        if(PB2Val == 0){   //Check the logic level of the digital input (dip switch)
            led2 = 1;      //if "off", turn LED off
        }
        else{
            led2 = 0;      //if "on", turn LED on
        }
    }
}

C# Host Computer Program Function

void ConsoleBuffer(int index){
          if (UsedFlag == 0)
          {
              for (i = UsedIndex; i < data.Length; i++)
              {
                  if (data[i] != 0x56)
                  {
                      dataConsole += data[i];
                  }
                  else
                  {
                      Log(LogMsgType.Incoming, dataConsole);
                      dataConsole = null;
                      UsedFlag = 1;
                      UsedIndex = i;
                      break;
                  }
              }
          }
          if(UsedFlag == 1)
          {
              for (i = UsedIndex; i < data.Length; i++)
              {
                  
                  if (UsedFlag == 0)
                  {
                      //public MouseEventArgs(
                      break;
                  }
                  if (data[i] != 0x0A)
                  {
                      dataUsed += data[i];
                  }
                  else
                  {
                      dataUsed += data[i];
                      //label2.Text = dataUsed;
                      Accuracy = dataUsed[8] - 0x30;
                      MouseClick = dataUsed[10] - 0x30;

                      Yval = (dataUsed[3] - 0x30) * 10;
                      Yval += (dataUsed[4] - 0x30);

                      if (MouseClick == 0)
                      {
                          mouse_event(MOUSEEVENTF_LEFTDOWN, Cursor.Position.X, Cursor.Position.Y, 0, 0);
                      }
                      else
                      {
                          mouse_event(MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);
                      }
                      
                      if (Yval == 0)
                      {
                          Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y);
                          YAccelDn = 0;
                          YAccelUp = 0;
                      }
                      else if (Yval < 55)
                      {
                          if (Accuracy == 0)
                          {
                              Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - 2);
                          }
                          else
                          {
                              Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - 5 - YAccelDn);
                              YAccelDn += 1;
                              if (YAccelDn >= 15)
                              {
                                  YAccelDn = 15;
                              }
                              YAccelUp = 0;
                          }
                      }
                      else if (Yval < 70)
                      {
                          Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y);
                          YAccelDn = 0;
                          YAccelUp = 0;
                      }
                      else
                      {
                          if (Accuracy == 0)
                          {
                              Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + 2);
                          }
                          else
                          {
                              Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + 5 + YAccelUp);
                              YAccelUp += 1;
                              if (YAccelUp >= 15)
                              {
                                  YAccelUp = 15;
                              }
                              YAccelDn = 0;
                          }
                      }

                      int Xconvert = dataUsed[6] - 0x30;
                      switch (Xconvert)
                      {
                          case 0:
                              break;
                          case 1:
                              if (Accuracy == 0)
                              {
                                  Cursor.Position = new Point(Cursor.Position.X - 2, Cursor.Position.Y);
                              }
                              else
                              {
                                  Cursor.Position = new Point(Cursor.Position.X - 3 - XAccelLS, Cursor.Position.Y);
                                  XAccelLS += 1;
                                  if (XAccelLS >= 20)
                                  {
                                      XAccelLS = 20;
                                  }
                                  XAccelLF = 0;
                                  XAccelRF = 0;
                                  XAccelRS = 0;
                              }
                              break;
                          case 2:
                              if (Accuracy == 0)
                              {
                                  Cursor.Position = new Point(Cursor.Position.X - 2, Cursor.Position.Y);
                              }
                              else
                              {
                                  Cursor.Position = new Point(Cursor.Position.X - 5 - XAccelLF, Cursor.Position.Y);
                                  XAccelLS = 0;
                                  XAccelLF += 1;
                                  if (XAccelLF >= 20)
                                  {
                                      XAccelLF = 20;
                                  }
                                  XAccelRF = 0;
                                  XAccelRS = 0;
                              }
                              break;
                          case 3:
                              if (Accuracy == 0)
                              {
                                  Cursor.Position = new Point(Cursor.Position.X + 2, Cursor.Position.Y);
                              }
                              else
                              {
                                  Cursor.Position = new Point(Cursor.Position.X + 3 + XAccelRS, Cursor.Position.Y);
                                  XAccelLS = 0;
                                  XAccelLF = 0;
                                  XAccelRF = 0;
                                  XAccelRS += 1;
                                  if (XAccelRS >= 20)
                                  {
                                      XAccelRS = 20;
                                  }
                              }
                              break;
                          case 4:
                              if (Accuracy == 0)
                              {
                                  Cursor.Position = new Point(Cursor.Position.X - 2, Cursor.Position.Y);
                              }
                              else
                              {
                                  Cursor.Position = new Point(Cursor.Position.X + 5 + XAccelRF, Cursor.Position.Y);
                                  XAccelLS = 0;
                                  XAccelLF = 0;
                                  XAccelRF += 1;
                                  if (XAccelRF >= 20)
                                  {
                                      XAccelRF = 20;
                                  }
                                  XAccelRS = 0;
                              }
                              break;
                      }
                      dataUsed = null;
                      UsedFlag = 0;
                      UsedIndex = i+1;
                  }
              }
          }
      }

Pictures

Setup:

http://i.imgur.com/p8QoQ.jpg

C# Host Program Control

http://i.imgur.com/QYBjv.png


4 comments on IR Mouse Control:

14 Apr 2014

Hello , I am trying to implement the C# code which you have given for IR mouse, but i am not able to track where to paste the code in the serial port terminal application code given by Noah Coad. Please tell me where to paste the given C# code in the code given by Noah Coad.

08 May 2014

please reply.....

08 May 2014

please reply soon.....

13 Feb 2017

any word?

Please log in to post comments.