1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-08-25

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

micro:bitを磁気センサのペリフェラルに設定

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

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

m103.png

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

m104.png

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

m105.png

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

m106.png

 Bluetoothを選択します。

m107.png

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

スクリーンショット 2020-08-25 06.50.57.png

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

スクリーンショット 2020-08-25 06.51.29.png

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

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

スクリーンショット 2020-08-25 07.03.28.png

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

スクリーンショット 2020-08-25 07.05.10.png

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

スクリーンショット 2020-08-25 07.08.14.png

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

スクリーンショット 2020-08-25 07.10.04.png

IMG_4384.jpg

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

スクリーンショット 2020-08-25 07.12.13.png

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

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

公式の情報

 Bluetooth Magnetometer Serviceのページに、磁気センサのサービスUUID、三つのキャラUUIDが掲載されています。

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が利用できるようにした状態でプログラムを作ります。

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

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

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

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

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

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

data1 = read(c1)

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

    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単位の数値が得られます。

    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

 全体のソースです。

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を実行したらディスコネクトなので、× の表示に変わります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?