core-bluetooth-tool icon indicating copy to clipboard operation
core-bluetooth-tool copied to clipboard

unable to scan nintendo switch joystick

Open quantrpeter opened this issue 10 months ago • 4 comments

hi. unable to scan nintendo switch joystick, but my imac can connect to it. thanks Peter

quantrpeter avatar Jun 11 '25 05:06 quantrpeter

Is your Nintendo Switch Joystick perhaps a Classic Bluetooth device? CoreBluetooth (as in the underlying Apple framework) used to deal solely with BLE devices until 2019. I never have used CoreBluetooth to work with Bluetooth 3.0 devices, so that's probably why it can't be seen.

That said, I'd love to make it work with classic devices as well.

mickeyl avatar Jun 11 '25 09:06 mickeyl

my switch is bought around 2022, i don't know it is classic Bluetooth or not, here is the testing program. In my iMac, I can see my switch joystick:

Image
import ubluetooth as bluetooth
import time

ble = bluetooth.BLE()
ble.active(True)

# IRQ event values from MicroPython docs (not defined in module)
_IRQ_SCAN_RESULT = 5
_IRQ_SCAN_DONE = 6
_IRQ_PERIPHERAL_CONNECT = 7
_IRQ_PERIPHERAL_DISCONNECT = 8
_IRQ_GATTC_SERVICE_RESULT = 9
_IRQ_GATTC_CHARACTERISTIC_RESULT = 11
_IRQ_GATTC_READ_RESULT = 15

# Helper to extract device name from advertisement data
# (parses BLE advertising payload for Complete Local Name or Shortened Local Name)
def decode_name(adv_data):
    i = 0
    while i + 1 < len(adv_data):
        length = adv_data[i]
        if length == 0:
            break
        type = adv_data[i + 1]
        if type == 0x09 or type == 0x08:  # Complete Local Name or Shortened Local Name
            return adv_data[i + 2:i + 1 + length].decode('utf-8')
        i += 1 + length
    return None

# Store connection handle globally
g_conn_handle = None

# Callback for scan results
def bt_irq(event, data):
    global g_conn_handle
    if event == _IRQ_SCAN_RESULT:
        addr_type, addr, adv_type, rssi, adv_data = data
        name = decode_name(adv_data)
        # print('Found device:', name, addr)
        # Look for Nintendo controller name (e.g., 'Joy-Con', 'Pro Controller')
        if name and ('Joy-Con' in name or 'Pro Controller' in name):
            print('Nintendo controller found! Connecting...')
            ble.gap_connect(addr_type, addr)
    elif event == _IRQ_SCAN_DONE:
        print('Scan complete')
    elif event == _IRQ_PERIPHERAL_CONNECT:
        conn_handle, addr_type, addr = data
        g_conn_handle = conn_handle
        print('Connected to peripheral')
        # Start service discovery (see docs)
        ble.gattc_discover_services(conn_handle)
    elif event == _IRQ_PERIPHERAL_DISCONNECT:
        conn_handle, addr_type, addr = data
        print('Disconnected from peripheral')
        g_conn_handle = None
    elif event == _IRQ_GATTC_SERVICE_RESULT:
        conn_handle, start_handle, end_handle, uuid = data
        print('Service found:', uuid)
        # You can now discover characteristics if desired
    elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
        conn_handle, def_handle, value_handle, properties, uuid = data
        print('Characteristic found:', uuid)
    elif event == _IRQ_GATTC_READ_RESULT:
        conn_handle, value_handle, char_data = data
        print('Read result:', char_data)
    # Add more event handling as needed

ble.irq(bt_irq)

print('Make sure your Nintendo controller is in pairing mode (hold sync button until lights flash).')

print('Scanning for Nintendo Switch controllers for 30 seconds...')
ble.gap_scan(30000, 30000, 30000)  # Scan for 30 seconds

# Main loop (keep script alive)
while True:
    time.sleep(1)

quantrpeter avatar Jun 11 '25 16:06 quantrpeter

@mickeyl seems micropython not supporting Bluetooth classic , it only support BLE. So probably no way to make it work. thanks

quantrpeter avatar Jun 11 '25 16:06 quantrpeter

@quantrpeter: It's vice versa, classic devices might not work yet, but BLE devices should. What's the output for you when you call scan without any parameters? Does it show any devices in vicinity?

mickeyl avatar Jun 11 '25 18:06 mickeyl