Introduction: 3D AIR Mouse | Arduino + Processing

3D AIR mouse | Arduino + Processing

I'm an Industrial design student, and last year as part of a course called "Technology as RAW materiel" I built this project as my final work.

I work most of the time with SolidWorks, a CAD software for design and engenering. Rotating a solid body on the screen is done using the middle mouse button. I was looking for something more intuitive.

This is how I ended up doing the 3D air mouse, where the actual rotation of an object is done by moving the mouse in mid air on all 3 axis - the same way you would rotate the object if you held it in your hand.

I used the Arduino, a couple of sensors and a Processing sketch.

NOTES:
- As of now, this is only a demonstration of the concept, as there is no actual plug-in to work with SolidWork (but of course, feel free to write one if you know how :)

- Since all the hardware wasn't mine, the actual 3D mouse is long gone, and I'm using some photos and a video to try and make some sense in all this, and to give you some idea if you want to try and build one yourself...

Enjoy it... (It's my first Instructable)

Here's the a video demo of the finished project


Step 1: Hardware and Stuff

It's not the cheapest Instructable as it is based on a 3 axis accelerometer + compass sensor.

Stuff you'll need:

* A mouse - a used one is better (only because it's used and cheaper), any mouse should do. You do need to have some space to house the sensors and some extra wires, so don't go for extra slim / extra tiny mice.

* Compass Module with Tilt Compensation - HMC634 - This is the 3 axis sensor, bought at SpurkFun for ~$149

* Logic Level Converter - A MUST! Since the Arduino is 5V and the 3 axis sensor is 3.3V, you need one of those to convert the 5V into 3.3V. It has a  big name, but only cost $1.95 at SpurkFun.

* Large Optical Detector / Phototransistor - This is a simple optical sensor, used in this project to detect when the mouse is being lifted off the work surface. Bought at SpurkFun for $2.25
If you don't have enough space to house this one inside your chosen mouse, you can use this one, smaller and cheaper.

* One (1) LED - never mind the color, ultra bright will work better.

* 2 Resistors - One (1) x 100Ω and One (1) x 100KΩ (For the optical sensor)

* Arduino board - DA! I used the Diecimila model. A newer Duemilanove is avalilable at SpurkFun for about $29.95 (Should work too) + Arduino software installed.

* Processingsoftware installed.

* The project's source code (Don't worry, you'll get to download it in a sec.)

Plus:
Some hot glue (to fix things in place)
A couple of tiny screws.
About 10cm of a 6mm (Dia.) wooden anchor.
Some extra wires.
Soldering iron.
Something to cut the plastic with, I used a cutting knife and a file (FOR shaping).

("Ok, don't hate me for this step, English is my 2nd language, if I got this one wrong, I'm sorry, I'm sure you'll understand what I'm taking about in a sec. when you'll see it in pictures")

Step 2: Electronics

Everything needs to be soldered together...In a way...

NOTE: The 3 axis sensor is an expensive little thing double check the wiring before powering the all thing up...

See the schematics attached for all the wiring used in this project.

The attached source code can only work if you use the same pin numbers I did, but feel free to change those when connecting as long as you change the appropriate numbers in the code.

Connecting the 3 axis sensor to the logic level converter:
Sensor VCC -> Arduino 3V3
Sensor GND -> Arduino Gnd
Sensor SDA -> Converter TXI (Chan1)
Converter TXO (Chan1) -> Arduino ANALOG IN 4
Sensor SCL -> Converter TXI (Chan2)
Converter TXO (Chan2) -> Arduino ANALOG IN 5
Converter GND (at least one of them) -> Arduino Gnd
Converter HV -> Arduino 5V
Converter LV -> Arduino 3V3

Optical sensor to Arduino:
See attached image
Digital in = Pin 11 on the Arduino

LED:
GND to some GND (I used one of the optical sensor)
+ to Arduino PIN 13 (This was done since this pin already have an on-board resistor, if you use a different one, make sure to use a resistor so you wont burn the LED)



Step 3: Preparing the Mouse

This is where the sensors find their place inside the mouse's housing.

Find the best place to fix the 3 axis sensor. Make sure is it leveled and mind the orientation (You'll know when you'll have the sensor in hand)
You can fix it any way you like, I used 2 short pieces of the wooden anchor, drilled to accept the 2 tiny screws, and hot glued to the mouse's main board.

For the optical sensor, shape a rectangular hole at the bottom of the mouse, the idea is to have the sensor "see" the table the all time. When the mouse is lifted and the sensor state is "open" (no table to see) the mouse switches into 3D mode (runs the Processing sketch)

Shape another hole for routing the extra wires (from the sensors to the Arduino) out of the plastic housing. Mine was located on the right hand side of the mouse.

Fix the LED where is will show. In this project the LED is the 3D-mode indicator. I places mine next to the silicone mouse wheel. When the mouse is lifted, the wheel had a nice blue glow.


Step 4: The Source Code

The code for the Arduino was written by Shachar Geiger, my teacher, And was modified by me for this project.

The 3D cube code is the basic code found on the Processing web site. I modified it a bit.

In the code, this chunk converts the raw information coming from the sensor (typically -180 to 180 x 10) to 0-255

getHeading();
Serial.write (’x');
x = (x+1800) / 14;
Serial.write(x);
Serial.write(’y');
y = (y+1800) / 14;
Serial.write(y);
Serial.write(’z');
z= (z+1800) / 14;
Serial.write(z);



The information from the sensor and the Arduino goes to the Processing sketch for each separate axis, but with a preceding axis letter (for exp. X12 Y200 Z130), the following code drops the letter and leaves only the values to be sent to the COM port

while(port.available() == 0){
}

char reading = 0;

while (reading != ‘x’) {
while(port.available() == 0){
}
reading = (char)port.read();
}
X = port.read();
while (reading != ‘y’) {
while(port.available() == 0){
}
reading = (char)port.read();
}
Y = port.read();
while (reading != ‘z’) {
while(port.available() == 0){
}
reading = (char)port.read();
}
Z = port.read();



This chunk of code drops all the negative values...

if ((X != -1) && (Y != -1) && (Z != -1))
{
rotateZ(-(float)Y/25.0);
rotateX((float)X/25.0);
rotateY((float)Z/25.0);
pX = X;
pY = Y;
pZ = Z;
} else {
rotateZ(-(float)pY/25.0);
rotateX((float)pX/25.0);
rotateY((float)pZ/25.0);
}



The attached ZIP file contained both Arduino and Processing code

Step 5: Video

That's it...
This is the finished project in a video.

There is a minor glitch (You can see that the cube sometimes "jumps" in the video), This is because of the Z axis, might not happen to you...



Arduino Contest

Participated in the
Arduino Contest