First I searched for information about Bluetooth in general, as I have never before used this protocol. And a Raspberry Pi was used for the first experiments.
The Raspberry Pi has the tool I needed already installed: bluetoothctl. This little program can scan, pair, bond and connect as well as send and receive gatt commands.
First I scanned for Bluetooth devices by turning on the scan function:
It discovered the Black Magic Pocket Cinema Camera right away and gave me its address. With this address I could try to pair up with it. But first I disabled the scan and set the newly found device as trusted:
On the camera screen a code appeared which I entered in bluetoothctl.
Now the Raspberry Pi and the camera are bonded, meaning I had to do this pairing only once. From now on, I simply can connect to the camera by:
If, for some reason, a connect fails, you can remove the device from the list by:
And pair up again. It is possible to see which devices are paired by entering:
This is al it took to control the camera. Which is the next bit: GATT or Generic Attribute Profile. This defines the way that two Bluetooth Low Energy devices transfer data back and forth. In bluetoothctl you can enter this mode by typing:
Listing all the attributes the device has:
There are two important UUIDs: the Outgoing Camera Control (UUID:5dd3465f-1aee-4299-8493-d2eca2f8e1bb) and the Incoming Camera Control (UUID:b864e140-76a0-416a-bf30-5876504537d9)
If we select the incoming camera control, we can read important status from the camera:
A bunch of data now scrolls over the screen. From this data we can distill information about the state of the camera.
If we select the outgoing camera control, we can write commands to the camera:
A big thanks to Sina Roughani (https://forum.blackmagicdesign.com/viewtopic.php?f=12&t=110565 and https://github.com/rgbbytes/blackmagic-bluetooth-control/) for sharing his knowledge on the Black Magic Pocket Cinema Camera Bluetooth LE implementation. Without his help, I still had a lot of frustrating hours of research ahead of me.
I took the liberty to copy a small, but very important, section from his post. It's about the order you have to send the byte to the camera:
The most critical part about this[the data send to the camera], 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
[bluetooth]#write "0x01 0x08 0x00 0x00 0x00 0x00 0x80 0x00 0xff 0x07 0x00 0x00"
[bluetooth]#write "1 8 0 0 0 0 128 0 255 7 0 0"
The most important function I want to control is the record button. When I sit in front of the camera, I want to be able to start and stop it remotely. Until now, I start the camera, sit down in front of it, plug in the lavalier mike and start reading from the teleprompter. But I do make a lot of mistakes (some call it 'making bloopers'). Than I have to restart the teleprompter and start all over again. All that time, the camera is spitting out gigabyte after gigabyte. And I end up with very large files I have to archive. If I can start and stop the camera remotely, I can trow away the files that are ruined because of my stupidity and I only have to archive the good takes. Saving tons of hard disk space.
So my first test scripts are for start recording and stop recording. Here they are:
$ cat ./bmpcc4k-start.sh
bluetoothctl << EOF
write "255 5 0 0 10 1 1 0 2 0 0 0"
$ cat ./bmpcc4k-stop.sh
bluetoothctl << EOF
write "255 5 0 0 10 1 1 0 0 0 0 0"
As you can see, I commented out the connect part. This is because you only have to connect once per session. And from the PinePhone you can connect by means of the Bluetooth icon in the tray. Yes, these scripts run on my PinePhone as well as a Raspberry Pi. For the PinePhone, I had to install bluetoothctl by hand and pair the camera to the phone. Pairing could not be done via the gui. But you can connect via the gui, which is nice.
Summary of the things I had to do on the PinePhone:
$ sudo pacman -S bluez-utils
Pairing with the camera:
Then you'll see the named devices available, pick your device ID, XX:XX:XX:XX:XX:XX
You will be prompted for the 6 digit passkey/PIN. Then you can connect and access the GATT data:
The last three commands are not necessary. I ran these commands to test if it was all working correctly. Which it did.
From now on, the PinePhone is bonded to the Black Magic Pocket Cinema 4K. You can connect to the camera by tapping the Bluetooth icon in the system tray and select connect. If you want, you can also connect via bluetoothctl. Both work equally well and can be used alongside each other.
After connecting to the camera, you can start and stop the camera by running the scripts from the command line. A gui would be nice...Next: V0.0.1