Corredor

ウェブ、プログラミングの勉強メモ。

Cordova アプリで Bluetooth 通信ができる cordova-plugin-bluetooth-serial を試した

iOS×BLE Core Bluetoothプログラミング

iOS×BLE Core Bluetoothプログラミング

Cordova アプリで Bluetooth 通信ができる cordova-plugin-bluetooth-serial を試してみた。

iOS 実機で試してみたかったが、思うようにいかず、Browser プラットフォームでのエミュレートによる動作検証のみ。

今回のソースは以下の CordovaExamples リポジトリの feat/bluetoothSerial ブランチに置いているので、コチラも参考にしてほしい。

iOS における Bluetooth 通信について

iPhone をはじめとする iOS デバイスは、Bluetooth Ver.4.0、通称「Bluetooth Low Energy (BLE)」という規格で通信するらしい。MacBook の Bluetooth などもコレに対応している。バージョン 4.0 ということで、古いバージョンの Bluetooth 規格だと対応していない、ということになる。

cordova-plugin-bluetooth-serial をインストールする

まずは Cordova プラグインをインストールする。Cordova は v7.0.1 で検証。

$ cordova plugin add cordova-plugin-bluetooth-serial

また、今回は Browser プラットフォーム向けに提供されているエミュレート関数を利用するので、Browser プラットフォームを準備していなければ導入する。

$ cordova platform add browser

実装の仕方

実装の仕方は以下の JavaScript コードを参照のこと。

Bluetooth エミュレートの用意

Bluetooth Serial プラグインは、Browser プラットフォーム向けにのみ、Bluetooth 機器のエミュレータを用意してくれている。以下の要領でエミュレータを準備できる。

window.bluetoothSerial.register(function(buf) {
  if(buf && buf.input) {
    buf.output = 'このような内容を受信しました : [ ' + buf.input + ' ]';
    buf.input = '';  // 受信データをクリアする
    return buf;
  }
});

bluetoothSerial.write() でエミュレータに向けてテキストデータを送信すると、buf.input がその内容を受信する。

逆に、このエミュレータからデータを受信したい場合は bluetoothSerial.read()bluetoothSerial.subscribe() を使うと、buf.output に指定されたテキストデータを受け取ることができる。

つまり上記のコードは、受信したデータ (buf.input) をほとんどそのまま送信 (buf.output) し返しているだけのエミュレータになる。

周辺デバイスの検索

周辺にある Bluetooth 機器を検索するには、bluetoothSerial.list() を使う。

window.bluetoothSerial.list(function(devices) {
  console.log('周辺の Bluetooth デバイスの件数 : ' + devices.length);
  devices.forEach(function(device) {
    console.log('デバイス名 : [' + device.name + '] ・ デバイス ID : [' + device.id + ']');
  });
}, function(error) {
  console.log('Bluetooth 通信エラー : ' + error);
});

ココで取得できる device.id が、このあと行うデバイス通信の際に通信先を特定するモノになる。

Bluetooth デバイスとの接続

通信したい相手、ココでは Bluetooth エミュレータとの通信を行えるよう、対象の Bluetooth デバイスに接続する。

var deviceId;  // 接続対象のデバイス ID

window.bluetoothSerial.connect(deviceId, function() {
  console.log('デバイス接続 成功');
  
  window.bluetoothSerial.subscribe('¥n', function(data) {
    console.log('デバイス接続 Subscribe 成功', data);
  }, function(subscribeError) {
    console.log('デバイス接続 Subscribe 失敗,' subscribeError);
  });
}, function(error) {
  console.log('デバイス接続 失敗', error);
});

ココで、Bluetooth 関連の用語を知っておくと理解が深まるので一部紹介。

  • ユーザが Bluetooth 接続を行うために操作する iPhone など、デバイスを発見しようとする側の機器のことを「セントラル」と呼ぶ。
  • 逆に、iPhone から発見されるような「見つけてくれ〜」と待ち構えている側の機器を「ペリフェラル」と呼ぶ。
  • ペリフェラルが発信する、自分を表すデータのことを「アドバタイズ」と呼ぶ。
  • サーバのデータを読み書きする単位を「キャラクタリスティクス」と呼ぶ。
  • ペリフェラル (通信先) のキャラクタリスティクスの変更 (≒サーバとの通信によって変わった発信内容) を、セントラル (iPhone 側) が受信できるようにすることを、「サブスクライブ」と呼ぶ。

…というわけで、bluetoothSerial.connect() で対象の機器との接続を確保し、bluetoothSerial.subscribe() で対象の機器から定期的にデータを受信できるようにする、ということみたい。Subscribe って「定期購読」の意味で訳されたりするから、そういうことなんだな。

デバイスとのデータの送受信

対象のデバイスとのサブスクライブができたら、bluetoothSerial.write()bluetoothSerial.read() でデータの送受信ができるようになる。基本的にテキストデータのみ扱える。

// データの送信
var textData = '送信したいテキストデータ'
window.bluetoothSerial.write(textData, function() {
  console.log('送信成功');
}, function(error) {
  console.log('送信失敗', error);
});

// データの受信
window.bluetoothSerial.read(function(data) {
  console.log('受信成功 … 受信データ : [' + data + ']');
}, function(error) {
  console.log('受信失敗', error);
});

接続の切断

接続中のデバイスとの通信を切断するには bluetoothSerial.disconnect() を使う。既に接続中なはずなので、デバイス ID の指定は不要。

window.bluetoothSerial.disconnect(function() {
  console.log('切断成功');
}, function(error) {
  console.log('切断失敗', error);
});

以上が基本的な API となる。

Cordova アプリで Bluetooth 通信を可能にする Cordova プラグインは他にもいくつかあるが、iOS の場合は BLE 通信であることは変わらず、用意されている API も大きくは変わらなかったりする。

その他のプラグインの例としては以下のとおり。

iOS シミュレータでは使えない

いずれのプラグインでも、iOS シミュレータの場合は Bluetooth 接続機能がシミュレータに実装されていないため、シミュレータでの動作確認はできない。必ず iOS 実機を使用することになる。

MacBook と iPhone 実機で通信できないか試したが…

開発を行っている MacBook をペリフェラル・デバイスとして、Cordova アプリをデプロイした iPhone から通信できないか、やり方を色々探ってみたが、思うようにいかず。やり方があれば教えてください。