如何读取Nintendo Switch Joycons输入并将双Joycon合并为单控制器使用
任天堂Switch Joycon 输入读取与合并解决方案
连接失败问题修复
你当前使用pybluez的代码无法连接的核心原因是:Joycon采用低功耗蓝牙(BLE)协议通信,而你写的代码调用的是经典蓝牙的RFCOMM套接字,二者协议不匹配。且pybluez对BLE的跨平台支持度较差,不推荐用来做Joycon的连接开发。
joycon-python 摇杆偏差修复
摇杆数据存在偏差是因为你没有读取Joycon固件内置的出厂校准参数,直接使用了原始ADC采样值,joycon-python库本身已经封装了校准数据读取逻辑,按如下方式初始化即可拿到校准后的准确数据:
from pyjoycon import JoyCon, get_L_id, get_R_id # 自动识别配对的左右Joycon并初始化,自动加载校准参数 joycon_left = JoyCon(*get_L_id()) joycon_right = JoyCon(*get_R_id()) # 读取校准后的摇杆值,范围为[-1, 1] left_x, left_y = joycon_left.get_stick_left_analog() right_x, right_y = joycon_right.get_stick_right_analog()
如果仍有微小漂移,可以自行添加死区过滤逻辑:当摇杆数值绝对值小于设定阈值(比如0.05)时直接返回0即可。
双Joycon合并为单个控制器
你可以通过创建虚拟游戏手柄的方式,将两个Joycon的输入映射到同一个虚拟手柄上,实现合并为单个控制器的效果,不同平台的实现方案如下:
- Windows平台:使用
vgamepad库创建虚拟Xbox 360手柄 - Linux平台:使用
python-uinput库创建虚拟手柄 - Mac平台:使用
pyobjc调用VirtualHID框架实现
以下是Windows平台的示例代码:
import vgamepad as vg from pyjoycon import JoyCon, get_L_id, get_R_id # 初始化虚拟Xbox手柄 virtual_pad = vg.VX360Gamepad() # 初始化两个Joycon joycon_l = JoyCon(*get_L_id()) joycon_r = JoyCon(*get_R_id()) while True: # 刷新两个Joycon的状态 joycon_l.get_status() joycon_r.get_status() # 摇杆映射:左Joycon左摇杆 -> 虚拟手柄左摇杆,右Joycon右摇杆 -> 虚拟手柄右摇杆 virtual_pad.left_joystick_float( x_value_float=joycon_l.left_stick_analog_x, y_value_float=joycon_l.left_stick_analog_y ) virtual_pad.right_joystick_float( x_value_float=joycon_r.right_stick_analog_x, y_value_float=joycon_r.right_stick_analog_y ) # 按键映射示例,可按需调整 # 左Joycon按键映射 if joycon_l.button_a: virtual_pad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A) else: virtual_pad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_A) if joycon_l.button_l: virtual_pad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_SHOULDER) else: virtual_pad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_LEFT_SHOULDER) # 右Joycon按键映射 if joycon_r.button_b: virtual_pad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_B) else: virtual_pad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_B) if joycon_r.button_r: virtual_pad.press_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_RIGHT_SHOULDER) else: virtual_pad.release_button(vg.XUSB_BUTTON.XUSB_GAMEPAD_RIGHT_SHOULDER) # 提交虚拟手柄状态更新 virtual_pad.update()
注意事项
- 运行代码前需要先将两个Joycon和电脑完成配对:按住Joycon侧面的配对按键直到指示灯闪烁,在系统蓝牙设置中完成配对即可
- Linux平台运行时需要给当前用户开放蓝牙操作和uinput的读写权限,否则会出现权限报错
- 可以根据自身使用需求调整按键、摇杆的映射规则
内容的提问来源于stack exchange,提问作者qwerty
相关产品推荐
相关产品推荐

