Branch: master->amiibo_edits
Emulate Nintendo Switch Controllers over Bluetooth.
Tested on Raspberry 4B Raspbian, should work on 3B+ too and anything that can do the setup.
Emulation of JOYCON_R, JOYCON_L and PRO_CONTROLLER. Able to send:
Install dependencies
Raspbian:
sudo apt install python3-dbus libhidapi-hidraw0 libbluetooth-dev bluez
Python: (a setup.py is present but not yet up to date)
Note that pip here has to be run as root, as otherwise the packages are not available to the root user.
sudo pip3 install aioconsole hid crc8
If you are unsure if the packages are properly installed, try running sudo python3
and import each using import package_name
.
setup bluetooth
bluetoothctl show
or bluetoothctl list
. Also a good indicator it the actual os reporting to not have bluetooth anymore.ExecStart
parameter in /lib/systemd/system/bluetooth.service
to ExecStart=/usr/lib/bluetooth/bluetoothd -C -P sap,input,avrcp
.\
This is to remove the additional reported features as the switch only looks for a controller.\
This also breaks all other Bluetooth gadgets, as this also disabled the needed drivers.input
plugin, only breaking bluetooth-input devices on your PC. Do so by changing ExecStart
to ExecStart=/usr/lib/bluetooth/bluetoothd -C -P input
instead.sudo systemctl daemon-reload
sudo systemctl restart bluetooth.service
There is a simple CLI (sudo python3 run_controller_cli.py
) provided with this app. Startup-options are:
usage: run_controller_cli.py [-h] [-l LOG] [-d DEVICE_ID]
[--spi_flash SPI_FLASH] [-r RECONNECT_BT_ADDR]
[--nfc NFC]
controller
positional arguments:
controller JOYCON_R, JOYCON_L or PRO_CONTROLLER
optional arguments:
-h, --help show this help message and exit
-l LOG, --log LOG BT-communication logfile output
-d DEVICE_ID, --device_id DEVICE_ID
not fully working yet, the BT-adapter to use
--spi_flash SPI_FLASH
controller SPI-memory dump to use
-r RECONNECT_BT_ADDR, --reconnect_bt_addr RECONNECT_BT_ADDR
The Switch console Bluetooth address (or "auto" for
automatic detection), for reconnecting as an already
paired controller.
--nfc NFC amiibo dump placed on the controller. Equivalent to
the nfc command.
To use the script:
start it (this is a minimal example)
sudo python3 run_controller_cli.py PRO_CONTROLLER
The cli does sanity checks on startup, you might get promps telling you they failed. Check the command-line options and your setup in this case. (Note: not the logging messages). You can however still try to proceed, sometimes it works despite the warnings.
Afterwards a PRO_CONTROLLER instance waiting for the Switch to connect is created.
If you didn't pass the -r
option, Open the "Change Grip/Order" menu of the Switch and wait for it to pair.
If you already connected the emulated controller once, you can use the reconnect option of the script (-r <Switch Bluetooth Mac address>
). Don't open the "Change Grip/Order" menu in this case, just make sure the switch is turned on. You can find out a paired mac address using the bluetoothctl paired-devices
system command or pass -r auto
as address for automatic detection.
After connecting, a command line interface is opened.
Note: Press \
Call "help" to see a list of available commands.
See the run_controller_cli.py
for an example how to use the API. A minimal example:
from joycontrol.protocol import controller_protocol_factory
from joycontrol.server import create_hid_server
from joycontrol.controller import Controller
# the type of controller to create
controller = Controller.PRO_CONTROLLER # or JOYCON_L or JOYCON_R
# a callback to create the corresponding protocol once a connection is established
factory = controller_protocol_factory(controller)
# start the emulated controller
transport, protocol = await create_hid_server(factory)
# get a reference to the state beeing emulated.
controller_state = protocol.get_controller_state()
# wait for input to be accepted
await controller_state.connect()
# some sample input
controller_state.button_state.set_button('a', True)
# wait for it to be sent at least once
await controller_state.send()
bluetoothctl
shows the connection constantly turning on and off. This means the switch tries initial pairing, you have to unpair the switch and try without the -r
option again.