Konubinix' opinionated web of thoughts

Connect to a Wiimote

Fleeting

wiimote

using bluez

Following the documentation of https://github.com/xwiimote/xwiimote and using https://github.com/TurpIF/PyWiimote as an example.

  1. press 1 + 2 on the wiimote

  2. find the device

    import bluetooth
    return bluetooth.discover_devices()
    
    ['CC:9E:00:B9:7F:EF']
    
  3. keep pressing 1 + 2

  4. connect to the device and listen to some events once connected

    from bluetooth import BluetoothSocket, L2CAP
    s = BluetoothSocket(L2CAP)
    s.connect(('CC:9E:00:B9:7F:EF', 0x13))
    return [s.recv(16) for i in range(10)]
    
    [b'\xa10\x00\x03', b'\xa10\x00\x02', b'\xa10\x00\x00', b'\xa10\x00\x08', b'\xa10\x00\x00', b'\xa10\x01\x00', b'\xa10\x00\x00', b'\xa10\x02\x00', b'\xa10\x00\x00', b'\xa10\x08\x00']
    
  5. in the future, it helps first running the program, then pressing 1 and 2. The first received data will be about 1 and 2.

  6. map the received data to pressed buttons

    • relaxed state: b’\xa10\x00\x00'
    • 1: b’\xa10\x00\x02'
    • 2: b’\xa10\x00\x01'
    • home: b’\xa10\x00\x80'
    • -: b’\xa10\x00\x10'
    • +: b’\xa10\x10\x00'
    • A: b’\xa10\x00\x08'
    • down: b’\xa10\x04\x00'
    • up: b’\xa10\x08\x00'
    • right: b’\xa10\x02\x00'
    • left: b’\xa10\x01\x00'
    • z: b’\xa10\x00\x04'
    • unplug nunchuk: b’\xa1 \x00\x00\x00\x00\x00c'
    • plug nunchuk: b’\xa1 \x00\x00\x02\x00\x00c'

Once the nunchuk is plugged, the device stops sending data.

To control the device

  • vibration

    from bluetooth import BluetoothSocket, L2CAP
    import time
    s = BluetoothSocket(L2CAP)
    s.connect(('CC:9E:00:B9:7F:EF', 0x11))
    s.send(''.join(map(chr, (0x52, 0x15, 0x01))))
    time.sleep(1)
    s.send(''.join(map(chr, (0x52, 0x15, 0x00))))
    

    receive b’\xa1 \x00\x00\x00\x00\x00b' b’\xa1 \x00\x00\x00\x00\x00a'

  • led number can be 0 (no led, 1 to 4)

    from bluetooth import BluetoothSocket, L2CAP
    import time
    s = BluetoothSocket(L2CAP)
    s.connect(('CC:9E:00:B9:7F:EF', 0x11))
    s.send(''.join(map(chr, (0x52, 0x11, int(number << 4)))))
    

    Nothing received

  • ask to get only the buttons

    from bluetooth import BluetoothSocket, L2CAP
    import time
    s = BluetoothSocket(L2CAP)
    s.connect(('CC:9E:00:B9:7F:EF', 0x11))
    n = 1
    s.send(''.join(map(chr, (0x52, 0x12, 0x00, 0x30))))
    

    receive b’\xa10\x00\x00'

  • buttons + acceleration

    from bluetooth import BluetoothSocket, L2CAP
    import time
    s = BluetoothSocket(L2CAP)
    s.connect(('CC:9E:00:B9:7F:EF', 0x11))
    n = 1
    s.send(''.join(map(chr, (0x52, 0x12, 0x00, 0x31))))
    

    Receive a lot of acceleration data b’\xa11\x00@\x8a\x7f\x94' b’\xa11`@\x88\x7f\x94' b’\xa11\x00`\x87~\x97' b’\xa11`\x00\x85\x7f\x9b' b’\xa11 `\x84\x7f\x9c' b’\xa11@ \x82\x7f\x9c' b’\xa11 \x00\x81\x7f\x9b' b’\xa11 \x00\x80~\x9b'

in android

Something like this should do it in my a python runtime on android. Yet it seems that the support for low level bluetooth stuff in the android API was introduced very late (android 10) .

And even in android 11, the connection stalled in my few attempts to make it work.

def run():
    from jnius import autoclass
    from android.broadcast import BroadcastReceiver

    from jnius import autoclass, cast
    from android.broadcast import BroadcastReceiver

    # Import necessary Java classes
    BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
    BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice')
    BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket')
    UUID = autoclass('java.util.UUID')
    # Get BluetoothAdapter and IntentFilter classes
    BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter')
    IntentFilter = autoclass('android.content.IntentFilter')

    # Get the default Bluetooth adapter
    bluetooth_adapter = BluetoothAdapter.getDefaultAdapter()


    # Define the target device's address and L2CAP port
    l2cap_psm = 0x13  # L2CAP Protocol/Service Multiplexor (PSM) value
    # Get the Bluetooth adapter and the remote device
    bluetooth_adapter = BluetoothAdapter.getDefaultAdapter()
    if not bluetooth_adapter:
        raise Exception("Bluetooth is not supported on this device")

    if not bluetooth_adapter.isEnabled():
        raise Exception("Bluetooth is not enabled")

    device_address = "CC:9E:00:B9:7F:EF"

    device = bluetooth_adapter.getRemoteDevice(device_address)

    print("Create an L2CAP socket")
    socket = device.createInsecureL2capChannel(l2cap_psm)
    print("connecting")
    # Connect to the remote device
    socket.connect()

    print("Receive data")
    try:
        input_stream = socket.getInputStream()
        for i in range(10):
            buffer = bytearray(16)
            num_bytes = input_stream.read(buffer)
            print(buffer[:num_bytes])
    finally:
        socket.close()