You are not logged in.
Hi, I built the device from https://github.com/sb-ocr/cad-mouse-mk2. Specifically using most of the firmware from here: https://github.com/lenkaiser/cad-mouse-mk2 (with some modifications to make the following work).
The rest of the device is the same as stated in there ^.
With spacenavd from aur the spacemouse portion of it works in blender. It works a bit weirdly, but those are more weird defaults for spacenavd.
I have a work laptop with windows, so I am able to test the device on there as well.
I wanted to also be able to use it as a mouse and 2 joysticks (for the fun of it), using the side buttons as mode switches.
Slight issue, arch does not seem to be able to "use" the input of the device as a mouse or controller, somehow it only seems to be able to use the Space-mouse portion of it.
If all 3 HID's are enabled they also don't all show up in dmesg, it will only ever show me 2 out of the 3, any less and it will show me exactly the ones i enabled (enabled as in "did not comment out in the code").
When testing the mouse portion back on windows it does work correctly, like i can move the mouse and everything.
But both the mouse portion and controller portion refuse to work back on arch, steam does recognize it as a controller, but receives no input.
This is what dmesg tells me:
[10680.844315] usb 1-2.4: new full-speed USB device number 52 using xhci_hcd
[10681.147425] usb 1-2.4: New USB device found, idVendor=[REDACTED], idProduct=[REDACTED], bcdDevice= 1.00
[10681.147435] usb 1-2.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[10681.147437] usb 1-2.4: Product: [REDACTED]
[10681.147439] usb 1-2.4: Manufacturer: Seeed Studio
[10681.147441] usb 1-2.4: SerialNumber: 4250304B38353816
[10681.182341] cdc_acm 1-2.4:1.0: ttyACM1: USB ACM device
[10681.182836] input: Seeed Studio [REDACTED] as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:10:00.0/usb1/1-2/1-2.4/1-2.4:1.2/0003:2E8A:000A.003A/input/input145
[10681.182892] hid-generic 0003:2E8A:000A.003A: input,hidraw3: USB HID v1.11 Multi-Axis Controller [Seeed Studio [REDACTED]] on usb-0000:10:00.0-2.4/input2
[10681.183756] input: Seeed Studio [REDACTED] as /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:10:00.0/usb1/1-2/1-2.4/1-2.4:1.3/0003:2E8A:000A.003B/input/input146
[10681.183804] hid-generic 0003:2E8A:000A.003B: input,hidraw4: USB HID v1.11 Mouse [Seeed Studio [REDACTED]] on usb-0000:10:00.0-2.4/input3
[10682.403795] input: Microsoft X-Box 360 pad 0 as /devices/virtual/input/input147What lsusb tells me:
Bus 001 Device 052: ID 2e8a:000a Seeed Studio [REDACTED]The modified HIDController.cpp file:
#include "controllers/HIDController.h"
#include <math.h>
#include "Config.h"
namespace {
const uint8_t kHidReportDescriptor[] PROGMEM = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x08, // USAGE (Multi-axis Controller)
0xA1, 0x01, // COLLECTION (Application)
0xA1, 0x00, // COLLECTION (Physical)
0x85, 0x01, // REPORT_ID (1)
0x16, 0xA2, 0xFE, // LOGICAL_MINIMUM (-350)
0x26, 0x5E, 0x01, // LOGICAL_MAXIMUM (350)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x09, 0x33, // USAGE (Rx)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x06, // REPORT_COUNT (6)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xC0, // END_COLLECTION
0xA1, 0x00, // COLLECTION (Physical)
0x85, 0x03, // REPORT_ID (3)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x02, // USAGE_MAXIMUM (Button 2)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x0E, // REPORT_COUNT (14) padding
0x81, 0x01, // INPUT (Const,Array,Abs)
0xC0, // END_COLLECTION
0xC0 // END_COLLECTION
};
}
uint8_t const desc_mouse_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
uint8_t const desc_controller_report[] = {
TUD_HID_REPORT_DESC_GAMEPAD()
};
void HIDController::begin() {
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
usbHid_Spacemouse.setReportDescriptor(kHidReportDescriptor, sizeof(kHidReportDescriptor));
usbHid_Spacemouse.setPollInterval(3);
usbHid_Spacemouse.begin();
usbHid_Mouse.setPollInterval(3);
usbHid_Mouse.setBootProtocol(HID_ITF_PROTOCOL_MOUSE);
usbHid_Mouse.setReportDescriptor(desc_mouse_report, sizeof(desc_mouse_report));
usbHid_Mouse.setStringDescriptor("Spacemouse - Mouse mode");
usbHid_Mouse.begin();
usbHid_Controller.setPollInterval(3);
usbHid_Controller.setReportDescriptor(desc_controller_report, sizeof(desc_controller_report));
usbHid_Controller.setStringDescriptor("Spacemouse - Controller mode");
usbHid_Controller.begin();
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
}
void HIDController::task() { TinyUSBDevice.task(); }
HIDController::ReportAxes HIDController::makeAxesReport(const float motion[6]) {
ReportAxes axes{}; //the first side mentioned is the positive value side.
axes.x = static_cast<int16_t>(motion[0]); //move left and right
axes.y = static_cast<int16_t>(motion[1]); //move forward and backwards
axes.z = static_cast<int16_t>(motion[2]); //move up and down
axes.rx = static_cast<int16_t>(motion[3]); //rotate forward and backwards
axes.ry = static_cast<int16_t>(motion[4]); //rotate right and left
axes.rz = static_cast<int16_t>(motion[5]); //rotate counterclockwise and clockwise
return axes;
}
bool HIDController::axesReportChanged(const ReportAxes& axes) const {
return axes.x != lastSentAxes_.x ||
axes.y != lastSentAxes_.y ||
axes.z != lastSentAxes_.z ||
axes.rx != lastSentAxes_.rx ||
axes.ry != lastSentAxes_.ry ||
axes.rz != lastSentAxes_.rz;
}
bool HIDController::sendReports(const float motion[6], uint16_t buttonBits) {
const ReportAxes axes = makeAxesReport(motion);
const bool sendAxes = axesReportChanged(axes);
const bool sendButtons = (buttonBits != buttonBitsSent_);
if (!sendAxes || !TinyUSBDevice.mounted()) {//!usbHid_Spacemouse.ready()
return false;
}
if (sendAxes) {
switch (CurrentMode)
{
case 1:
if (!usbHid_Spacemouse.ready())
{
return false;
}
usbHid_Spacemouse.sendReport(0x01, &axes, sizeof(axes));
//Serial.println("Sent spacemouse movement");
break;
case 2:
if (!usbHid_Mouse.ready())
{
return false;
}
usbHid_Mouse.mouseMove(0, (int8_t)(motion[4]*mul_fac), (int8_t)(motion[3]*mul_fac));
// Serial.println("Sent mouse movement");
break;
case 3:
if (!usbHid_Controller.ready())
{
return false;
}
gp.x = (int8_t)(motion[1]*mul_fac);
gp.y = (int8_t)(motion[0]*mul_fac);
gp.z = (int8_t)(motion[4]*mul_fac);
gp.rz = (int8_t)(motion[3]*mul_fac);
usbHid_Controller.sendReport(0, &gp, sizeof(gp));
// Serial.println((int8_t)(motion[3]*mul_fac));
break;
default:
break;
}
lastSentAxes_ = axes;
}
if (sendButtons && buttonBits > 0) {
CurrentMode = (short)buttonBits;
if(buttonBits == 3){
delay(1000);
}
/*
ReportButtons btn{};
btn.bits = buttonBits & 0x0003;
usbHid_Spacemouse.sendReport(0x03, &btn, sizeof(btn));
*/
buttonBitsSent_ = buttonBits;
}
return true;
}
The modified HIDController.h file:
#pragma once
#include <Adafruit_TinyUSB.h>
#include <Arduino.h>
class HIDController {
public:
void begin();
void task();
bool sendReports(const float motion[6], uint16_t buttonBits);
private:
struct __attribute__((packed)) ReportAxes {
int16_t x, y, z, rx, ry, rz;
};
struct __attribute__((packed)) ReportButtons {
uint16_t bits;
};
static ReportAxes makeAxesReport(const float motion[6]);
bool axesReportChanged(const ReportAxes& axes) const;
Adafruit_USBD_HID usbHid_Spacemouse;
const float mul_fac = 0.3;//(sizeof(int8_t)/350);
Adafruit_USBD_HID usbHid_Mouse;
Adafruit_USBD_HID usbHid_Controller;
hid_gamepad_report_t gp;
uint16_t buttonBitsSent_ = 0;
ReportAxes lastSentAxes_{};
short CurrentMode = 1; //1 = spacemouse, 2 = mouse, 3 = controller
};The status of systemctl spacenavd.service:
● spacenavd.service - Spacenav driver daemon
Loaded: loaded (/usr/lib/systemd/system/spacenavd.service; enabled; preset: disabled)
Active: active (running) since Sat 2026-05-09 11:00:01 CEST; 3h 10min ago
Invocation: 4c63bf3497604be39fc0263af8d7190a
Main PID: 968 (spacenavd)
Tasks: 1 (limit: 74184)
Memory: 2.2M (peak: 3.2M)
CPU: 165ms
CGroup: /system.slice/spacenavd.service
└─968 /usr/bin/spacenavd
May 09 11:00:01 [REDACTED] systemd[1]: Starting Spacenav driver daemon...
May 09 11:00:01 [REDACTED] systemd[1]: Started Spacenav driver daemon.I don't really know what to do at this point. am i missing udev rules to make this work correctly or what could be the problem?
Offline