2021年07月29日 更新

開発視点の超簡単BLE入門

どうも、クラゲです。
今回はBLEそのものについて超簡単に説明します。
BlueJellyに限らず、全てのBLEに共通した内容です。BLE雑学ではなく、開発視点での最低限必要な情報だけを説明します!

【 概要 】

[TOC]

はじめに

初めに、BLEと普通のBluetooth(以下BTと略します)の違いについて説明します。ポイントは3つです。

普通のBTはクラシックBT

普通のBTはクラシックBTと呼ばれています。データのやりとりは主にSPP(Serial Port Protocol)が使われていました。

低消費電力になっただけじゃない

ファームウェアやアプリ開発視点ではクラシックBTのSPPや一般的なシリアル通信(UART、I2C、SPI、RS232Cなど)と結構違います。

イメージ的にオブジェクト指向

注) 技術的にオブジェクト指向という意味ではないです。
例えば、趣味でちょっとしたサービスを1つだけ作るにはクラシックBTはお手軽に使えますが、業務で多くの大規模サービスを作る場合は効率が悪いです。
逆にBLEは、業務で多数のサービスを作る場合は使い回しやすいので非常に効率的ですが、趣味でちょっとしたサービスを1つだけ作りたい場合には効率が悪いのが現状です。

プログラミングのオブジェクト指向は、良く分からんヨコモジがたくさん出てきて混乱することがあると思います。
BLEもセントラルやらキャラクタリスティックやらUUIDやら聞き慣れない単語が出現しますが、クラゲが超簡単に噛み砕いて説明し、余計なうんちくはバッサリ切り落としますので混乱せず読み進めることが出来ます!

シリアル通信との違い

電子工作をやっている人はシリアル通信が分かりやすいと思いますので、それとの比較で書きます。シリアル通信が分からない方も雰囲気は伝わるかと思います。

クラシックBTはデバイス毎に別仕様

シリアル通信は、それぞれの通信シーケンスに従いコマンドを使ってデータのやり取りを行います。コマンドやシーケンスは通信するデバイスやICが異なれば、全く別モノで、通信仕様書をしっかり読みこなす必要があります。

BLEは全デバイスで共通仕様

一方のBLEもコマンドやシーケンスを使いデータのやり取りを行いますが、コマンドやシーケンスそのものについては全てのデバイスやICで共通です。
例えばコマンドで主に使うのは以下の3つだけです。コマンドの詳細は後ほど説明します。
READ, WRITE, NOTIFY

コマンドのイメージです。ちなみにBLEで "コマンド" や "番地" という表現はしません。イメージしやすいようにクラゲが勝手に使っているだけです

READの例 : a = read(3番地)
3番地のデータ値を読み込んで変数a に入れる

WRITEの例 : write(4番地, 100)
4番地にデータ値100 を書き込む

このようにコマンドを使って、引数にはデータ番地とデータ値のみを指定さえすれば、通信できます。
つまり、クラシックBTのSPP通信のように、どんなシーケンスでどんなコマンドがあるのか、毎回通信仕様書とにらめっこする必要がないのです。ただし、もちろん、どの番地に何のデータが入っているかは仕様書を見る必要があります

BLEの登場人物

では早速、BLE特有のヨコモジに慣れましょう。

GAP と GATT

たくさんあるBT通信ルールの中の2つです。カッコ良く言うと"プロファイル"です。
GAPは、通信役割や接続手順に関するルールです。
GATTは、データ構造やデータへのアクセス手法に関するルールです。

Central と Peripheral

BT通信においてどのように立ち振る舞うかの役割名称です。
セントラルは、端的に言って、スマホやタブレット、PC側 のことです。シリアル通信でいう "マスター" に相当します。
ペリフェラルは、端的に言って、センサーデバイス側のことです。シリアル通信でいう "スレーブ" に相当します。

Advertise, Scan, Connect, Disconnect

Bluetooth接続に関する手順です。後で詳細を書きます

Service, Characteristic

データを格納している場所です。このデータ構造について後で詳細を書きます。

UUID

ServiceやCharacteristicはUUIDというIDで表現します。後で詳細を書きます。

Read, Write, Notify

データにアクセスする方法です。後で詳細を書きます。

BLE開発で知ってれば良いヨコモジはこれだけです。
これだけ知っていれば、BLE開発できちゃいます!

BLEの接続手順

接続手順は4つだけ!

Advertise

ペリフェラルが「私を見つけて!」と電波を発する行為

Scan

セントラルが「周りにどれだけペリフェラル居るかな?」と周辺のペリフェラルを探す行為

Connect

セントラルが「こいつに決めた!」と特定のペリフェラルと接続する処理。ユーザーに選択させます。

DiSconnect

接続解除。セントラルがアプリを終了する前などに実行します。

この順番で接続〜解除するだけです。
DisconnectせずにScanすると見つからない場合があるので気をつけましょう。

BLEのデータ構造

パソコンのフォルダとファイルの関係と同じです。

Service

フォルダのようなもの。
ペリフェラルの中に1つ以上のServiceがあります。

Characteristic

ファイルのようなもの。
各Serviceの中に1つ以上のCharacteristicがあります。
ファイルの中身には下記のValue, Property, Descriptorの3つが入っています。

Value

データそのものです。まさにこのデータをBLEでやりとりします。

Property

read, write, notify のどれに対応していのかを示す属性です。例えばwrite属性がないのに書き込もうとするとエラーになります。

Descriptor

追加情報のことですが、特に使わなくてもやっていけるので、忘れてしまいましょう。

BLEのデータ名

データ構造は、ServiceやCharacteristicで出来ているということは分かりましたが、パソコンと同じように具体的なフォルダ名とファイル名が分からないとデータにアクセスできません。
BLEではService名やCharacteristic名に自由に名前をつけてアクセスするのではなく、サイズとフォーマットが明確に決まっている UUID というIDを使って表現します。
UUIDとは、重複する事のないIDで、128bitの数値です。Byteで表すと16Byte、文字数でいうとハイフンを除いて32文字です。

例:00002a19-0000-1000-8000-00805f9b34fb

ServiceのUUID と CharacteristicsのUUID の2つさえ分かればデータにアクセス可能です。
このUUIDは一意的、つまりこの世に1つしかない値です。
この程度のことさえ知っておけば、とりあえず開発着手できます。
UUIDについてもっと知りたい方は こちら を参照してください。

BLEのデータへのアクセス手法

Read

Readはセントラルがペリフェラルからデータを読むコマンド

Write

Writeはセントルがペリフェラルに対してデータを書き込むコマンド

Notify

ペリフェラル側のタイミングで継続的にセントラルへデータ送信させるコマンド

NotifyはBLE特有なコマンドです。
例えば温度センサーの取得であれば、セントラルが10秒毎にペリフェラルからREADすることも可能ですが、Notifyを使えば、ペリフェラル側から温度変化があったときだけ教えてくれるということが出来ます。

RSSI(電波強度)

BT通信では、ペリフェラルの電波強度(RSSI)を知ることが出来ます。
ペリフェラルとセントラルの距離が近ければRSSIは高い値となり、遠ければ低い値となります。
BLEにおいては基本Advertise中に取得しますが、最近はAndroidもiOSもADVERTISE以外でも取得できるようです。
ちなみに2017年8月現在において、WebBluetoothAPIではRSSIの取得が未対応のようです。

ビーコン(BLEの特殊な使い方)

BLEにおけるビーコンとは、セントラルがペリフェラルにConnectせずにペリフェラルの情報を得る裏技です。
実は、ペリフェラル側はAdvertise時に少しの情報をある程度載せる事ができます。
それをセントラル側がScan時にチラ見するという具合です。

メリットとしては、ペリフェラル側は非常に低消費電力で動作させることができることです。(コイン電池で数年レベル)
一方デメリットとして、Characteristicsの中身のデータにはアクセスできないことと、ディレイ(遅延)が結構あります。

BLEビーコンはAppleのiBeaconやGoogleのEddystoneなどが有名なので、興味のある人は調べてみると良いと思います。
ちなみに2017年8月現在では、WebBluetoothAPIではiBeaconは取得できなさそうです。

さあ、ここまで読めば、あなたもBLEアプリ開発できます。BlueJellyを使ってWEBでお気軽に開発してみましょう!
以上、開発視点の超簡単BLE入門でした。