Head Mouse - Game Controller or Disability Aid

69,014

583

163

Posted in TechnologyArduino

Introduction: Head Mouse - Game Controller or Disability Aid

My kids wanted to have a head controlled mouse for playing Minecraft - they wanted to move their heads and have the field of view move. I decided that was a challenge I couldn't resist, so I decided to build a movement controlled mouse using an arduino and a gyroscope chip.

Components

A-Star 32U4 Micro - a tiny Arduino Leonardo clone

LSM9DS0 Breakout board - a combined gyroscope, accelerometer and magnetometer

A 3.3V to 5V logic level converter

10k resistor

push button switch

strip board

I started off prototyping with an Arduino Uno, and but it doesn't have the ability to be a HID controller at the same time as being able to load the firmware via USB. I tried reading the sensors via the serial port, but that's just not the same as a genuine mouse because you always need a client piece of software running, which isn't elegant, nor is it always convenient. However, the Arduino Leonardo does have the ability to act as a mouse or a keyboard, so I decided to use one of those. In fact, what i decided to use was a clone of that. There is a fantastic clone board called the A-Star 32U4 Micro, which is tiny - just 1" x 0.6", and it's half the price, so it's a winner all round for this project,

For the gyroscope, I chose the LSM9DS0 chip which is a combined gyroscope, accelerometer and magnetometer, giving me the choice of being a bit more sophisticated about detecting movement. I don't have the facility to make my own circuit boards or to surface mount chips, so I bought it on a breakout board.

The LSM9DS0 runs with 3.3V outputs, but the processor needs 5V inputs, so a logic level converter for the SCL and SDA lines is required too.

Finally, it's a good idea to be able to turn the mouse operation of the device on and off without unplugging it - that way if you make a mistake, you can re-program it without the mouse feature running wild.

Step 1: The Circuit

The easiest way to run the LSM9DS0 is on the I2C interface. That allows the microprocessor to talk to it over a simple serial interface, which has standard libraries. To do that, we wire the SDA and SCL pins to the SDA and SCL pins on the 32U4 board, via the logic level converter to change the signals from 3.3V to 5V.

You can periodically poll the LSM9DS0 for data, but to optimally know when there is data, there are three interupt outputs - one for each sensor. They also run at 3.3V, but that is high enough for the 32U4 to treat as a high signal, so there is no need to run those through the logic level converter.

Sparkfun have a fantastic writeup of all of this here;

https://learn.sparkfun.com/tutorials/lsm9ds0-hooku...

The sketch shows the circuit, along with a push switch going to pin 11, with a 10k pull up resistor connected to 5V to stop the pin from floating.

I prototyped the solution on a breadboard first, as shown in the photo.

Step 2: The Code

The sparkfun guys have put together some sample code for using the LSM9DS0, as well as libraries for using the board;

https://github.com/sparkfun/LSM9DS0_Breakout/

After much pain, I found that there's a quirk in the LSM9DS0 which means that it doesn't always return all of the data that you expect it to, so use the attached libraries instead, where the issue is worked round. Without this, you can find the system hanging.

I used the sparkfun example code to get the gyroscope to move the mouse. I combine that with the readings from the accelerometer to detect what way the device is oriented, and translate that in to x and y movements for the mouse. You can find that code in the attached file.

The code expects the device to be on the right hand side of your head. If you want to have it on the left, invert the Y axis calculation, otherwise it will move the mouse down when your head moves up.

The LSM9DS0 doesn't start as fast as the processor, so the code pauses for 1s when it first starts to allow the sensors to come on line. Then I throw away the first 10 readings because the first readings seem to be less accurate.

The accelerometer seems to not say zero when it is stationary (movement of the earth perhaps?), so the code takes an average of readings 10 through 40 when you turn it on, and subtracts those from subsequent readings to make it stable. Make sure the mouse is stable when you plug it in for that reason.

The button is used to pause the mouse interaction, and when it starts again the stationary readings are taken again, so be sure to keep the device steady when starting it up - e.g. put it on the table.

To use the code, create a folder called SFE_LSM9DS0 underneath {install directory}/Adruino/libraries, and put SFE_LSM9DS0.cpp and SFE_LSM9DS0.h in that folder. Then you can open headMouse2.ino and load it to your Arduino.

Step 3: The Build

Next step is to solder it all up on a strip board. It's not as elegant as a custom built PCB, but I love strip board because it's always there ready to use for whatever you want, and you can tinker with it if it doesn't work. It's not particularly elegant (nor is my soldering), but it all works great.

Step 4: Packaging

It's no fun having a bare circuit board strapped to your head, not to mention the risk of static, so it needs to be packaged in something. I considered a altoids tin, but metal isn't the best thing to put this in, plus it's large and uncomfortable. Fortunately, walking too far in new shoes resulted in me to emptying a plastic blister plaster box which was a perfect size for the circuit board (well, after I trimmed down the board with a dremel it was anyway). Plus, it was nice and smooth, and comfortable to have strapped to your head. I cut holes for the USB connector and the button, fixed the circuit board in to place with some sugru, and used a bit of leftover green sugru to make a matching green button top for the case.

I cut a couple of lines in the case and threaded a child's elastic belt through it as an ideal size for a head band, so the device can be comfortably worn on the head.

Step 5: Minecraft

So here it is in action. Crank up minecraft with a first person view, and as you look up and down, Steve looks up and down in the game. Look left and right, and Steve looks left and right. It's uncannily accurate, and brilliant fun to have your real life movements reflected in the game. If you look off the side of the screen, it re-centers when you move back to the middle, so to face a new direction, just move your head left or right past the edge of the screen and then back again.

Yes, you still need to use the mouse buttons to dig and build. Does that defeat the point of the head mouse? No, not at all. It's not about completely ditching the mouse - it's about a more immersive gaming experience.

Step 6: Disability Assistance

The other obvious use for a head mouse is for people with physical disabilities which prevent them from using a mouse. For people with limited mobility, this can be held or attached to any part of your body - move your head, your foot, your arm, anything. The sensitivity of movement can be adjusted in the code to suit any user too, and movements can be averaged to smooth out any body jitters.

The other essential addition for people with physical disabilities (as opposed to immersive gaming) is the need to click the mouse. The solution to that depends on the level of mobility of the user. For example, it's easy to add a foot controlled button that is connected to the Arduino, and call Mouse.click() when that is pressed. When that is not an option, you can rely on "dwell" - i.e. when the mouse pointer has been in a particular area for a period of time, call Mouse.click(). The attached Arduino file does just that - it will look to see the total movement over the past second. If it has moved less than 20 pixels, it will click. If movement is over 20 pixels, it resets the timer. You can edit the file to change the radius that counts as stationary and the dwell time to suit the user.

Step 7: Conclusion

Adding a gyroscope to an Arduino Leonardo gives a huge number of options for controlling your computer. I had a load of fun building it (which, like with many instructables, was mostly the point). But if you think of any other good projects for this sensor, let me know in the comments.

Sensors Contest

First Prize in the
Sensors Contest

Share

Recommendations

  • Make it Move Contest

    Make it Move Contest
  • Woodworking Contest

    Woodworking Contest
  • Casting Contest

    Casting Contest
user

We have a be nice policy.
Please be positive and constructive.

Tips

1 Questions

Hi, I'm trying to build a similar device adn I'm having trouble with the mouse click. I've looked through your code and I can't find or understand the part that click the mouse when you hold your head still.

Are you looking at the second .ino file? There are two - one without clicks and one with. The second one has the following lines for clicking;

if(totalMovement > dwellRadius){

resetLastMousePositions();

} else {

if(lastResetTime<(millis()-dwellTime)){

Mouse.click();

resetLastMousePositions();

// reduce waiting time

lastResetTime=millis()+dwellTime-dwellRepeatTime;

}

}

1 more answer

Yes I found that second file, thank you.

163 Comments

Hi. This is just what i need :) ( sorry for bad english im swedish ) . I work i n a kinderarden and have kids that need something like this. Is there eny chans to have 2 made for us? We kan pay for it. My email is mattiasblomfeldt@hotmail.com

1 reply

Hi Mattias,

I'm sorry, it was a one off for me. Perhaps there is a local Makers group who would like to help you build one?

Martin

Hello

I like your project besides i dont understand nothing about programming but im going to learn, to make one for me for sure :)

I have some questions because the button, when you talk that need for the project a push button switch, is a push button that when we only need to close one time the circuit to change, or it need to be closed with an button on/off switch to change?

And the button change from mouse to what?I dont understand the difference. Beside it work like the left mouse button when we stop the head and it press automatic to open, the reading of the movements to a computer of the axis are different? Or work different the head mouse in the movement of the head for the example you show in minecraft or in windows?

Best Regards

3 replies

It's a push to make button - i.e. on when you press it, off when you let go. It allows you to enable and disable the mouse, and to re-center it when required.

Good luck with the build!

Martin

I finish my building :)

But i already have a problem and i need Help because i unsderstand almost nothing about codes :)

When im trying to send the code into arduino clone it pops up an error in Line and cant send the code:

Mouse.move((averageX-dof.calcGyro(dof.gx))*dof.calcAccel(dof.ax) +(averageY-dof.calcGyro(dof.gy))*dof.calcAccel(dof.ay), averageZ-dof.calcGyro(dof.gz));

and said in the error:

´Mouse´ not find. Your Draft include the line´#include <Mouse.h>´?

C:\Users\OFICINA\AppData\Local\Temp\arduino_modified_sketch_913103\headMouse2.ino: In function ' void Setup() ':

headMouse2:177: error: ' Mouse ' is not found. The your draft includes the line ' <Mouse.h> ' #include?

Mouse. begin ();

^

C:\Users\OFICINA\AppData\Local\Temp\arduino_modified_sketch_913103\headMouse2.ino: In function ' void mouseMoveGyro () ':

headMouse2:277: error: ' Mouse ' is not found. The your draft includes the line ' <Mouse.h> ' #include?

Mouse move ((averageX-dof. calcGyro (dof. gx)) * dof. calcAccel (dof. ax) + (averageY-dof. calcGyro (dof.gy)) * dof. calcAccel (dof. ay), averageZ-dof. calcGyro (dof.gz));

^

Multiple libraries were found to «SFE_LSM9DS0. h»

Used: C:\Users\OFICINA\Documents\Arduino\libraries\SFE_LSM9DS0

Not used: C:\Program Files (x 86) \Arduino\libraries\SFE_LSM9DS0

exit status 1

' Mouse ' is not found. The your draft includes the line ' <Mouse.h> ' #include?

Whats happens with th mouse.

Can you Help me?

Best Regards

I already solve the problem :)

And now its alive!

Great Project

i could implement other tasks, such as sustained click or secondary click, this with respect to programming?

I cant found the same LSM9DS0 ic which you have used in your project what to do? please help

hello sir,

its amazing work but I have problem how we find the value of gx,gy,gz,ax,ay,az as well as vx, vy, vz

Hi, I need to know what is the principle of working of the gyroscope, accelerometer and magneometer? please

Sketch uses 10,966 bytes (38%) of program storage space. Maximum is 28,672 bytes.

Global variables use 471 bytes (18%) of dynamic memory, leaving 2,089 bytes for local variables. Maximum is 2,560 bytes.

An error occurred while uploading the sketch

Got any solution??

Excellent project Hello , I have a question estre microcontroller when connecting to a device android recognize it as HID ??

2 replies

Yes, Android recognises it as a HID.It works as a mouse on your phone (requires a OTG USB cable)

I have managed to do this project with one and with transmission arduino bluetooth for pc, what I want is to use bluetooth android but also , any idea that can help me ?? thanks greetings.

Thank you very much for this helpful project!
but i wanna ask you something can i replace the LSMD9S0 with MPU-6050?

1 reply

and if i can use the mpu6050 what should i do to replace the LSMd9s0 code?

At first congratulations for the project its a great DIY project, i hope to make it in some days but maybe its posible to try attach with VR glasses to combine mouse head movement with the visual play screen. Its very cool for simulator games DCS, etc...

Could you see posible to include new movement, like zoom moving the head (back to front for example).

Thanks for your project!.

hi,

can it be controlled wirelessly by bluetooth or xbee?