matlabでBLEを使う①

　Matlabを使い始めて5日目。オーソドックスな書き方や変数の型がよくわかっていません。Instrument Control ToolboxにはBluetooth対応と書かれていますが、scanして見つかったのはiPad。Bluetooth4以前のSPP (Serial Port Profile)に対応しているようです。
　現在、4.x以降、BLEと呼ばれる新しいプロトコルが、センサ類の通信に使われています。ヘルプセンターで、[「Bluetooth Low Energy での通信」](https://jp.mathworks.com/help/matlab/bluetooth-low-energy-communication.html?searchHighlight=Bluetooth%20Low%20Energy%20%E3%81%A7%E3%81%AE%E9%80%9A%E4%BF%A1&s_tid=srchtitle)が見つかりました。ここが解説の入り口のようです。
# ペリフェラルはCC2650 SensorTag
　古いのですが、温度や照明センサの入ったテキサスインスツルメンツの製品です。この後にLPSTK-CC1352Rというマルチセンサが販売されていますが、技適は取れていないようです。サービスやキャラクトリスティックには、一部同じUUIDが使われていますが、内容は微妙に異なります。問題は、UUIDの解説とデータのフォーマットの資料が見つからないことです。つまり、使えません。
　CC2650 SensorTagは、資料；[CC2650 SensorTag User's Guide](https://processors.wiki.ti.com/index.php/CC2650_SensorTag_User's_Guide)が残っているので、データの読み出し方法や、換算式がわかります。


# セントラルはWindows10 PC
　***ペリフェラル***は、サーバです。***セントラル***はクライアントだと考えると、わかりやすいです。ペリフェラルは、電源が入ると、一定時間アドバタイジングをします。具体的には、誰かつなぎに来るのを待つように電波を出します。セントラルであるPCは、scanをします。誰かアドバタイジングしていないかを見つける動作です。
`list = blelist("Timeout",10);`　scanです。タイムアウトしたのちlistの中をのぞくと、見つかったペリフェラルが列挙されています。
![スクリーンショット 2020-06-22 08.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a94dc2f5-8339-f9fd-82a5-e937946005fe.png)

`b = ble("CC2650 SensorTag");`見つかったペリフェラルの中のname（local name）は"CC2650 SensorTag"なので、bというインスタンスを作ります。これを実行すると、bの中に、サービスUUIDとサービス名、キャラクトリスティックUUIDとキャラクトリスティック名などが表示できます。
![スクリーンショット 2020-06-22 08.06.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a38460ad-cddb-fdff-bbee-1f332aacb291.png)

　Servicesの値をクリックします。
![スクリーンショット 2020-06-22 08.08.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/af7c04e1-3b21-3149-0143-4f1ab930cf67.png)
　Characteristicsの値をクリックします。
![スクリーンショット 2020-06-22 08.09.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/feebcca9-e5e1-989d-a93c-44693b561cb6.png)

　資料から、AA20がHumidity Sensorのサービスで、AA21が温度と湿度が入って4バイトのデータ（Temp[0:7], Temp[8:15], Hum[0:7], Hum[8:15]）がreadでき、AA22はデフォルトが0で、0x01を書き込むと変換を開始することがわかります。
　バッテリの残量を示すサービスBattery ServiceのキャラクトリスティックBattery levelの関係は、次の図のようになります。
![GATT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c4044b4a-8e9c-eb4a-090e-d06cc49990d2.png)
　つまり、BLEは複数のサービスが同居していて、サービスの中にキャラクトリスティックがあり、Valueを読むと、残量がわかるという構成です。
　今回のマルチセンサも同じで、複数のセンサがひとつずつサービスUUIDが割り当てられていて、センサは複数の計測値をもつので、それらがキャラクトリスティックUUIDに割り当てられ、それぞれ適したフォーマットでValueが存在します。
　登録されているUUIDは短いUUIDが、そうでないカスタムはフルの長さのUUIDが使われます。

# 温湿度を読み出すプログラム
　サービスUUIDとキャラクトリスティックUUIDを指定して、インスタンスc1を作ります。AA22は変換開始のための読み書きができます。0x01を書き込みます。

```matlab
　c1 = characteristic(b, "F000AA20-0451-4000-B000-000000000000", "F000AA22-0451-4000-B000-000000000000");
  write(c1,0x01)
```

 　AA21にはデータが入っています。data1には4バイトの数値データが1次元配列で収納されています。最初に読んだときに全部0のことがときどきありました。
![スクリーンショット 2020-06-22 08.39.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/95758b4d-8f8d-a633-9c4b-77c739c9d6a2.png)


```matlab
c10 = characteristic(b, "F000AA20-0451-4000-B000-000000000000", "F000AA21-0451-4000-B000-000000000000");
data1 = read(c10);
```

　読み出します。資料に書かれているようにHDC1000（すでに古く、世代はHDC20xxとかに代わっている）の換算式から温度と湿度を求めます。それぞれのデータは16ビットで、下位1バイト、上位1バイトの順で入っています。上位1バイトを8ビット・シフトして下位1バイトと加算して16ビット・データにしています。

```matlab
Temp = ((data1(2) * 256 + data1(1)) / 65536) * 165 - 40
Humi = ((data1(4) * 256 + data1(3)) / 65536) * 100
```

　全体です。最初のclearは、ワークスペースの値を初期化します。1秒ごとに10回読んできます。

```matlab
clear
list = blelist("Timeout",10);
b = ble("CC2650 SensorTag");
bb = b.Characteristics;

for i=1:10
    c1 = characteristic(b, "F000AA20-0451-4000-B000-000000000000", "F000AA22-0451-4000-B000-000000000000");
    write(c1,0x01)
    % data00 = read(c1);
    c10 = characteristic(b, "F000AA20-0451-4000-B000-000000000000", "F000AA21-0451-4000-B000-000000000000");
    data1 = read(c10);
    % data1(1),data1(2),data1(3),data1(4)
    Temp = ((data1(2) * 256 + data1(1)) / 65536) * 165 - 40
    Humi = ((data1(4) * 256 + data1(3)) / 65536) * 100
    pause(1);
end
```

　~~disconnectの方法がわかっていません。~~
　(2020/06/22)  最後に、clear b　でdisconnectするようです。