CAD Mouse Mk2

This post documents my build of the open-source CAD Mouse Mk2, including assembly, firmware installation, and configuration under Linux.
Assembly #

The printed parts from the repository were manufactured in black and transparent PETG without modification using the FDM Print Service.

The remaining mechanical components were ordered from Amazon using the project's Bill of Materials (BOM).

Following the assembly guide, the mouse base was filled with approximately 200 g of lead shot and fixed with epoxy resin to give the device a more substantial feel during use.


The PCBs were manufactured by JLPCB using the Gerber CAD files provided in the project repository.
The remaining electronic components were ordered from DigiKey using the sensor board BOM included in the repository.

The firmware was built with PlatformIO in Visual Studio Code, flashed to the RP2040, and worked immediately without requiring any modifications.
Finish #

To improve the appearance and feel of the printed parts, the enclosure was first coated with a plastic filler and sanded smooth. After applying two coats of plastic primer with light sanding in between, the final finish was applied using LIQUID GUM. Besides giving the enclosure a clean, uniform appearance, the coating provides a pleasant soft-touch surface that feels excellent during everyday use.
Building Firmware #
Building the firmware requires PlatformIO. Visual Studio Code with the PlatformIO extension is recommended but not strictly required.
Installation and testing #
After connecting the device, Linux detects it as a USB multi-axis controller. The following dmesg output confirms that the CAD Mouse Mk2 has been recognized successfully.
[ 8351.589275] usb 3-7: new full-speed USB device number 14 using xhci_hcd
[ 8351.717267] usb 3-7: New USB device found, idVendor=2e8a, idProduct=000a, bcdDevice= 1.00
[ 8351.717283] usb 3-7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 8351.717290] usb 3-7: Product: CAD Mouse MK2
[ 8351.717296] usb 3-7: Manufacturer: Seeed Studio
[ 8351.717301] usb 3-7: SerialNumber: 4250305539333104
[ 8351.722239] cdc_acm 3-7:1.0: ttyACM0: USB ACM device
[ 8351.724535] input: Seeed Studio CAD Mouse MK2 as /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.2/0003:2E8A:000A.000C/input/input29
[ 8351.724773] hid-generic 0003:2E8A:000A.000C: input,hidraw5: USB HID v1.11 Multi-Axis Controller [Seeed Studio CAD Mouse MK2] on usb-0000:00:14.0-7/input2
The following steps were performed on Ubuntu/Linuxmint 22.
spacenavd provides support for six-degree-of-freedom (6-DoF) input devices used by applications such as FreeCAD.
Installation of the spacenavd user-space driver (daemon), for 6-dof input devices.
sudo apt-get install spacenavd
sudo systemctl enable --now spacenavd
spnavcfg provides a graphical interface for testing the device and adjusting sensitivity, dead zones, and axis mappings.
Installation of the spnavcfg configuration GUI.
wget https://mirror.cs.uchicago.edu/ubuntu/ubuntu/pool/universe/s/spnavcfg/spnavcfg_1.1-3_amd64.deb
sudo dpkg -i spnavcfg_1.1-3_amd64.deb
Because the CAD Mouse Mk2 uses different USB vendor and product IDs than the original SpaceNavigator, spacenavd does not recognize it automatically. Adding the device ID to the configuration file enables support.
Create /etc/spnavrc using the example configuration below.
sudo nano /etc/spnavrc
The important change is the additional device identifier near the end of the file. Source
# This is an example configuration file for spacenavd. Uncomment and change
# any settings you need and copy it to /etc/spnavrc.
#
# Note that it's much easier to configure sensitivities and figure out axis
# reversals by using the interactive configure utility "spnavcfg", which lets
# you fiddle with all the settings and see the result immediately.
#
# Lines that start with a `#' are comments, and are ignored by spacenavd.
# Sensitivity is multiplied with every motion (1.0 normal).
#
#sensitivity = 1.0
# Separate sensitivity for rotation and translation.
#
#sensitivity-translation = 1.0
#sensitivity-rotation = 1.0
# Separate sensitivity for each rotation and translation axis.
#
#sensitivity-translation-x = 1.0
#sensitivity-translation-y = 1.0
#sensitivity-translation-z = 1.0
#sensitivity-rotation-x = 1.0
#sensitivity-rotation-y = 1.0
#sensitivity-rotation-z = 1.0
# Dead zone; any motion less than this number is discarded as noise.
#
#dead-zone = 2
# Separate dead-zone for each rotation and translation axis.
# This is still supported, but unclear in face of device axes mapping, and
# therefore you are encouraged to use dead-zoneN instead.
#
#dead-zone-translation-x = 2
#dead-zone-translation-y = 2
#dead-zone-translation-z = 2
#dead-zone-rotation-x = 2
#dead-zone-rotation-y = 2
#dead-zone-rotation-z = 2
# Separate dead-zone for each device axis.
#
#dead-zone0 = 2
#dead-zone1 = 2
# ...
#dead-zoneN = 2
# Selectively invert translation and rotation axes. Valid values are
# combinations of the letters x, y, and z.
#
#invert-rot = yz
#invert-trans = yz
# Swap Y and Z axes
#
#swap-yz = false
# Axis remapping (zero-based)
#
axismap0 = 0
axismap1 = 1
axismap2 = 2
axismap3 = 3
axismap4 = 4
axismap5 = 5
#...
#axismapN = N (N < 64)
# Button remapping (zero-based)
#
#bnmap0 = 0
#bnmap1 = 1
#...
#bnmapN = N (N < 64)
# Button action mapping
# Use the following syntax:
# bnactN = <action>
# Where N is the button number (zero-based), and action is one of the following
# available actions:
# none,
# sensitivity-up, sensitivity-down, sensitivity-reset
# disable-rotation
# disable-translation
# dominant-axis
#
#bnact16 = sensitivity-up
#bnact17 = sensitivity-down
#bnact18 = sensitivity-reset
# Map buttons to keyboard keys (experimental)
# By default no such mappings are active. Use the following syntax:
# kbmapN = <keysym>
# where N is the button number (zero-based), and <keysym> is a keysym name from
# /usr/include/X11/keysymdef.h, without the leading XK_
# Example:
# kbmap0 = Escape
# Serial device
# Set this only if you have a serial device, and make sure you specify the
# correct device file. If you do set this option, any USB devices will be
# ignored!
#
#serial = /dev/ttyS0
# Enable/disable LED light (for devices that have one).
#
#led = on
# Device grab (USB)
#
# When set to true (default): grab the USB device to prevent other programs
# (such as the X server) from also using it.
#
# Grabbing the device ensures that other programs won't be able to use it without
# talking to spacenavd. For instance some versions of Xorg will use the device to move
# the mouse pointer if we don't grab it.
# Set this to false if you want to use programs that try to talk to the device directly
# such as google earth, then follow FAQ 11 http://spacenav.sourceforge.net/faq.html#faq11
# to force the X server to ignore the device
#
grab = true
# List of additional USB devices to use (multiple devices can be listed)
#
# example:
device-id = 2e8a:000a
# Repeat interval (milliseconds)
# Non-deadzone events are repeated every so many milliseconds (-1 to disable).
#
# You probably don't need this setting. Set it to something like 250 if you
# find that your apps stop moving the view while you hold the puck/ball at a
# fixed off-center position (like bottomed out on the vertical axis).
# Might cause inadvertent continuous motion if the deadzone is too small for
# the re-centering power of the device.
#
#repeat-interval = -1
Axis mappings, sensitivities, and dead zones can be adjusted to personal preference. The device-id entry should remain unchanged.
Save and restart the spacenavd service.
sudo systemctl restart spacenavd
Run spnavcfg and check that the CAD Mouse Mk2 is detected and operational.

The CAD Mouse Mk2 can now be used in applications such as FreeCAD. Basic functionality works as expected, although the default axis mapping is not yet ideal. Further tuning of the axis assignments and sensitivity settings is still required for the most natural navigation experience.
👈 Home
