1

Goal

I have a HITSLAM Camera Shutter Bluetooth button (which is a AB Shutter 3 device, a common Bluetooth camera remote control) which I want to connect to my NVIDIA Jetson Nano using Bluetooth, so that I can use the button's input for some task.

What I Have Done

I am using the PyBluez library for connecting. I use the following to find out which port and protocol the AB Shutter 3 uses (where target_device_address is the AB Shutter 3's device address):

service_matches = bt.find_service(name=None,uuid=None,address=target_device_address)
first_match = service_matches[0]
print("Port {}, Name {}, Host {}, Protocol {}".format(first_match['port'], first_match['name'], first_match['host'], first_match['protocol']))

This is how I get the port (17) which to connect to and the protocol (L2CAP) it uses.

Now, I try to connect to it using the following:

client_sock = bt.BluetoothSocket(bt.L2CAP)
client_sock.connect((target_device_address,port))

I have also used Python's native socket library (which have yielded me the same results):

client_sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
client_sock.connect((target_device_address,port))

Which it successfully connects according to hcitool, after which I wait for user input:

if target_device_address in (subprocess.getoutput("hcitool con")).split():
    print('connected')
    while True:
        data = client_sock.recv(1024)
        print(str(data))

Issues

  • The device actually does not show up as an input in /dev/input/. When I connect it manually through the GUI, it shows up as /dev/input/event5.
  • After connecting, there is no input captured by my script.

My Questions

  • How does it connect according to hcitool con yet not be registered as an input device (and register any inputs)?
  • What do you suggest doing? I have looked everywhere and do not seem to get a proper solution. There is a workaround with implementing a bash script that uses bluetoothctl to connect to the Bluetooth remote control, but it just does not make sense to me why Python cannot make this connection and retrieve information.

1 Answers1

3

My recommendation would be not to use hcitool as it was deprecated back in 2017.

I prefer to use the BlueZ D-Bus API directly which is documented at: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt

This can be accessed in Python using the pydbus library

I am going to assume your Bluetooth adapter is on hci0 on the Jetson but you can check this with:

$ busctl tree org.bluez
└─/org
  └─/org/bluez
    └─/org/bluez/hci0

This would make the code something like:

import pydbus

DEVICE_ADDR = '11:22:22:E7:CE:BE'

# DBus object paths
BLUEZ_SERVICE = 'org.bluez'
ADAPTER_PATH = '/org/bluez/hci0'
device_path = f"{ADAPTER_PATH}/dev_{DEVICE_ADDR.upper().replace(':', '_')}"

# setup dbus
bus = pydbus.SystemBus()
mngr = bus.get(BLUEZ_SERVICE, '/')
adapter = bus.get(BLUEZ_SERVICE, ADAPTER_PATH) 
device = bus.get(BLUEZ_SERVICE, device_path)

device.Connect()

This should create the event at /dev/input/ and I would use the python library evdev to get the inputs as was done in the following question: https://stackoverflow.com/a/54765300/7721752

ukBaz
  • 6,985
  • 2
  • 8
  • 31
  • Thank you so much! This is exactly what I needed - it makes sense because I am trying to actually connect to a device, not create a socket for exchange of data. One interesting thing to note is that when I tried to connect to the device using the device address I had previously, it actually changed. So moving forward, I would use `PyBluez` to search for the shutter and get the device address, then use `pydbus` to connect to it. – codeabiswas Feb 26 '21 at 15:48