Skip to content

Joy-Con 1 / Switch Pro

Status: hardware-validated (Joy-Con L/R and Pro Controller).

The first-generation Joy-Con and the Switch Pro Controller share one HID protocol. They connect over USB or Bluetooth Classic and expose a 6-axis IMU with no magnetometer.

Component Part Range / scale
IMU (genuine) STMicroelectronics LSM6DS3-TR-C accel ±8 g (4096 LSB/g), gyro ±2000 dps (16.4 LSB/dps)
IMU (clones) InvenSense ICM-20600 or similar auto-detected via SPI ID; slower bias warm-up

The MEMS core is polled internally at roughly 740 Hz and decimated to three fresh samples per input report (never duplicated). Clones commonly appear on the grey market; their SPI calibration reads may return zeros, in which case fusion absorbs the bias over a slightly longer warm-up.

VID:PID Device
057E:2006 Joy-Con L
057E:2007 Joy-Con R
057E:2009 Switch Pro Controller
057E:200E Charging Grip (proxies its docked Joy-Cons; connect them over Bluetooth instead)
  • USB: direct HID. The Pro Controller requires an 0x80 0x02 handshake before HID traffic; the driver performs this on init.
  • Bluetooth Classic: HID over Bluetooth, paired through the OS (Windows Settings → Devices, or bluetoothctl on Linux).

Input report 0x30 carries 3 IMU samples per packet. All three are decoded - reading only the first would halve the effective rate. The packet period is set by the negotiated Bluetooth link interval, not by a fixed IMU ODR, so the delivered rate sits around 200 Hz and varies with the host’s radio. The fusion timestep is measured live from the real per-sample period rather than assumed.

Read over SPI with subcommand 0x10:

Source Region Notes
Factory accel 0x6020 offsets + scales
Factory gyro 0x603D offsets + scales
User override 0x8010 / 0x8028 gated by magic bytes

Rest bias is also estimated on-device after ~30 s of stillness.

ID Purpose
0x40 Enable IMU
0x30 Player LEDs (bits 3:0 solid, 7:4 flashing)
0x38 Home LED (Joy-Con R + Pro; up to 15 mini-cycles)
0x48 HD rumble enable
0x10 SPI read

Vibration must be enabled first (0x48 0x01) or rumble is silently ignored. Each side takes a 4-byte packed frame (high-freq bits, high-amp, low-freq, low-amp); the neutral silence frame is 00 01 40 40. Both sides must be sent even when driving only one. Useful frequency range is 40-1252 Hz.

Body frame is (x, z, -y) of the raw IMU output - gravity reads +Z when the controller lies face-up.

Gesture Action
Capture button Reset Yaw
Home (short press) Reset Yaw
Home (≥1 s hold) Reset Full
  • After bonding, the controller may sleep; the first input report can take ~1.5 s. The driver re-issues the IMU-enable on the first timeout.
  • With no magnetometer, yaw drifts on body rotation - re-yaw facing forward or use Reset Mounting.
  • NFC, the IR camera, and Ring-Con are intentionally left unused: they consume bandwidth that would starve the IMU rate.