Air Mouse

Lindsay Herron, Javier Ceballos, Joshua Dixon

The Air Mouse is an MBED project that allows you to control the mouse on a Windows PC using motion. The project requires an LSM9DS1 IMU board, and a 5-way Tactile switch. A C# Windows application running on the Windows PC is also required in addition to the C MBED code.

Here is a demo of the mouse:

/media/uploads/jdixon37/tactile.jpg 5-Way Tactile Switch

/media/uploads/jdixon37/imu_rs38FKI.jpg LSM9DS1 IMU

The LSM9DS1 IMU communicates with the MBED via I2C using pins p28 and p27 on the MBED. The 5-way Tactile switch connects to the MBED using pins P7, P8, P9, and P10. The MBED talks with the PC using serial communication over USB.

Here is a schematic for the wiring of the Air Mouse: /media/uploads/jdixon37/air_mouse_mbed_circuit.png

Here is the MBED code:

AirMouse

#include "mbed.h"
#include "LSM9DS1.h"
#include "uLCD_4DGL.h"

DigitalOut led(LED1);

DigitalIn d(p10);
DigitalIn r(p9);
DigitalIn u(p8);
DigitalIn l(p7);

Serial pc(USBTX, USBRX);

float x = 64;
float y = 64;
char buf[40]; //Limited buffer size from limited float below
float left = 0;
float right = 0;
float scrollUp = 0;
float scrollDown = 0;


int main (void)
{
    r.mode(PullUp);
    l.mode(PullUp);
    d.mode(PullUp);
    u.mode(PullUp);

    pc.baud(115200);
    pc.printf("Party Started!!!");

    /// init IMU
    LSM9DS1 IMU(p28, p27, 0xD6, 0x3C);
    IMU.begin();
    if (!IMU.begin()) {
        //pc.printf("Failed to communicate with LSM9DS1.\n");
    }
    IMU.calibrate();
    while(1) {
        while(!IMU.accelAvailable()) {
            pc.printf("Failed Acc\n\r");
        };
        
        if(l == 0){left = 1.0;}else{left = 0.0;}
        if(r == 0){right = 1.0;}else {right = 0.0;}
        if(u == 0){scrollUp = 1.0;}else{scrollUp = 0.0;}
        if(d == 0){scrollDown = 1.0;}else{scrollDown = 0.0;}
        
        
        IMU.readAccel();

        x = IMU.ax;
        y = IMU.ay;
       
        wait(.075);
        sprintf(buf,"%.0f/%.0f/%.0f/%.0f/%.0f/%.0f \n\r",x,y,left,right,scrollUp,scrollDown); //Limit floating point to 1 decimal place (limit buffer size)D

        pc.printf("%s",buf);
        
    }
}

The Windows side C# code was created as a Windows Form Application in Visual Studio

C# Windows code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Runtime.InteropServices;
using System.Windows.Controls;

namespace AirMouse
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
        private const int MOUSEEVENTF_MOVE = 0x0001;
        private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const int MOUSEEVENTF_LEFTUP = 0x0004;
        private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        private const int MOUSEEVENTF_RIGHTUP = 0x0010;
        private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
        
        

        public static void Move(int xDelta, int yDelta)
        {
            mouse_event(MOUSEEVENTF_MOVE, xDelta, yDelta, 0, 0);
        }
        public static void MoveTo(int x, int y)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0);
        }
        public static void LeftClick()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

        public static void LeftDown()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

        public static void LeftUp()
        {
            mouse_event(MOUSEEVENTF_LEFTUP, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

        public static void RightClick()
        {
            mouse_event(MOUSEEVENTF_RIGHTDOWN, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
            mouse_event(MOUSEEVENTF_RIGHTUP, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

        public static void RightDown()
        {
            mouse_event(MOUSEEVENTF_RIGHTDOWN, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

        public static void RightUp()
        {
            mouse_event(MOUSEEVENTF_RIGHTUP, System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y, 0, 0);
        }

     
        public static void Main(string[] args)
        {
            
            int x = 0;
            int oldx = 0;
            int oldy = 0;
            int y = 0;
            int l = 0;
            int r = 0;
            int u = 0;
            int d = 0;
            //Get current Mouse Position
            int currPosX = Cursor.Position.X;
            int currPosY = Cursor.Position.Y;
            //Get Screen Resolution
            int ScreenX = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            int ScreenY = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
           
            int start = 0;
          
            SerialPort myport = new SerialPort("COM8", 115200, Parity.None, 8, StopBits.One);
            myport.Open();
            Console.Write("Port Open\n\r");
            Console.Write("ScreenX = " + ScreenX + "\n\r");
            Console.Write("ScreenY = " + ScreenY + "\n\r");
            
            while (true)
            {
                try
                {

                    String input = myport.ReadLine();
                    //Console.Write("input: " + input + "\n\r");
                    String[] xylrud = input.Split('/');
                    oldx = x;
                    oldy = y;
                    y = int.Parse(xylrud[0]);
                    x = -1*int.Parse(xylrud[1]);
                    r = int.Parse(xylrud[2]);
                    l = int.Parse(xylrud[3]);
                    u = int.Parse(xylrud[4]);
                    d = int.Parse(xylrud[5]);


                    if(u == 1){
                        if ((DateTime.Now.Millisecond - start) > 75)
                        {
                            SendKeys.SendWait("{PGUP}");
                            Console.WriteLine("PageUP\n\r");
                        }
                        start = DateTime.Now.Millisecond;
                       
                    }

                    if(d == 1){
                        if ((DateTime.Now.Millisecond - start) > 75)
                        {
                            SendKeys.SendWait("{PGDN}");
                            Console.WriteLine("PageDown\n\r");
                        }
                        start = DateTime.Now.Millisecond;
                    }


                    if(currPosX < ScreenX && currPosY < ScreenY){
                        if((x > 600 || y > 500 || x < -600 || y < -500)){
                            Move(x/120,y/100);
                        }
                    }

                    if (l == 1){
                        LeftClick();
                        //Console.Write("LEFT CLICK");
                    }
                    if (r == 1)
                    {
                        RightClick();
                        //Console.Write("RIGHT CLICK");
                    }
                }
                catch (Exception)
                {
                    //Console.Write("Something's Wrong");
                }

            }

        }
    }
}


Please log in to post comments.