Introduction: DIY Space Mouse for Fusion 360 Using Magnets
This project originated from my curiosity about CAD input devices. I realized that I was struggling to remember navigation combos in Fusion 360 whenever I switched workstations. Having never used a Space mouse before, I decided to explore the possibility of creating a similar device using only the parts I already had on hand.
To make the 3-axis joystick, I used a low-resolution magnetometer and neodymium magnets mounted on a spring system directly inspired form the real 3D connexion Space Mouse. Currently, the device emulates the mouse and keyboard to execute the orbit and pan functions within Fusion 360. There are also two shortcut buttons — one for the home view and another for fitting to the screen.
To address the lack of a native option to assign a keyboard shortcut for views in Fusion 360, we will go over a workaround that involves a custom python add-in.
Supplies
Parts
- 1 × QT Py RP2040 Adafruit
- 1 × TLV493D Triple-Axis Magnetometer Adafruit
- 1 × STEMMA QT / Qwiic JST SH 4-pin Cable - 100mm Long Adafruit
- 2 × Tactile Button switch (6mm) Adafruit
- 3 × Adafruit LED Sequins - Emerald Green (optional) Adafruit
- 4 × Rubber Bumper Feet Adafruit
Hardware
- Round Magnets Amazon
- 6 × (6 × 2mm)
- Springs Amazon
- 3 × Compression 23/64" × 1-3/8"
- 3 × Extension 13/64" × 13/16"
- M2.5 Heat-Set Inserts McMasterCarr
- 24 × 3.4 mm
- M2.5 Socket Head Screws Amazon
- 10 × 3mm
- 3 × 5mm
- 7 × 8mm
- 4 × 12mm
3D printing
Finishing (optional)
- Assorted Grits Sandpaper Amazon
- Glazing and Spot Putty Amazon
- Filler Primer Amazon
- Spray Paint Amazon
- Flat Matte Clear Coat Amazon
Tools
- 3D Printer Amazon
- Soldering Station/Iron. Amazon
- Helping hands Amazon
- Precision Screwdriver Set Amazon
- Wire stripper Amazon
- Sanding block
- Flux, Solder
- Hook up wire
- Flush cutters
- Hobby knife
- Tweezers and pliers
Affiliate links may be included in the parts list. I may receive a small commission at no additional cost to you.
Step 1: Watch the Build Video
The video will give you an overview of the design and build process.
Step 2: 3D Printing
You can grab the included STLs in the page or from Github
⚠️ Few things to keep in mind before printing
- I have designed the holes and fit of the pieces to accommodate tolerances from my 3D printing setup. You might want to verify the heated inserts holes and the fit, particularly between the Base_top.stl and the Base_bottom.stl before proceeding.
- For the Base_bottom.stl, I printed it using a 5% grid infill with 3-4 wall counts. Around layer 64, I paused the print to pack in the steel BB's and add some weight. This step is essential to counteract the tension from the springs prevent the the device from sliding around.
- I suggest to go for 100% infill solid parts from the knob and the three stem parts.
- I included 1 model for the buttons but you obviously need to print it twice.
Attachments
Step 3: Finishing (optional)
If you are not familiar with post-processing techniques for FDM prints, I have some instructions in this project to guide you.
Step 4: Heated Inserts
Once the clear coat has had ample time to dry, I proceeded to install the heated inserts into the designated 24 holes.
Although it may seem excessive for most cases, I prefer incorporating them into my 3D prints. I would rather do this then deal with stripped threads after few adjustments.
Step 5: Assembly _1
Following that, I proceeded to install six mini round magnets (6x2mm) into the designated slot on Stem_top.stl.
Please note that depending on the tolerances of your 3D printer and the magnet manufacturer, you may need to apply some glue to secure them in place. In my case, I was able friction fit them.
Step 6: Assembly _2
Now, we can assemble the spring mechanism and attach it to the knob from the inside.
Begin by inserting the 3 compression springs into the appropriate holes on both Stem_top.stl and Stem_middle.stl. With both pieces compressed together, securely hold them in place while fastening the extension springs to the three sides using 6 x 3mm M2.5 socket head screws.
Once this step is complete, you can insert the entire contraption inside the knob and secure it from the inside using 3 x 5mm M2.5 screws. The Stem_middle.stl features three larger holes, allowing you to pass through the springs and screw in the entire thing to the knob from inside.
Step 7: Wiring _1
I did not plan on this initially. However, it seemed to be a great opportunity to incorporate some LEDs for added visual interest.
I carefully glued and wired 3 Adafruit LED Sequins onto the sides of Stem_bottom.stl. I took care to ensure that they did not interfere with the four screws or the lip protruding from Base_bottom.stl, allowing for proper clearance.
Next, I plugged the Magnetometer and secured over it Stem_bottom.stl to the inside of the knob using 4 x 8mm M2.5 screws.
⚠️ Check the wiring diagram
Attachments
Step 8: Wiring _2
I soldered wires to both switches and carefully measured the length of the shared wire (ground) that needs to fit into the channel around the opening in the middle. Then, I placed the two printed buttons with the thicker part facing up into the slots, followed by the switch it self. Once that was completed, I positioned the Base_middle_plate.stl and guided the remaining 5 wires (3 from the buttons and 2 from the leds) through the opening from inside. Finally, I secured plate using four 4 x 3mm M2.5 screws.
⚠️ Check the wiring diagram
Attachments
Step 9: Wiring _3
Now, we can complete the wiring by soldering the remaining five wires to the RP2040 on the bottom side, ensuring they are placed as far away from the edges as possible (please refer to the image). After soldering the wires, we can neatly tuck the slack into the opening below, aligning the RP2040 snugly in its designated slot.
⚠️ Check the wiring diagram
Attachments
Step 10: Assembly _3
The assembly was finalized by positioning the Base_bottom.stl and securely attaching it to the stem using 3 x 8mm M2.5 screws then to the rest of the body using 4 x 12mm M2.5 screws.
To enhance stability, I affixed 4 rubber feet to the bottom.
Now, we can proceed to upload the code and conduct a test run of the device.
Step 11: Code _1
First thing is to get the Adafruit QT Py RP2040 working in the Arduino IDE. You can follow this guide if you never done this before.
Once the board is working properly you can open the Arduino sketch located here and install the required libraries in your environment.
#include <TinyUSB_Mouse_and_Keyboard.h>
#include <OneButton.h>
#include <Tlv493d.h>
#include <SimpleKalmanFilter.h>
In order for the sketch to compile you will also need to change the USB stack to from Arduino to TinyUSB. You can read more on how to do that here.
Once the board flashed successfully you can unplug, open the serial console and plug it back in.
By default the code prints out to the console x,y,z after initialization.
You can test the knob to see if it moves the mouse cursor and if it's in the right orientation. Incase it's reversed you can invert the values in the code if you don't want to open it and flip the sensor.
Depending on how centred the knob in your build and how the everything fits together, you might need to adjust the magRange and sensitivity values. You can move the knob to the extremities take a look at the x and y values printed on serial console and adjust the ceiling value for magRange.
The "dead zone" or center position is represented by xyThreshold you can adjust this for tighter tolerances to your preference.
int calSamples = 300;
int sensivity = 8;
int magRange = 3;
int outRange = 127; // Max allowed in HID report
float xyThreshold = 0.4; // Center threshold
The shortcut buttons are sent from these 2 functions. You can define new combos if you like using this reference.
// go to home view in Fusion 360 by pressing (CMD + SHIFT + H) shortcut assigned to the custom Add-in command
void goHome()
{
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.write('h');
delay(10);
Keyboard.releaseAll();
Serial.println("pressed home");
}
// fit to view by pressing the middle mouse button twice
void fitToScreen()
{
Mouse.press(MOUSE_MIDDLE);
Mouse.release(MOUSE_MIDDLE);
Mouse.press(MOUSE_MIDDLE);
Mouse.release(MOUSE_MIDDLE);
Serial.println("pressed fit");
}
Step 12: Code _2
To get homeview shortcut working you'll need to install the custom Add-in for Fusion.
- In the toolbar, go to UTILITIES > Scripts and Add-Ins.
- Click on the Add-Ins tab. Under My Add-Ins click on the green plus sign and copy the Send home folder located here to that location and click open.
- Make sure Run on Startup is active and click Run.
- You should see a new command > Send To Home View appear under Add-Ins.
- Click on the 3 dots icon > Change Keyboard Shortcut...
- Assign the same keyboard shortcut sent by the button press from the device: cmd+shift+h
Step 13: Done
Thank you for sticking around until the end!
This was a lot of fun to make and I enjoyed the process. There is certainly a lot of improvements to be made. I'd love to hear your suggestions in the comments below.
I have a lot of ideas and I plan on making more projects like these Follow me for more
Grand Prize in the
Magnets Contest
134 Comments
Question 14 days ago
Stops working for me as well after a few seconds (Windows 10), it then
messes up my normal mouse an keyboard functionality and I am forced to
restart. Anyone else able to get it working? Using all the parts suggested in the tutorial. Using latest Arduino IDE and Adafruit libraries.I did try increasing the sensitivity and thresholds to no avail.
Answer 13 days ago
I ended up fixing my issue. Narrowed the issue to Keyboard.press(KEY_LEFT_SHIFT); causing the issue. Added code to release the key press if no changes detected to xyz coordinates. Now it no longer crashes and locks up the system. This instructable has been a blast to make! Thanks for sharing this awesome project.
Reply 5 days ago
I'm having this same issue and attempted to add some code to release but it keeps happening. Would you mind sharing some details on what you did to fix it?
Question 7 weeks ago
Hi Salim,
I've finished my Space-Mouse yesterday, it looks good so far. The problem is, it's only working for a few seconds, best was 20 seconds. After that the ghost of the Space-Mouse takes control, open and closes windows, marks text, mouse arrow moves around, appears and disappears... The scroll wheel of the proper mouse doesn't work eather. I have to disconnect the Space-Mouse and everything is okay again. Any idea? I used all the parts from your BOM.
Regards Olaf
Answer 6 weeks ago
Same, seems to also stop working after I use the MacBook internal trackpad.
Reply 17 days ago
I tried it and it seems to work. I have to test it more intensively, but it's definitely better than before and I now know where to look. Thank you very much.
Answer 19 days ago
int calSamples = 300;
int magRange = 3;
int outRange = 127; // Max allowed in HID report
float xyThreshold = 1.0; // Center threshold
If you are still having issues, check your x and y readings and if they are greater than 1.0, you may need to increase the xyThreshold even more. The sensitivity adjustment slowed down pan and rotate to a more manageable rate.
One last thing, I also noticed that the magnetometer would stop reading out. I added a reinitialization of it in the fitToScreen function just in case it does it again.
void fitToScreen() {
Mouse.press(MOUSE_MIDDLE);
Mouse.release(MOUSE_MIDDLE);
Mouse.press(MOUSE_MIDDLE);
Mouse.release(MOUSE_MIDDLE);
// Restart Mag Sensor
Wire1.begin();
mag.begin(Wire1);
mag.setAccessMode(mag.MASTERCONTROLLEDMODE);
mag.disableTemp();
Serial.println("pressed fit");
}
Hope this helps.
2 months ago
having trouble location a TLV493D at a reasonable price, would one of the other Magnetometers from Adafruit work?
Search Results for 'Triple-Axis Magnetometer - STEMMA QT' on Adafruit Industries
Reply 2 months ago
Yes, few people in the comments built the project using the MMC5603. There is wiring and code changes in the comments. Go check them out!
Reply 18 days ago
Salim I´ve been looking in the YT comments and here but I cannot seem to find the instructions for the MMC5603 magnetometer. Can you point me the right direction? Cheers
Reply 2 months ago
Where are the wiring and code changes for the MMC5603?
21 days ago
Been pondering this project for some time now, and this is a much more elegant solution that I had in mind! Great use of magnetometry! And a truly worthy write-up and video of the Prize! Look forward to future project =D
Only small suggestion I have is to consider adding some extra hotkey buttons, but I suspect most folks who can do this project can figure that out also.
https://www.instructables.com/How-to-make-an-Ergon...
This is a very old project I did that you may enjoy also... pretty much pre-[cheap]-3D-printing, but might give you a laugh. Weird to look at it, but despite cringing a little, home DIY~ has come a long way, huh!?
Reply 21 days ago
Thanks!
Some people already added more buttons to the sides as you suspected.
What a nice project you made! Did the Sugru Skin hold up well?
Reply 20 days ago
Ah yes - I see that now! Makes sense ;o)
The Sugru Skin did hold up well, but I think over time the depth of the filler is key to it being stable. Unless using glass reinforced. But as you likely gathered - it's more of a prototyping journey. Good times ;o)
20 days ago
Still not working (see my comment a month ago) - another project for the bin.
22 days ago
Build seemed to go fine, but I have no response from the RP2040 when plugging in via USB. PC doesn't even see anything being plugged in. Must have killed it soldering, which would be the first time I've killed anything soldering. Don't feel like I used too much heat or for too long. Weird. Guess i'll try another one.
Edit: I got it working. RP2040 was fine, it was just missing a diode so the BOOT button wouldn't work. Got the code flashed, but like the others, it only seems to work for just a few seconds before "crashing".
Question 24 days ago
How much does it cost to build the mouse apposed to buying a space mouse?
Question 4 weeks ago
Thanks for the great project. I'm just building the Space Mouse but ran in to a problem with USB connectivity. I can flash the QT py RP2040 card but looks like I don't get anything on the serial monitor. If I load the NeoPixelBlink sketch then the serial monitor works but not for the Spacemouse sketch. Might be something to do with the TinyUSB stack? I'm running a MAC with OS Monterey.
Answer 4 weeks ago
To answer my own question: The terminal on Arduino IDE is not that good, so most of the times did not work at all. Installed the free CoolTerm app and that works great every time.
5 weeks ago on Step 6
So I love this design, but upon building it, I found the pinging of the springs to be a non-starter for me, springs were way too loud. Luckily I came up with a dead simple solution without a redesign (I'd recommend adding a large chamfer on the edges around the compression spring holes, didn't try it myself, but noise seems to be primarily from springs catching on these edges). In the event any of you have this same issue, I'd HIGHLY recommend adding electrical tape around the springs. Sounds really dumb, but it was shockingly effective at removing the vast majority of the noise. Video with the power on the LEDs shows the noise before, video without the LEDs on shows after adding tape. I'll be uploading better pictures of the mouse itself later as I need to touch up the stain on it, but wood filament with stain was definitely a cool way to go on this project.