Bluetooth Development Beginners Guide

Ask software engineering and SDK questions for developers working on Mac OS X, Windows or Linux.
  • Author
  • Message
Offline

sinaroughani

  • Posts: 6
  • Joined: Mon Mar 16, 2020 8:13 pm
  • Real Name: Sina Roughani

Bluetooth Development Beginners Guide

PostFri Apr 03, 2020 10:19 pm

Hello,
For others interested in getting started with bluetooth control of the camera, I have developed a framework which you can use and adapt freely.
On a GNU/Linux system install bluez.
On Ubuntu this is
Code: Select all
sudo apt-get install bluez bluetooth

But bluez is widespread and available in many package managers.
Then use bluetoothctl to trust, scan, pair, connect to your camera. Bluetoothctl is interactive, autocompletes, is enough to access all the bluetooth features we care about, and I've been able to script it. I am currently looking for more elegant solutions.
Code: Select all
bluetoothctl
*entering the bluetoothctl shell*
[bluetooth]#agent on
[bluetooth]#scan on

Then you'll see the named devices available, pick your device ID, XX:XX:XX:XX:XX:XX
Code: Select all
[bluetooth]#scan off
[bluetooth]#trust XX:XX:XX:XX:XX:XX
[bluetooth]#pair XX:XX:XX:XX:XX:XX

You will be prompted for the 6 digit passkey/PIN and it will cancel a couple of times, just enter pair XX:XX:XX:XX:XX:XX again and it should work eventually and let you enter it successfully from the camera's bluetooth menu. Then you can connect and access the GATT data
Code: Select all
[bluetooth]#connect XX:XX:XX:XX:XX:XX
[bluetooth]#menu gatt
[bluetooth]#list-attributes

You can see all of them and their UUID's, but only 2 are super important.
The Outgoing Camera Control (encrypted) from the development guide
/org/bluez/hci0/dev_D0_CF_5E_38_42_91/service000b/char000c
UUID:5dd3465f-1aee-4299-8493-d2eca2f8e1bb

And the Incoming Camera Control (encrypted)
/org/bluez/hci0/dev_D0_CF_5E_38_42_91/service000b/char000e
UUID:b864e140-76a0-416a-bf30-5876504537d9

5dd3... is the attribute that we can write to to change focus, ISO, record, etc.
b864...is the attribute that we can request notifications from to know what's happening to the camera
Let's examine the Incoming Camera Control first
Code: Select all
[bluetooth]#select-attribute /org/bluez/hci0/dev_D0_CF_5E_38_42_91/service000b/char000e
or
[bluetooth]#select-attribute b864e140-76a0-416a-bf30-5876504537d9
[bluetooth]#notify on

Now you'll see junk passing through your screen, but go ahead and pull focus on a lens with electronics inside and you'll see the focus distance in millimeters! We're done with this so turn that off, and let's look at the Outgoing Camera Control
Code: Select all
[bluetooth]#notify off
[bluetooth]#select-attribute /org/bluez/hci0/dev_D0_CF_5E_38_42_91/service000b/char000c
or
[bluetooth]#select-attribute 5dd3465f-1aee-4299-8493-d2eca2f8e1bb

The most critical part about this, with limited documentation available is that when you write commands you need to group your bytes within parentheses! You can use hex or decimal values. Here's the command to focus.
1st byte addresses camera 1 so we say 1
2nd byte says we send 8 bytes on top of the 4 byte header, so we say 8
3rd byte says we're sending a command, so we say 0
4th byte is reserved for future use by BM, so we say 0, thus ends the header
5th byte says we pick the 0th category group , "Lens" so we say 0
6th byte says we pick the 0th parameter of the group, "Focus", so we say 0
7th byte says the data type we are manipulating is a fixed, signed 5.11 number, defined as type 128 in the manual, so we say 128
8th byte says we are setting (0) or adding (1) the value, since we are setting, we say 0, thus ends the command
9th byte says the second byte of the 5.11 number we set/offset*
10th byte says the first byte of the 5.11 number we set/offset*
11th byte is padding up to a 4-byte/32-bit multiple message length
12th byte is padding up to a 4-byte/32-bit multiple message length
So our message was 12 bytes/96 bits long and set the focus to a value.
*The 16 bit focus position data is encoded Least Significant BYTE first, so when we write the maximum 0x0800, we actually write 0x00 0x08, and when we write 0x0001, we actually write 0x01 0x00, this was pretty confusing initially.
Here, I'll set the focus to 0.9995, and demonstrate using hex and numbers
Code: Select all
[bluetooth]#write "0x01 0x08 0x00 0x00 0x00 0x00 0x80 0x00 0xff 0x07 0x00 0x00"
or
[bluetooth]#write "1 8 0 0 0 0 128 0 255 7 0 0"

Now let's look at the command to set the codec to BRAW 8:1. From the developer guide, we see this is the 10th group, parameter 0, with 2 bytes of data, the first being 3, the second being 4, of type int8 or 1
Code: Select all
[bluetooth]#write "0x01 0x08 0x00 0x00 0x0a 0x00 0x01 0x00 0x03 0x04 0x00 0x00"
or
[bluetooth]#write "1 8 0 0 10 0 1 0 3 4 0 0"

Now that's great, but can I script it? Yes, you could use the program, "expect", as per my Github project
But bash seems to be able to quickly spawn bluetoothctl just as well, not as flexible as expect though.
Code: Select all
#!/bin/bash
bluetoothctl << EOF
devices
agent on
connect XX:XX:XX:XX:XX:XX
menu gatt
select-attribute 5dd3465f-1aee-4299-8493-d2eca2f8e1bb
write "0x01 0x08 0x00 0x00 0x00 0x00 0x80 0x00 0xff 0x07 0x00 0x00"
EOF

How about including this in my Python or C program? PyBluez seems to be unstable on my system, so I'm gonna be looking into the bluez library to implement C-based commands. I'll add a reply when I get that figured out.
Now you know How to Train your Dragon...errr.... cinema camera... Red uses a different command structure, but you'll still be able to use bluetoothctl in that, too.
Please include any information you dig up on this post so we can improve everybody's experience and possibilities with this camera!

Here is a link to my Github project where I share my code in use in a LIDAR TOF autofocus system. Beat that, Canon! (they could easily beat that)
https://github.com/rgbbytes/blackmagic- ... h-control/
Offline

Firedan1176

  • Posts: 6
  • Joined: Tue Dec 04, 2018 4:24 am
  • Real Name: Daniel Moore

Re: Bluetooth Development Beginners Guide

PostMon Jun 15, 2020 5:50 pm

I've worked on several github repos to extend and implement BMCC bluetooth control (particularly for Android), but it seems we're a few firmware versions ahead to make full use of the documentation. I'm planning to manually test and brute force packet info to the device to see which features we can control through trial and error. Would you be interested in contributing to a community guide and/or utility to control over Bluetooth?
Offline

sinaroughani

  • Posts: 6
  • Joined: Mon Mar 16, 2020 8:13 pm
  • Real Name: Sina Roughani

Re: Bluetooth Development Beginners Guide

PostThu Sep 17, 2020 2:39 am

Hello, I'd like to say that I greatly admire Grant Petty on a spiritual level and find it super cool that he's willing to release the latest August camera update which fixes the issue which causes bluetooth to stop responding on the camera, leading me to try SIX bluetooth adapters and yet still fail. Sorry, it's really late and I'm tired. Now, the above guide I have provided will work flawlessly and I will unveil by bluetooth rangefinder soon! Won't be selling it though as the Bluetooth SIG are a bunch of greedy suits and charge a mafia fee of $8000 per product which doesn't make sense for selling 10 rangefinders... Again, love everything you do Grant!
-Sina
Offline

briwil

  • Posts: 3
  • Joined: Fri Sep 25, 2020 10:41 pm
  • Real Name: Brian Williams

Re: Bluetooth Development Beginners Guide

PostTue Oct 06, 2020 5:18 pm

sinaroughani wrote:7th byte says the data type we are manipulating is a fixed, signed 5.11 number, defined as type 128 in the manual, so we say 128
8th byte says we are setting (0) or adding (1) the value, since we are setting, we say 0, thus ends the command
9th byte says the second byte of the 5.11 number we set/offset*
10th byte says the first byte of the 5.11 number we set/offset*
11th byte is padding up to a 4-byte/32-bit multiple message length
12th byte is padding up to a 4-byte/32-bit multiple message length
So our message was 12 bytes/96 bits long and set the focus to a value.
*The 16 bit focus position data is encoded Least Significant BYTE first, so when we write the maximum 0x0800, we actually write 0x00 0x08, and when we write 0x0001, we actually write 0x01 0x00, this was pretty confusing initially.
Here, I'll set the focus to 0.9995, and demonstrate using hex and numbers


Hi, thanks so much for this- I'm a relative noob to this, but I am following along here pretty well and have it running and working on my Pi, but where exactly are you setting the focus to 0.9995? I'm assuming its the 9th and 10th byte, but not understanding how the numbers are equating to 0.9995? Or which of the two bytes need to be changed in order to change the focus distance. I was under the impression that the focus range for BM camera was 0-65535, but here its seems its from 0-1? Any help understanding this would be greatly appreciated.
Thanks, Brian

Return to Software Developers

Who is online

Users browsing this forum: No registered users and 6 guests