nRF51でBLE MIDIをアドバタイズする

wdmi01

BLE MIDI ってのは、Bluetooth SIG で決まってるわけじゃないのでいくつか仕様があるのですが、
今回は iOS の GarageBand と繋げたいので、Apple の BLE MIDI を使います。

仕様はこちら、
Apple Bluetooth Low Energy MIDI Specification

その仕様によると BLE MIDI の UUID は、

Name UUID
Service 03B80E5A-EDE8-4B33-A751-6CE34EC4C700
I/O Characteristic 7772E5DB-3868-4112-A1A9-F2669D106BF3

ここまでわかれば、SDK にサンプルとして入ってる ble_nus ( Nordic UART Service ) を、
ちょちょっといじればアドバタイズまではできるはずです。

そして ble_nus の UUID はこちら。

Name UUID
Service 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
TX Characteristic 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
RX Characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E

ble_nus.c によると、Service 追加の方法は、

uint8_t         uuid_type;
ble_uuid128_t   nus_base_uuid = {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0,
                                  0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}};
ble_uuid_t      ble_uuid;
uint16_t        service_handle;

// Add custom base UUID.
sd_ble_uuid_vs_add(&nus_base_uuid, &uuid_type);

ble_uuid.type = uuid_type;
ble_uuid.uuid = BLE_UUID_NUS_SERVICE; // 0x0001

// Add service.
sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                         &ble_uuid,
                         &service_handle);

Characteristic は、

ble_gatts_char_md_t      char_md;
ble_gatts_attr_t         attr_char_value;
ble_uuid_t               char_uuid;
ble_gatts_attr_md_t      attr_md;
ble_gatts_char_handles_t rx_handles;

// 省略するけど char_md と attr_char_value をいろいろ設定

char_uuid.type = uuid_type;
char_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC; // 0x0002;

// Add RX Characteristic.
sd_ble_gatts_characteristic_add(service_handle,
                                &char_md,
                                &attr_char_value,
                                &rx_handles);

やり方がわかったので、
これを BLE MIDI に置き換えてみます。

まず、Base UUID から
Service UUID の一部を 0 変えたら、
03B80000-EDE8-4B33-A751-6CE34EC4C700 になるので、前後ひっくり返して…

ble_uuid128_t   midi_base_uuid = {{0x00, 0xC7, 0xC4, 0x4E, 0xE3, 0x6C, 0x51, 0xA7,
                                   0x33, 0x4B, 0xE8, 0xED, 0x00, 0x00, 0xB8, 0x03}};

次に、Service
さっき 0 に変えたところを uuid として指定します。

ble_uuid.type = uuid_type;
ble_uuid.uuid = 0x0E58;

// Add service.
sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                         &ble_uuid,
                         &service_handle);

あとは、Characteristic なんだけど、
Service と Base UUID が違う。

ここで、かなりはまったんだけど。
結局、Base UUID をもう一個作ったらうまくいきました。

uint8_t         char_uuid_type;
ble_uuid128_t   midi_char_uuid = {{0xF3, 0x6B, 0x10, 0x9D, 0x66, 0xF2, 0xA9, 0xA1,
                                   0x12, 0x41, 0x68, 0x38, 0x00, 0x00, 0x72, 0x77}};
ble_uuid_t      char_uuid;

// Add custom base UUID.
sd_ble_uuid_vs_add(&midi_char_uuid, &char_uuid_type);

char_uuid.type = char_uuid_type;
char_uuid.uuid = 0xE5DB;

よかった。
ここまでできたら GarageBand と接続できます。
あとは、Appleの仕様とMIDIの仕様のとおりにノート送ったりするだけなので簡単です。

なんか作ったよ

BLE MIDI を使って、野菜を楽器にして遊ぶデバイスを作ってみました。
Maker Faire に出したら、ちびっこたちに大人気。
せっかくの無線なのにケーブルいっぱいですみません。

wdmi01.jpg