Update 10 June 2016
Background:
Early in 2016 Yamaha released a couple of Bluetooth Low Energy MIDI adapters. The one that interested me was the USB model (UD-BT01) – I hoped it could be used with my USB-connected Akai EWI-USB wind controller. The EWI has a cable that powers it from a USB port and carries the MIDI messages to and from the synthesiser. The UD-BT01 is advertised as being only compatible with Apple MIDI products, but the attraction of being able to cut the cord to the synth was too strong – I bought one.
Problems:
- Bluetooth peripherals are coded to tell the computer they connect to what type of device they are (e.g. mouse, keyboard, heart monitor). To date, only Apple has published a standard for sending MIDI over Bluetooth, and it applies to only Apple products, which means that MIDI Bluetooth peripherals will not be recognised by non-Apple equipment. This is because the TYPE of device (MIDI) is not recognised in the general Bluetooth standard (as opposed to the Apple spec). The UD-BT01 can be SEEN by other systems (Windows, Linux), but it won’t connect automatically. A custom program to connect is required.
- Bluetooth LE is still fairly young, and, while programming languages exist to handle the connections, the documentation is thin, and there aren’t many examples available to use as models.
- The details of how to connect to and get data from a “Designed-For-Apple” peripheral are not readily available, so there’s a lot of trial-and-error involved if you don’t have the information on this page.
Solutions:
I have worked out a way of connecting the Yamaha UD-BT01 to a Raspberry-Pi. It works pretty well. My EWI-PI project has all the programs, but here I want to just give the key ideas for others attempting to do the same.
You need to refer to:
- The Apple Bluetooth Low Energy MIDI Specification. This gives the details of how the MIDI messages, including Sysex messages, are packaged.
- Ian Harvey’s BluePy. This is the python interface for Bluetooth LE on Linux.
To connect to the UD-BT01 you will need the Bluetooth address for your unit. They are all different. You can find out what the address is by using a computer or phone to do a LE scan when the adapter is powered up. When you have discovered the address you can then connect using BluePy. You need to connect in “random” mode. There are examples of how to connect in the BluePy on-line docs.
To send to and receive data from the UD-BT01, you need information about the Bluetooth “handles”. A GATT scan will show that the handle for the MIDI data is decimal 26. What it won’t show you is that data needs to be sent to handle 27, and the handle for enabling notifications is 28. I don’t know if these are “standards” for BLE (sending is at data+1 and notifications is at data+2), but that’s what I found. To enable notifications, after connecting you need to send 0x01 0x00 to handle 27. When that is done the peripheral (server) will send a notification to the computer (client) each time new data arrives, and the computer then asks the peripheral for the data. BluePy/Bluez does this automatically for you.
During the connection negotiation process, the peripheral sends the computer “Peripheral Preferred Connection Parameters”. These are suggestions, and the computer can ignore them. In practice I discovered that the RPi produced high latency with the default set of parameters. I was unable to discover what those parameters were, but when I re-configured the connection using the Linux hcitool I got a good result. The command I used was:
sudo hcitool lecup – -handle $HANDLE – -min 6 – -max 6 – -latency 0 – -timeout 500
Where $HANDLE is the number of the computer’s connection handle (NOT the UD-BT01’s connection handle – they are different), – -min is the minimum connection interval (6 x 1.25msec = 7.5msec, the minimum for BLE), – -max is the maximum connection interval, – -latency is the number of intervals the peripheral can delay replying to the computer’s message, and – -timeout is the time that must elapse before a dead connection is re-established by the computer (500 x 10msec = 5sec). The min/max/latency settings I have used here give the minimum latency.
To get the computer’s handle number, use:
sudo hcitool con
The UD-BT01 appears to have a 20-byte maximum message length. I don’t know if this is configurable during the “negotiation” process, but that’s what mine defaulted to. The Apple spec implies it can be changed. MIDI commands are 3 bytes long, and with the additional header and timestamp bytes (see the Apple spec), it means that a maximum of 4 MIDI commands can be sent per message. Your program will have to determine how many commands are contained in each message (it varies). In addition, Sysex commands can be sent. These can be long, and may be broken up into multiple messages, so as not to exceed the 20-char limit. See the Apple spec for details. Your program will have to determine if each message is a Sysex (third character is 0xF0).
Header and timestamp bytes are added to the messages. For my particular application (live performance) they are not important, however, when sending header and timing bytes TO the UD-BT01, they need to meet the specification. The header byte actually contains part of the timing information (see the Apple spec), but has a minimum value of 0x80 (with a timestamp of zero), likewise the timing byte has a minimum value of 0x80. Successive timing bytes need to be increasing, so for the Sysex commands I have used the following sequence: 0x80 0x81 0x82 0x83 … This series need to be consistent only within each “batch” of Sysex commands. You can start from 0x080 again for the next “batch”.
Interesting Stuff:
The Bluetooth connection to the computer is completely independent from the USB connection between the adapter and the instrument (EWI-USB in my case). You can unplug the instrument from the adapter, while keeping the adapter powered up, and then re-connect the instrument. It won’t affect the Bluetooth connection.
The power required to run the adapter and my EWI-USB is really small. I have left the instrument powered up for a 24-hour period and used only 1/4 of a 8000mAh battery pack
The Bluetooth connection needs to be re-configured each time it starts. So, if the connection is lost for some reason, and then re-made, you will have to run the hcitool command (above) again. I have put this command in a batch file which checks the handle number to see if it has changed, and if it has (the connection has been re-made) it runs the command again.