前回、micro:bitに搭載されている磁気センサのデータをBLE経由でPCから読みました。ここでは、もうひとつの加速度センサのデータを読み込みます。
micro:bit側の設定
磁気センサとまったく同じ手順で、「加速度計サービス」を用意し、ダウンロードします。
matlabの設定
前回とほとんど同じです。加速度センサのサービスとキャラは次のとおりです。
Accelerometer_Service_UUID = "E95D0753-251D-470A-A062-FA1922DFA9A8"; % 加速度計サービス
Accelerometer_Characteristic_Data_UUID = "E95DCA4B-251D-470A-A062-FA1922DFA9A8"; % 加速度データ
Accelerometer_Characteristic_Period_UUID = "E95DFB24-251D-470A-A062-FA1922DFA9A8"; % 取得間隔
読み取れるのは、x、y、zのデータです。センサは MMA8653のようです。データシートのよれば、単位はgで、10ビットのデータです。三つのレンジがあり、±2g、±4g、±8gのどのレンジでデータが送られてくるのかは不明です。データのフォーマットは、上位8ビット+下位2ビットの形式ですが、実際BLEで送られてくるのが磁気センサと同じリトル・エンディアンであれば、下位2ビット+上位8ビットと推測できます。
下位ビットは8ビットと7ビット目にデータが入り、残りの6ビットは不明です。したがって、10ビットを読んで、右に6シフトすれば、正しい10ビットのデータになります。BLEではそのデータを2バイトに分けて送ってくるとしたら、たんに8ビット+8ビットのデータを読み取ればよいと思います。
公式ページ
https://lancaster-university.github.io/microbit-docs/ble/accelerometer-service/
では、リトル・エンディアンでデータを読み、1000で割った値をなにもスケーリングしていません。
同じように処理しました。
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;
このあとpitchとroolを計算します。
pitch = atan( 1 * x / sqrt(y.^2 + z.^2));
roll = atan(y / z);
rollの計算は、検索していろいろなところに書かれた計算式です。公式ページはそうなっていません。pitchの計算式は、arctanの中の符号が+ですが、検索した解説ページではーになっています。この符号は、外に出しても同じ結果になります。
全体のソースです。
clear
list = blelist("Timeout",20)
b = ble("BBC micro:bit [gavag]");
Accelerometer_Service_UUID = "E95D0753-251D-470A-A062-FA1922DFA9A8"; % 加速度計サービス
Accelerometer_Characteristic_Data_UUID = "E95DCA4B-251D-470A-A062-FA1922DFA9A8"; % 加速度データ
Accelerometer_Characteristic_Period_UUID = "E95DFB24-251D-470A-A062-FA1922DFA9A8"; % 取得間隔
% 加速度データ
k1 = characteristic(b, Accelerometer_Service_UUID, Accelerometer_Characteristic_Data_UUID);
fprintf('start');
subscribe(k1); % notify enable
count = 20;
X = (count);
Y = (count);
Z = (count);
P = (count);
R = (count);
for i = 1:count
data1 = read(k1);
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;
pitch = (180 / pi) * atan( x / sqrt(y.^2 + z.^2));
roll = (180 / pi) * atan(y / z);
fprintf('read x,y,z %.3f %.3f %.3f || %.3f %.3f \n', x, y, z, pitch, roll);
pause(0.5);
X(i) = x;
Y(i) = y;
Z(i) = z;
P(i) = pitch;
R(i) = roll;
end
fprintf('done');
figure
feather(P,R)
clear b
グラフはfeatherというのを選びました。このグラフを選んだのは、ピッチとロールの変化がわかりやすいからです。
ピッチとは、X方向(ICの1ピンがX方向)に対して前後の揺れぐあい、ロールは左右の揺れぐあいを表します。もう一つの回転を表すヨーは加速度センサでは取得できないようです。
グラフの例です。マイコン・ボードをぐるーとまわしています。