Skip to content

Nintendo 3DS / 2DS

Status: implemented; axis remap and accel scale pending live-console validation.

The 3DS, New 3DS, 2DS, and New 2DS XL all carry a full 6-axis IMU - a 3-axis accelerometer and a 3-axis gyroscope - making them good trackers, roughly Joy-Con 1 tier and far better than a single-axis pad. The console can’t be driven over USB or Bluetooth, so a homebrew app runs on the 3DS and streams raw IMU over UDP.

Aspect Value
Protocol UDP, bridge binds 0.0.0.0:9305
Direction 3DS → bridge (one-way, no back-channel)
Identity sender IP (one console = one tracker)
Rate ~100 Hz (homebrew loop, 10 ms sleep)
Config plain server IP in a server.cfg on the SD card
struct ImuPacket { // 12 bytes, packed
s16 ax, ay, az; // accelerometer
s16 gx, gy, gz; // gyroscope
};
Offset Field
0x00 Accel X (i16 LE)
0x02 Accel Y
0x04 Accel Z
0x06 Gyro X (i16 LE)
0x08 Gyro Y
0x0A Gyro Z

No header, sequence, or checksum - validate length == 12 and drop otherwise.

  • Gyro: rad/s = raw × 0.00125 (≈ 0.0716 °/s per LSB).
  • Accel: the raw count per g varies by revision, so the driver auto-scales to gravity - over the first ~100 samples it computes division = 9.80665 / mean(|a|) and applies m/s² = raw × division. No magic LSB/g constant.

accel = (ax, az, ay) × division, gyro = (−gx, −gy, −gz) × 0.00125. Ported from a known-working forwarder; the accel swaps Y↔Z while the gyro only negates. This is confirmed empirically elsewhere but pending validation on eimu hardware - bring up a live console, confirm gravity reads +Z screen-up, and confirm the gyro sign agrees with accel-derived rotation before treating it as canonical.

Straight 6-axis: accel (m/s²) + gyro (rad/s). No magnetometer, so yaw is gyro-integrated with motion-based bias correction - slow drift, recenter with Reset Yaw.

  • No buttons in the packet, so there is no on-device reset gesture - use software recenter until the homebrew is extended.
  • No battery or rumble on the wire.
  • Old-3DS Wi-Fi is 2.4 GHz b/g; UDP loss is tolerated (fusion coasts over a dropped frame).