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.


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;


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.

<p>Nice work m8!</p>
<p>Nice work m8 </p>
<p>Hi, I need to know what is the principle of working of the gyroscope, accelerometer and magneometer? please</p>
<p>Hello</p><p>I like your project besides i dont understand nothing about programming but im going to learn, to make one for me for sure :) </p><p>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?</p><p>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?</p><p>Best Regards </p>
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. <br><br>Good luck with the build!<br><br>Martin
<p>Sketch uses 10,966 bytes (38%) of program storage space. Maximum is 28,672 bytes.</p><p>Global variables use 471 bytes (18%) of dynamic memory, leaving 2,089 bytes for local variables. Maximum is 2,560 bytes.</p><p>An error occurred while uploading the sketch</p><p>Got any solution??</p>
<p>Excellent project Hello , I have a question estre microcontroller when connecting to a device android recognize it as HID ??</p>
Yes, Android recognises it as a HID.It works as a mouse on your phone (requires a OTG USB cable)
<p>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.</p>
<p>Thank you very much for this helpful project!<br>but i wanna ask you something can i replace the LSMD9S0 with MPU-6050?</p>
<p>and if i can use the mpu6050 what should i do to replace the LSMd9s0 code?</p>
<p>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...</p><p> Could you see posible to include new movement, like zoom moving the head (back to front for example).</p><p>Thanks for your project!.</p>
<p>hi,</p><p>can it be controlled wirelessly by bluetooth or xbee?</p>
<p>amazing project!!!! </p>
<p>G'Day Millmore fantastic project, i just have a few questions. </p><p>1. When turning the Head Mouse on it sometimes loads up with a 'drift' where it will just start slowly moving to one side of the screen until i reset it, is this a known cause?</p><p>2. The mouse seems try center itself on the screen every 10secs but actually just ends up jittering leaving myself unable to maintain a position on the screen. i suspect this is from the 'averageCount= 100;' line of code?</p>
Hi. Yes, drift can be an issue with any gyroscope. It can happen if the device is not 100% stationary when you calibrate it, and it can happen over time. <br><br>The averageCount line is about removing jitter - if every measured movement was translated in to a mouse movement, it would move all over the place, so the averaging stops that. It shouldn't jump to the center of the screen though.<br><br>if your gyroscope is particularly jittery, you could increase the averaging.
I didn't use the magnetometer, because it wasn't as precise at measuring small movements as the gyroscope. You might find that you can get better results though - give it a go.<br><br>Yes, you can move the mouse to the other side - there are comments in the code for how to do that, in the mouseMoveGyro method. Basically change averageZ-dof.calcGyro(dof.gz) to dof.calcGyro(dof.gz)-averageZ
<p>Cheers Millmore, I set this up on an 32u4 5v Pro Micro and Adafruit LSM9DS0 gyro. Another few questions (Sorry!);</p><p>1. Looking upon your code you don't use your Magnetometer to help get a more accurate reading any reason for this?</p><p>2. Is there anyway to alter the code so instead of having the device on the left or right side your head you can have it on the top of your head? </p><p>3. So the jittering tends to happen in the 1st 10 seconds of plugging it in, cursor is center of the screen and it'll jump about 1inch to the top left or bottom right corner, then again a few seconds after that and then again a few seconds after that and then it will stop. maybe it is my gyro but i will have to do more testing.</p>
<p>Sir, i have bought a gy-521 with MPU-6050 in order to make this project.can it be done or i need to change the sensor???please help.</p>
<p>Awesome and simple project for the electronics beginner!<br>Do you have any tips or suggestions as how to reduce drag of the mouse? I often find myself having to move the mouse to the side or the top of the screen to readjust the location of the mouse with respect to my head! Thanks in advance!</p>
Yea, I know what you mean - it's the same as moving your mouse too far left or right - you need to pick the mouse up and move it back again. Not so easy to do with your head. One thing I did experiment with earlier on was having the direction of the mouse output as a serial stream from the arduino, and have a simple PC app to listen to that and turn it in to a mouse location on screen. It worked well and is immune to over pointing, but it needs the client side app to work, which I didn't like so much.
<p>So suuuuper late reply here, but could you possibly send me your code for this, or just a little more information on what you actually did?</p>
<p>For everywhere else in the world who are using UNO and MEGA this is the alternative millmore was talking about:</p><p><a href="http://www.instructables.com/id/Make-arduino-uno-work-like-leonardo/" rel="nofollow">http://www.instructables.com/id/Make-arduino-uno-w...</a></p><p><a href="https://nicohood.wordpress.com/2014/06/03/install-new-firmwares-with-dfu-and-flip-on-arduino-unomega-r3/" rel="nofollow">https://nicohood.wordpress.com/2014/06/03/install-...</a></p><p>This is not easy! It's better to invest in a A-Star 32U4 Micro</p>
Very cool. Thanks for sharing.
<p>Anyone can please help me in connection part. </p><p>i have arduino Leonardo, MPU-9150 and logic level converter.</p><p>Thank you.!</p>
<p>Awesome project. i wish to do same. soon i will start to build it your instruction as mentioned. </p>
First I tried it on Leonardo but it becomes too bulky that's Y I used micro made some changes in the code works like a charm
<p>Has anyone done this project, or something similar, using the MPU6050? I have been fiddling with it, but have not had too much success as of yet, and would appreciate some assistance. </p>
<p>i am using a sunfounder push button with three pins: gnd, +5v and signal, how would i set up the button?</p>
<p>what do i do with the headmouse2.ino code/file, i cant see it in this instructable</p>
That's the code that you need to load in to the Arduino. Download the arduino IDE from http://arduino.cc/en/Main/Software and install it, then create the directories I mention in Step 2 for the c++ code. Then open headMouse2.ino in the arduino IDE and connect your arduino to your computer using the usb cable, and in the IDE you can send the code to the arduino.
so do i just copy and paste the code?
<p>Yes, that would work.</p>
<p>Sir i have a question, can i use an arduino mega for this project? will it still work?</p>
It's not quite as simple with a Mega because it can't act as a HID device without some fancy bootloader, whereas the Leonardo based devices can do natively. I believe it's technically possible, but I have never tried it.
<p>Dear Sir:</p><p>Its an excellent project. I am also working on a similar project called &quot;Wireless inertial pointer&quot;. Its similar to a wireless mouse like the one you showed in your video but in my device I will be adding buttons for right and left click. </p><p>I am using arduino UNO and MPU 9150. I have combined the gyro data and accelerometer data using complimentary filter. Everything is working very well and I am also able to move the cursor on the screen but however it is not smooth enough and therefore doesn't acts like a pointer. I want my cursor(pointer) on screen to directly go to the point where I am projecting the device instead of going through the x and y axis values.</p><p>I hope my question is clear to you I will be very grateful if you can help me out. Following is my code that makes use of mouse.move method.</p><p>if(compAngleX &gt; 90)</p><p> compAngleX = 90;</p><p> if(compAngleX &lt;-90)</p><p> compAngleX = -90;</p><p> if(compAngleY &gt; 95)</p><p> compAngleY = 95;</p><p> if(compAngleY &lt;-95)</p><p> compAngleY = -95;</p><p> int x = map(compAngleY, -90, 90, -10, 10);</p><p> int y = map(compAngleX, -90, 90, -10, 10);</p><p> Mouse.move(x,y,0);</p><p>Thanks and Regards:</p><p>sufiyan.</p>
If you look at my code for running as a mouse with auto clicking (Step 6), you will see that I average over the last 100 readings. That's specifically to smooth out the movement. You should probably do the same.<br><br>Martin
<p>Also Sir, I am facing problems with the yaw angle that I am getting using the magnetometer, even after removing the soft iron and hard iron errors. The yaw angle is not stable and changes significantly when the roll is changed (rotation along the x-axis). Can you please suggest what I can do about it. Would really appreciate your help. Thanks a lot!</p>
<p>To make the readings smooth and avoid jitters I have used complimentary filter. Which Sensor Fusion algorithm you have used ?</p><p>Thanks.</p>
<p>Great Tutorial, thanks!</p><p>I want to do the same thing, with my EDtracker (Sparkfun Micro Pro-with the GY-521 MPU6050 (no magnetometer) <a href="http://www.edtracker.org.uk" rel="nofollow"> www.edtracker.org.uk</a></p><p>Trying to make a 360 degree sensor for FPV games for use on my DIY Rift. </p><p>EDtracker comes with a sketch that emulates joysticks up to 180degree (90left, 90right etc..) I would like to make it 360 obviously, but should I just flash new sketches to turn it into an air mouse, like yours? Is that even possible? I'm completely new to Arduino and I have no coding experience. </p><p>Im assuming your code won't work with mine. Any suggestions? </p>
From what you say, I imagine that you'd be better off editing their code - it's designed specifically for that hardware. I really recommend learning to code - it's such a useful life skill, and there are some brilliant sites out there for beginners.<br><br>Anyway, I took a look at their code, and if you look at line 460-462, you will see the constraints they have added to limit it to 180 degrees;<br><br>https://github.com/pocketmoon/EDTracker2/blob/master/sketches/EDTrackerII/EDTrackerII.ino<br><br>I suspect that all you need to do is change those lines. But also, learn to code - it's easy, doesn't cost anything and opens up loads of new projects.
<p>Thanks very much for the response. I will try to learn to code, but it looks so alien to me. I wouldn't know where to begin. But yes, I would love to be able to. </p>
<p>Hello, I still cant get the code to work and been reading all the comments. Is there any way you can do a quick video on the code? </p>
What doesn't work about it for you?
<p>Cool, i have made this one with LSM9D40 and A-Star 32U4 Pro Micro sparkfun 3,3V/8MHz and it's works. thanks </p><p>Now, i'm gonna going for mouseclick</p>
Great. Well done!
<p>finally i got this problem: </p><p>headMouse2.ino.ino: In function 'void setup()':</p><p>headMouse2.ino.ino:163: error: 'Mouse' was not declared in this scope</p><p>headMouse2.ino.ino: In function 'void mouseMoveGyro()':</p><p>headMouse2.ino.ino:263: error: 'Mouse' was not declared in this scope</p><p>i hope u can reply my comment thanks. I use a star with 3,3 v/8Mhz</p>
<p>Not all aruinos support Mouse - only the Leonardo and ones based on that (such as the A-Star 32U4 Micro). If you pick the wrong device in the arduino IDE, it won't compile as it won't find that library. Make sure you install your hardware drivers and pick the right device in Tools-&gt;Board.</p>

About This Instructable




More by millmore:Slate House Number Head Mouse - Game controller or disability aid Recover Shoe Polish 
Add instructable to: