loading

Head Mouse - Game controller or disability aid

FeaturedContest Winner
Picture of Head Mouse - Game controller or disability aid
IMAG0196.jpg

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.

 
Remove these adsRemove these ads by Signing Up

Step 1: The circuit

Picture of The circuit
HeadMouseCircuit.png

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

Picture of The build
IMAG0206.jpg

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

Picture of Packaging
IMAG0229.jpg
IMAG0230.jpg
IMAG0231.jpg
IMAG0232.jpg

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

Picture of 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.

1-40 of 138Next »
Agatosh10 hours ago

For everywhere else in the world who are using UNO and MEGA this is the alternative millmore was talking about:

http://www.instructables.com/id/Make-arduino-uno-w...

https://nicohood.wordpress.com/2014/06/03/install-...

This is not easy! It's better to invest in a A-Star 32U4 Micro

millmore (author)  Agatosh9 hours ago
Very cool. Thanks for sharing.
aqibisl7865 days ago

Anyone can please help me in connection part.

i have arduino Leonardo, MPU-9150 and logic level converter.

Thank you.!

aqibisl7861 month ago

Awesome project. i wish to do same. soon i will start to build it your instruction as mentioned.

afenrir made it!1 month ago
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
temp_1050114559.jpgtemp_851577536.jpg

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.

ca63 months ago

i am using a sunfounder push button with three pins: gnd, +5v and signal, how would i set up the button?

ca64 months ago

what do i do with the headmouse2.ino code/file, i cant see it in this instructable

millmore (author)  ca64 months ago
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.
ca6 millmore4 months ago
so do i just copy and paste the code?
millmore (author)  ca64 months ago

Yes, that would work.

returner5 months ago

Sir i have a question, can i use an arduino mega for this project? will it still work?

millmore (author)  returner5 months ago
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.

Dear Sir:

Its an excellent project. I am also working on a similar project called "Wireless inertial pointer". 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.

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.

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.

if(compAngleX > 90)

compAngleX = 90;

if(compAngleX <-90)

compAngleX = -90;

if(compAngleY > 95)

compAngleY = 95;

if(compAngleY <-95)

compAngleY = -95;

int x = map(compAngleY, -90, 90, -10, 10);

int y = map(compAngleX, -90, 90, -10, 10);

Mouse.move(x,y,0);

Thanks and Regards:

sufiyan.

millmore (author)  sufiyan.muhammad.97 months ago
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.

Martin

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!

To make the readings smooth and avoid jitters I have used complimentary filter. Which Sensor Fusion algorithm you have used ?

Thanks.

LeoB36 months ago

Great Tutorial, thanks!

I want to do the same thing, with my EDtracker (Sparkfun Micro Pro-with the GY-521 MPU6050 (no magnetometer) www.edtracker.org.uk

Trying to make a 360 degree sensor for FPV games for use on my DIY Rift.

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.

Im assuming your code won't work with mine. Any suggestions?

millmore (author)  LeoB36 months ago
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.

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;

https://github.com/pocketmoon/EDTracker2/blob/master/sketches/EDTrackerII/EDTrackerII.ino

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.
LeoB3 millmore6 months ago

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.

aca707 months ago

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?

millmore (author)  aca707 months ago
What doesn't work about it for you?
tmalau8 months ago

Cool, i have made this one with LSM9D40 and A-Star 32U4 Pro Micro sparkfun 3,3V/8MHz and it's works. thanks

Now, i'm gonna going for mouseclick

IMG_4789.JPG
millmore (author)  tmalau8 months ago
Great. Well done!
tmalau8 months ago

finally i got this problem:

headMouse2.ino.ino: In function 'void setup()':

headMouse2.ino.ino:163: error: 'Mouse' was not declared in this scope

headMouse2.ino.ino: In function 'void mouseMoveGyro()':

headMouse2.ino.ino:263: error: 'Mouse' was not declared in this scope

i hope u can reply my comment thanks. I use a star with 3,3 v/8Mhz

millmore (author)  tmalau8 months ago

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->Board.

tmalau millmore8 months ago

thanks for reply, i found solution of my problem.

https://learn.sparkfun.com/tutorials/pro-micro--fi...

I use pro micro 32U4, sparkfun board. I think i can use 2 board ( A-star 32U4 pro micro and LSM9DS0) to make it, with out converter. I hope your kindness can help me. Wish me luck

tmalau millmore8 months ago

thanks for reply, i found solution of my problem.

https://learn.sparkfun.com/tutorials/pro-micro--fi...

I use pro micro 32U4, sparkfun board. I think i can use 2 board ( A-star 32U4 pro micro and LSM9DS0) to make it, with out converter. I hope your kindness can help me. Wish me luck

kelin.wheeler8 months ago
Eureka! Thank you so much!
IMG_20141123_043222_849.jpg
millmore (author)  kelin.wheeler8 months ago

Brilliant, glad you got it working!

kelin.wheeler8 months ago

Hey, excellent project. I've built the circuit but an having an issue with the sketch. I'm admittedly better with soldering than software, so any help would be appreciated. the error i'm getting seems to be all about the LSM9DSO constructor, it reads:

LSM9DSO:83: error: 'LSM9DS0' does not name a type

LSM9DSO.ino: In function 'void setup()':

LSM9DSO:130: error: 'dof' was not declared in this scope

LSM9DSO.ino: In function 'void mouseMoveGyro()':

LSM9DSO:258: error: 'dof' was not declared in this scope

LSM9DSO.ino: In function 'void recordAverageGyro()':

LSM9DSO:270: error: 'dof' was not declared in this scope

any guess as to what i've done wrong?

millmore (author)  kelin.wheeler8 months ago
Did you include the library files SFE_LSM9DS0.cpp and SFE_LSM9DS0.h? See the end of step 2 for the instructions to do that.

thanks for replying, I'm sure this is a simple fix. I have, they are under Mydocuments>Arduino>Libraries>SFE_LSM9DSO

and under that is my headmouse2 folder, containing headmouse2.ino

millmore (author)  kelin.wheeler8 months ago

When you go to Sketch -> Import Library in the Arduino software, you should see SFE_LSM9DSO. If you don't, you haven't installed it right. headmouse2 doesn't need to be below the library folder - in fact it would be unusual for it to be.

EddieLearner10 months ago

Hi! Great project!

I'm trying to make this project with an added feature, making it wireless. Any suggestions and recommendations?
Also A-Star is not available in our country. Can I use Fio v3 or Pro Micro?

millmore (author)  EddieLearner10 months ago

You could turn it in to a bluetooth mouse using a BlueSMiRF. I found a good tutorial for that here;

http://www.kobakant.at/DIY/?p=3310

Yes, you can undoubtedly use a different arduino compatible board. I chose the A-Star because it is small and could act as a HID, but if you are using the BlueSMiRF, it will be the HID, not the arduino, so you have more options.

tmalau millmore8 months ago

sir, i have try to make this project, it's so great. But i have questions

1. Can i change that USB cable with bluetooth module? Have u try this one?

2. How to make right click and left click mouse?

Thanks for ur tutorial, it's help to make project as a gift for disability school.

millmore (author)  tmalau8 months ago

You could turn it in to a bluetooth mouse using a BlueSMiRF. I found a good tutorial for that here;

http://www.kobakant.at/DIY/?p=3310

If you look at step 6 of the instructable it shows code for doing a click on dwell - i.e. staying still for a while. You could probably detect other motion to select between left and right click if desired, e.g. looking top left sets it to left click, and looking top right sets it to right click. Should be pretty easy to program it to do that.

Thanks for your great suggestion!

If I were to use the BlueSmirf HID, I can use any Arduino(w/ or w/o HID support). Is that right?
Also, if I were to use this item, will the code be very different? Or just some minor tweaks?

millmore (author)  EddieLearner10 months ago

I've not tried it myself, but yes, I suspect you could use any arduino.

The code that calls Mouse.move would need to be changed to make the bluetooth HID calls.

1-40 of 138Next »