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.
Hardware
Section titled “Hardware”| 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.
Identification (VID:PID)
Section titled “Identification (VID:PID)”| 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) |
Transport
Section titled “Transport”- USB: direct HID. The Pro Controller requires an
0x80 0x02handshake before HID traffic; the driver performs this on init. - Bluetooth Classic: HID over Bluetooth, paired through the OS (Windows
Settings → Devices, or
bluetoothctlon Linux).
Sample rate
Section titled “Sample rate”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.
Factory calibration
Section titled “Factory calibration”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.
Subcommands
Section titled “Subcommands”| 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 |
Rumble (HD Rumble)
Section titled “Rumble (HD Rumble)”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.
Axis convention
Section titled “Axis convention”Body frame is (x, z, -y) of the raw IMU output - gravity reads +Z when the
controller lies face-up.
Reset gestures
Section titled “Reset gestures”| Gesture | Action |
|---|---|
| Capture button | Reset Yaw |
| Home (short press) | Reset Yaw |
| Home (≥1 s hold) | Reset Full |
Quirks
Section titled “Quirks”- 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.