matlabでBLEを使う⑤micro:bitのmagnetometer 

　英国ですべての中学生に配られたマイコン・ボードmicro:bitは、GUIのプログラミング・ツールが利用できます。いくつかのセンサ（加速度センサはMMA8653もしくはLSM303 ）が搭載されていて、センサから読み出した値をBLEで簡単に送ることができます。最初に、磁気センサ（磁力センサもしくはコンパス）を利用できるようにします。
###micro:bitを磁気センサのペリフェラルに設定

　BLEの用途に限らず、micro:bitのファームウェアは最新にしておきます。執筆時点では、Interface Version: 0254でした（DETAILS.TXT）。

　https://makecode.microbit.org/　
へ行き、ホームから新しいプロジェクトをクリックします。画面右上の歯車のアイコンをクリックします。

![m103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/2d061477-477b-c872-604a-274595dbc159.png)

　プロジェクトの設定を選びます。

![m104.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/24bfd4e2-7363-687a-6cb1-81c40ad88814.png)

　No Pairing Required:...を選び、保存します。

![m105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a9299fe2-2a2c-174c-acc5-b0ff9de4097b.png)

　同じく歯車のメニューから拡張機能を選びます。

![m106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/e9895f30-eed6-1913-c70b-f22fbc8c3838.png)

　Bluetoothを選択します。

![m107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/6986b475-4e43-6596-417c-2af9e2ade503.png)

　Bluetoothがメニューに追加されています。クリックして、その中から「磁力計サービス」を選択します。

![スクリーンショット 2020-08-25 06.50.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/976119dd-aae2-957d-2600-fc4df286ab0f.png)

　「最初だけ」の中に「磁力計サービス」をドロップします。「ずっと」は不要なので消します。

![スクリーンショット 2020-08-25 06.51.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/d856e262-42da-8317-2454-b28c642ec8df.png)

　接続されたとき、接続が切断されたときのLED表示を追加します。

　「基本」から「アイコンを表示」を選びます。

![スクリーンショット 2020-08-25 07.03.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a26bd2e1-4160-0f9e-096e-f236f3fbf8cb.png)

　「Bluetooth」から「Bluetooth接続されたとき」を選びます。

![スクリーンショット 2020-08-25 07.05.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f8559900-bbf0-8f35-2876-73fdc95db7a7.png)


　「Bluetooth接続されたとき」に「アイコンを表示」を入れます。

![スクリーンショット 2020-08-25 07.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c3a35e5f-7e50-57af-5614-cfe18435c27f.png)


　「アイコンを表示」の▼マークをクリックし、任意の表示を選びます。四角形を選びました。

![スクリーンショット 2020-08-25 07.10.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/7075682e-8c4b-2788-42ad-3909d544e329.png)

![IMG_4384.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c8145758-56af-e9a4-7c64-e26c166bd0b9.jpeg)

　同様に、「Bluetooth接続が切断されたとき」も作ります。バツを選びました。
　完成です。

![スクリーンショット 2020-08-25 07.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/7ee61c9c-dfdc-427c-cc13-56f902e446e8.png)

　温度計の事例は、こちら
　　https://www.denshi.club/cookbook/wireless/ble/microbitble.html
を参照してください。

　画面右下のダウンロードをクリックし、ダウンロードしたファイルをmicro:bitのフォルダにドラッグすると、プログラムがコピーされ、終了するとリセットがかかり、ペリフェラルとしてアドバタイジングを開始します。

###公式の情報
　[Bluetooth Magnetometer Service](https://lancaster-university.github.io/microbit-docs/ble/magnetometer-service/)のページに、磁気センサのサービスUUID、三つのキャラUUIDが掲載されています。

```java
public static String MAGNETOMETERSERVICE_SERVICE_UUID = "E95DF2D8251D470AA062FA1922DFA9A8";
public static String MAGNETOMETERDATA_CHARACTERISTIC_UUID = "E95DFB11251D470AA062FA1922DFA9A8";
public static String MAGNETOMETERPERIOD_CHARACTERISTIC_UUID = "E95D386C251D470AA062FA1922DFA9A8";
public static String MAGNETOMETERBEARING_CHARACTERISTIC_UUID = "E95D9715251D470AA062FA1922DFA9A8";
```

　このマイコン・ボードでは、NXPもしくはSTマイクロ（LSM303） のどちらかのデバイスが使われています。筆者のは表面の文字がMAGと読めたので、MAG3110と思われます。データシートを読むと、BEARINGは存在しないようです。
　実際、オン・セミコンダクターのBLEであるRSL10 Bluetooth Low Enaergy Exploerを使って情報を見ると、BEARING（E95D9715251D470AA062FA1922DFA9A8）データは送られてきません。PERIODは固定された値（100）で、使いません。
　したがって、DATAのnotifyを有効にすれば、どんどん磁気データを送ってくると推測できます。DATAの内容は、X、Y、Zの三つで、それぞれ16ビットです。上位バイト、下位バイトの構成で、2の補数形式であることが、データシートから読み取れます。ただし、ビッグ・エンディアンかリトル・エンディアンかどうかは、読んでみるまでわかりません。

###Matlabの設定
　 matlabを動かしているPCでBluetoothが利用できるようにした状態でプログラムを作ります。

```matlab
clear all
list = blelist("Timeout",10);
```

　探してきます。BBC micro:bit[xxx]というlocal nameを見つけてくると思います。

```matlab
b = ble("BBC micro:bit [gavag]");
```

　  bの内容を見ます。公式の情報のUUIDが見つかると思います。

```matlab
Magnetometer_Service_UUID = "E95DF2D8-251D-470A-A062-FA1922DFA9A8"; % 磁力計サービス
Magnetometer_Characteristic_Data_UUID = "E95DFB11-251D-470A-A062-FA1922DFA9A8"; % 磁力データ
Magnetometer_Characteristic_Period_UUID = "E95D386C-251D-470A-A062-FA1922DFA9A8"; % 取得間隔
Magnetometer_Characteristic_Bearing_UUID = "E95D9715-251D-470A-A062-FA1922DFA9A8"; % 方角データ
```

　利用するのは磁力データだけです。

```matlab
% 磁力データ
c1 = characteristic(b, Magnetometer_Service_UUID, Magnetometer_Characteristic_Data_UUID);
fprintf('start');
subscribe(c1);  % notify enable
```

　送られてくるデータを表示し、ボードを微妙に動かします。

```
data1 = read(c1)
```

　6桁のうち、1,3,5番目のデータが変化します。したがって、
　　x下位バイト、x上位バイト、y下位バイト、y上位バイト、z下位バイト、z上位バイト
の順番だと推測します。リトル・エンディアンでしたね。

```matlab
    x = double(bitor( bitshift(int16(data1(2)), 8) , (data1(1)) )) /1000;
    y = double(bitor( bitshift(int16(data1(4)), 8) , (data1(3)) )) /1000;
    z = double(bitor( bitshift(int16(data1(6)), 8) , (data1(5)) )) /1000;
```

　このデコードで、uT単位の数値が得られます。

```matlab
    x = (double(data1(2)*256) + double(data1(1)) ) / 1000;
    y = (double(data1(4)*256) + double(data1(3)) ) / 1000;
    z = (double(data1(6)*256) + double(data1(5)) ) / 1000;
```

　このデコードでもよいように思えますが、符号が消えてしまいました。シフトbitshiftを使ったほうは、最上位が'1'のとき、マイナスの数値になります。

　この後の処理がわかっていません。X,Yから方向を導くようなのですが、当然、経度の補正や、オフセットの修正が必要です。さらにz軸の補正も必要ですが、特にz軸の補正方法の資料が見つかりません。資料が見つかれば、matlabの行列処理機能ですぐに補正ができそうです。
　とりあえず、生データを使ってcompassグラフと、極座標へ変換した後のcompassグラフを描きました。

![スクリーンショット 2020-08-25 08.57.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/f92214a7-76f9-4595-cfa7-8140720945f4.png)

　全体のソースです。

```matlab
clear all
list = blelist("Timeout",20)
b = ble("BBC micro:bit [gavag]");
Magnetometer_Service_UUID = "E95DF2D8-251D-470A-A062-FA1922DFA9A8"; % 磁力計サービス
Magnetometer_Characteristic_Data_UUID    = "E95DFB11-251D-470A-A062-FA1922DFA9A8"; % 磁力データ
Magnetometer_Characteristic_Period_UUID  = "E95D386C-251D-470A-A062-FA1922DFA9A8"; % 取得間隔
Magnetometer_Characteristic_Bearing_UUID = "E95D9715-251D-470A-A062-FA1922DFA9A8"; % 方角データ

% 磁力データ
c1 = characteristic(b, Magnetometer_Service_UUID, Magnetometer_Characteristic_Data_UUID);
fprintf('start');
subscribe(c1);  % notify enable
X = [];
Y = [];
Z = [];
U = [];

for i = 1:20
    data1 = read(c1);
    x = double(bitor( bitshift(int16(data1(2)), 8) , (data1(1)) )) /1000;
    y = double(bitor( bitshift(int16(data1(4)), 8) , (data1(3)) )) /1000;
    z = double(bitor( bitshift(int16(data1(6)), 8) , (data1(5)) )) /1000;
    th = atan( y / x);
    azimuth = 90- th;
    %fprintf('%08s %08s %08s \n', dec2bin(x), dec2bin(y), dec2bin(z));
    %fprintf('read x,y,z %.3f %.3f %.3f \n', x, y, z);
    fprintf('read x,y,z %.3f %.3f %.3f ||  %.3f %.3f  \n', x, y, z, th, azimuth);
    pause(0.5);
    X(i) = x;
    Y(i) = y;
    Z(i) = z;
    U(i) = th;
    %compass(x,y)
end
fprintf('done');

figure
compass(X,Y)

[theta,rho] = cart2pol(X,Y);
polarplot(theta,rho,'o');
pax = gca;
angles = 0:45:360;
pax.ThetaTick = angles;
labels = {'東','NE','北','NW','西','SW','南','SE'};
pax.ThetaTickLabel = labels;

clear b
```

　通信を始めると、micro:bitのLEDは □ の表示になり、clear bを実行したらディスコネクトなので、× の表示に変わります。