Skip to content

Instantly share code, notes, and snippets.

@colemickens
Last active March 23, 2024 03:37
Show Gist options
  • Save colemickens/b08d1a339f4483c6b3c08e739d6cf5d0 to your computer and use it in GitHub Desktop.
Save colemickens/b08d1a339f4483c6b3c08e739d6cf5d0 to your computer and use it in GitHub Desktop.
amiibo-emulation-with-linux-vm.md

Easy Amiibo Emulation - https://bit.ly/2z0m09k

(^ that's a short-link to this page, so you can open it in Linux)

Some users are discussing this guide in #hacking on the JoyConDroid Discord: https://discord.gg/SQNEx9v.

DO NOT ask for, or share links to, Amiibo bins in the comments! They will be removed. Thank you for understanding.

(Windows|Linux PC) + JoyControl + Bluetooth = AMIIBO EMULATION

Video Guides

Overview

This guide shows you how to use joycontrol to emulate Amiibos. You only need a Bluetooth adapter, and to boot your PC temporarily into Linux! (or you can try to use a Linux VM in Windows, but it has more issues).

Thanks to @mart1nro for joycontrol and @spacemeowx2 for the Amiibo support!

See the bottom for Troubleshooting steps!

Step 1: Boot Linux

Skip this if you are running Linux.

Go ahead and download an Ubuntu disc image Go here, https://mirror.us.leaseweb.net/ubuntu-cdimage/xubuntu/releases/20.04/release/. Download xubuntu-20.04-desktop-amd64.iso.

You have two options now:

  1. WSL is not an option. WSL2 is not an option. If you're asking, Docker will almost guaranteedly not help you either.

  2. Boot from USB

    • DO NOT choose 'Install' when you boot Xubuntu! I am not responsible for you messing up your computer.

    • If you're making a bootable USB, make sure you right click on the ISO file and choose "Burn Image to Disc" (this will wipe your USB drive). You cannot just copy the ISO file onto a regular usb drive with other files.

    • There is a full guide here: How to make bootable Linux USB in Windows (use the xubuntu iso though!)

  3. Boot in a Virtual Machine

    • you can use VirtualBox or similar to boot Linux inside Windows
    • you will need to forward your Bluetooth adapter to the VM. This video, at this timestamp, does a good job of describing what to do. https://youtu.be/zvVNwrseZhg?t=350. This guide used to have slightly different instructions. Go ahead and enable Bluetooth like the video says. If you have Bluetooth issues, see Troubleshooting at the bottom.
    • make sure to allocate at least 3GB of RAM to avoid any freezing, or issues with running out of space during setup
    • you can theoretically "install" Xubuntu so that you don't have to repeat the joycontrol setup steps, but the install takes a while and is unnecessary if you just want to get this up and going once or even a few times (you can just leave the VM run for a few days depending on what your'e doing).

Step 2: Install JoyControl

Run these commands in the VM. You'll want to run these in a Terminal. You can open the Terminal by clicking "Applications" in the top-left corner and then choosing "Terminal" under "Accessories".

Note, these commands will require Internet access, but most VM providers will have Internet wired up to the VM by default. Configuring this is out-of-scope for this guide.

(If you need to open this page in the VM to copy/paste, this link (to this page) is shorter: https://bit.ly/2z0m09k.)

sudo true # hopefully sudo is happy

sudo apt-get update -qy
sudo apt-get upgrade -qy
sudo apt-get install -qy git python3-pip libglib2.0-dev libhidapi-hidraw0 libhidapi-libusb0 libdbus-1-dev
sudo pip3 install hid aioconsole crc8 dbus-python

mkdir -p ~/joycontrol
git clone https://github.com/mart1nro/joycontrol ~/joycontrol

Step 3: Quick Linux Path Guide (for Amiibo Files)

You need to get the amiibo bin files into the VM. You're on your own for that. If you put them in your "home" folder in Linux, that is /home/xubuntu. It's also sometimes shortened to ~. So ~/Downloads would mean /home/xubuntu/Downloads.

If you drag and drop an amiibo bin named foobar.bin into your home directory, the path would be /home/xubuntu/foobar.bin for example (that you will use later). If you were to use a browser and, as an example, download a backup from your OneDrive account, it will end up in ~/Downloads, and so you could pass /home/xubuntu/Downloads/foobar.bin to joycontrol, as shown below.

Step 4: Use JoyControl!

Notes:

  • If you have problems, you can press CTRL+c and it will kill the app. Also, you can tap the up arrow to pull up the last command and run it again.
  • Only send buttons to the Switch via this app. Do not press buttons on real controllers!
  • After the connection, press <Enter> in the terminal to get the >>> prompt

The following shows someone starting joycontrol, connecting, sending some button presses and then loading up the amiibo bin and activating the amiibo reading:

cd ~/joycontrol
sudo python3 ./run_controller_cli.py PRO_CONTROLLER

# connect the control
# then after the messages and connection, press <ENTER>

# now you can send commands:
# you can send buttons (pressing enter after each line)
home
a
b

# get the amiibo payload ready:
# (see above for what the path should be)
amiibo /home/xubuntu/Downloads/backup-of-my-amiibo.bin

# activate the final dialog to start the NFC/amiibo read
a

Troubleshooting

  • Anything

    Try a few times! Things seem to be a bit flakey, even in pretty ideal conditions...

    Also, try another adapter. People seem to really struggle with the internal laptop adapters and report more luck when they try when they find lying around.

  • OSError: [Errno 97] Address family not supported by protocol

    You can't use WSL (neither WSL1 nor WSL2). If you're still getting this error, please give lots of details about anything you might have done differently.

  • The virtual joycon disconnects when I leave the Grip screen

    You might get an error like this:

    ERROR - [Errno 104] Connection reset by peer [19:39:05] joycontrol.protocol connection_lost::121
    ERROR - Connection lost.
    

    Few things:

    1. Do not touch the real joycons or controller! Remove the joycons entirely, if possible, from the system. Remove other pro controllers.
    2. Send all buttons from the joycontrol app, instead of pressing the real buttons. You should get the game all ready to read the amiibo, then do the steps to attach the controller. Then send the final buttons to get back to the game and activate the amiibo.
    3. If you've done these things and it still disconnects when you leave the Grip screen, then you might be having Bluetooth issues. If this is the case, check your BT forwarding to your VM setup. Try booting into Linux on a USB instead. Or try another Bluetooth adapter.
  • OSError: [Errno 98] Address already in use

    Check two things:

    1. It's likely that you have joycontrol running already. Run ps aux | grep joycontrol. Does it look like there are two sets running. Try to kill them, or reboot.

    2. If you're sure that's not it, you can try this workaround, but it really shouldn't be necessary almost ever. (details)

      sudo sed -i 's|^ExecStart=/usr/lib/bluetooth/bluetoothd.*$|ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=input|g' /lib/systemd/system/bluetooth.service
      sudo systemctl daemon-reload
      sudo systemctl restart bluetooth

      If this still doesn't help, it's the other one...

Old Troubleshooting

These steps are not really recommended by me anymore. I think they tend to cause more problems than good.

Windows + VirtualBox Workaround

You may need to disable your BT adapter so VirutalBox can control it:

  1. Go into Device Manager

    • Find your Bluetooth adapter
    • Right-click -> Disable
  2. Go into Windows Services

    • Disable THREE Bluetooth services:
      • "Bluetooth Audio Gateway Service"
      • "Bluetooth Support Service"
      • "BluetoothUserService_xxxx"

MANY USERS are reporting that they re-enabled the devices in Hardware Manager after the VM booted and THEN were able to complete the steps successfully.

Known Good Setups

  1. Raspberry Pi 4 with built-in Bluetooth + Raspbian
  2. Raspberry Pi 0 with built-in Bluetooth + Raspbian

(it's possible a few steps are slightly different on Raspbian)

@sarahgagag
Copy link

hii!
i get this rly annozing issue when running the $ sudo python3 ./run_controller_cli.py PRO_CONTROLLER

sarah@sarah-VirtualBox:~/joycontrol$ sudo python3 ./run_controller_cli.py PRO_CONTROLLER
Traceback (most recent call last):
File "./run_controller_cli.py", line 10, in
from joycontrol import logging_default as log, utils
File "/home/sarah/joycontrol/joycontrol/utils.py", line 5, in
import hid
File "/usr/local/lib/python3.8/dist-packages/hid/init.py", line 83, in
hidapi.hid_get_input_report.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_size_t]
File "/usr/lib/python3.8/ctypes/init.py", line 386, in getattr
func = self.getitem(name)
File "/usr/lib/python3.8/ctypes/init.py", line 391, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0: undefined symbol: hid_get_input_report

message me on discord isatonmycat9137 if you can help me please

@whatislogic8
Copy link

need some help. ive input "sudo pip3 install hid aioconsole crc8 dbus-python" and the program keeps saying "sudo pip3 command not found". doesnt matter if it was typed in or pasted, cant get it to work. (also apologies in advance, ive never done thing before)

@MonsterDruide1
Copy link

need some help. ive input "sudo pip3 install hid aioconsole crc8 dbus-python" and the program keeps saying "sudo pip3 command not found". doesnt matter if it was typed in or pasted, cant get it to work. (also apologies in advance, ive never done thing before)

You seem to have missed the step right above it: sudo apt-get install -qy git python3-pip libglib2.0-dev libhidapi-hidraw0 libhidapi-libusb0 libdbus-1-dev

@menlover22
Copy link

When I type in sudo python3 ./run_controller_cli.py PRO_CONTROLLER, I get a pairing request from a switch with a different MAC address than mine. Not sure what to do.

@ThatOtterGuy
Copy link

ThatOtterGuy commented Sep 26, 2022

I'm getting this error:
Traceback (most recent call last):
File "./run_controller_cli.py", line 10, in
from joycontrol import logging_default as log, utils
File "/home/khryaus/joycontrol/joycontrol/utils.py", line 5, in
import hid
File "/usr/local/lib/python3.8/dist-packages/hid/init.py", line 83, in
hidapi.hid_get_input_report.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_size_t]
File "/usr/lib/python3.8/ctypes/init.py", line 386, in getattr
func = self.getitem(name)
File "/usr/lib/python3.8/ctypes/init.py", line 391, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0: undefined symbol: hid_get_input_report

@menlover22
Copy link

Does anyone know how to change the device class on this vm? Also, the pairing requests I get are from a switch with a different MAC address than mine. Still not sure what to do

@yoyotam3
Copy link

I keep getting disconnects as soon as I leave the change grip/order screen

@TheOriginalGOC
Copy link

can you help me solve this issue? I tried many times to build VMs but the result is the same

Traceback (most recent call last): File "./run_controller_cli.py", line 10, in from joycontrol import logging_default as log, utils File "/home/t/joycontrol/joycontrol/utils.py", line 5, in import hid File "/usr/local/lib/python3.8/dist-packages/hid/init.py", line 83, in hidapi.hid_get_input_report.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_size_t] File "/usr/lib/python3.8/ctypes/init.py", line 386, in getattr func = self.getitem(name) File "/usr/lib/python3.8/ctypes/init.py", line 391, in getitem func = self._FuncPtr((name_or_ordinal, self)) AttributeError: /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0: undefined symbol: hid_get_input_report

I was able to get past this with pip install hid==1.0.4

But now just gets stuck at Please open the "Change Grip/Order" menu; it does the pairing request, I accept and it just keeps asking.

@akariifx
Copy link

akariifx commented Mar 27, 2023

I was able to get past this with pip install hid==1.0.4

But now just gets stuck at Please open the "Change Grip/Order" menu; it does the pairing request, I accept and it just keeps asking.

I was also able to get past this using pip install hid==1.0.4

however, it does the same thing as @TheOriginalGOC . Anyone find a solution to this yet?

@Chickpeaplane
Copy link

I have been trying to do this as well, but I am heving the same problem as @akariifx and @TheOriginalGOC. It asks me to accept a pairing request with my switch and when I acceept, nothing happens, and it asks me again 30 seconds later. Anyone know how to fix this yet?

@Legarad
Copy link

Legarad commented May 19, 2023

How unpair?

@evilmilk2008
Copy link

When I try to run Joycontrol, I get this error:

Traceback (most recent call last):
  File "./run_controller_cli.py", line 328, in <module>
    loop.run_until_complete(
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "./run_controller_cli.py", line 284, in _main
    transport, protocol = await create_hid_server(factory, reconnect_bt_addr=args.reconnect_bt_addr,
  File "/home/amiibo/joycontrol/joycontrol/server.py", line 94, in create_hid_server
    hid.discoverable()
  File "/home/amiibo/joycontrol/joycontrol/device.py", line 48, in discoverable
    self.properties.Set(self.adapter.dbus_interface, 'Discoverable', boolean)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 141, in __call__
    return self._connection.call_blocking(self._named_service,
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 652, in call_blocking
    reply_message = self.send_message_with_replyTraceback (most recent call last):
  File "./run_controller_cli.py", line 328, in <module>
    loop.run_until_complete(
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "./run_controller_cli.py", line 284, in _main
    transport, protocol = await create_hid_server(factory, reconnect_bt_addr=args.reconnect_bt_addr,
  File "/home/amiibo/joycontrol/joycontrol/server.py", line 94, in create_hid_server
    hid.discoverable()
  File "/home/amiibo/joycontrol/joycontrol/device.py", line 48, in discoverable
    self.properties.Set(self.adapter.dbus_interface, 'Discoverable', boolean)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 141, in __call__
    return self._connection.call_blocking(self._named_service,
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 652, in call_blocking
    reply_message = self.send_message_with_reply_and_block(
dbus.exceptions.DBusException: org.bluez.Error.Failed: Not Powered
_and_block(
dbus.exceptions.DBusException: org.bluez.Error.Failed: Not Powered

Does anyone know how to fix it?

@joodle229
Copy link

hi, i did everything the guide instructed but i get this error whenever i use the pro controller command in joycontrol:
AttributeError: /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0: undefined symbol: hid_get_input_report
what should i do to fix it? thanks!

@Malo1301
Copy link

When I try to connect to my Switch, it shows my console in the bluetooth menu for 2 seconds then disconnects, and the Switch never find the virtual controller. I'm using Ubuntu 23.10 on a Legion 5 15ACH6H with the internal Bluetooth adapter, I don't have any external bluetooth adapters.

@steelmonkey
Copy link

hi, i did everything the guide instructed but i get this error whenever i use the pro controller command in joycontrol: AttributeError: /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0: undefined symbol: hid_get_input_report what should i do to fix it? thanks!

i had the same issue turns out you need to uninstall the old hid and then install the new one in sudo using these two commands

sudo pip uninstall hid
sudo pip install hid==1.0.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment