2022.10.30 2021.10.29 Coskx Lab
micro:bit MakeCodeには「方角(°)」というブロックがあります。
このブロックを使うと水平におかれたmicro:bitの「y軸+」の方角が得られます。
この測定にはmicro:bitに搭載されている「3軸磁気センサ」が使用されています。
方角は,磁北を0度とし,時計回りに0度から359度までの値が得られます。(方位磁石の真東が90度)
「方角(°)」ブロックを使用して,図ようにmicro:bitのy軸の方角を測定します。
水平置きされたmicro:bitを上から見たところ |
342
339
342
339
340
342
340
339
341
339
micro:bitを動かさないようにして方角データを取得してるのに方角データは揺れています。
方角データとしては平均化して使う方が良い場合があります。
次のプログラムでは,10回平均した方角を取得する関数を使うようになっています。
関数azimuth10は,10回平均の方角値を返す関数なので,「ずっと」ブロック中の「シリアル通信 1行に書き出す」で使えます。
方角の連続取得の場合には,このプログラムにあるように20msecの間隔が必要です。(補足2 短インターバル繰り返し測定)
また,この値を所望の変数に代入することもできます。
平均化したときの様子は次のようになりました。まだ少し揺れがありますが,1度以下の揺れになりました。
ただし,10回の平均値を求めるのに,200ms=0.2secかかることになります。
用途によって平均化回数を考える必要があります。
311
310
310
311
310
310
310
310
310
310
309
311
310
310
しかし,方角の平均値を求めるときは,0と359の間に不連続なところがあるので,計算にはもう一工夫必要です。
例えば,359,1,359,1,0の平均値は0になるはずですね。
スマートフォンやiPhoneなど方位測定アプリでは,様々な工夫がされていて,安定して方位測定出来るようになっています。
micro:bitでの方位測定では磁気センサから直接測定値を取り出しているため,方位角では10度程度の誤差を含みます。
また,近くに磁石がある場合や,鉄製の器具がある場合,建物に鉄製の構造材が使われている場合,地磁気が乱れていて,正しい方位を求められないことがあります。
地磁気の乱れがある場合は,スマートフォンやiPhoneなど方位測定アプリでも同様なことが起こります。
地磁気の乱れがあっても,周辺の鉄製の器具などが動かないならば,同じ位置で方位測定を複数回行なってみると,正しい方位とは限りませんが,測定値はほとんど変わりません。(時不変の性質,再現性があります。)
micro:bit MakeCodeの「方角(°)」ブロックを使用してmicro:bitの方角(磁北とy軸+のなす角)を求めました。
注意 「方角(°)」ブロックを連続使用するときは,最低でも20msは間隔をとる必要があります。
micro:bit側の測定値更新が20msほどかかるので,それ以下の間隔での測定値取得では,同じ値を取り込んでしまうことになります。
特に測定値の平均化のときは,平均化が無意味になってしまうので注意が必要です。
「ずっと」ブロックを使って毎回測定する場合は,「ずっと」ブロックの舞台裏で20msの一時停止(pause)が行われるため問題ありません。
(「補足2 短インターバル繰り返し測定」参照)
micro:bitでの方角の検出における誤差は次のような原因があります。
A micro:bit自身に起因する誤差
B 環境に起因する誤差
上記のような影響があるため,次のようなことが起こります。誤差が生ずることを念頭に,実際に方角測定を行って,評価してから使う必要があります
「方角(°)」ブロックは磁気センサを利用しています。磁気センサは,内部でAD変換・I2C通信しており,その結果をプログラムで磁気センサ値さらに方角として受け取っています。
AD変換・I2C通信は一定の時間を必要とするため,短インターバル繰り返しで磁気センサ値を受け取ろうとすると,思い通りの測定値が得られないことがあります。(実は舞台裏でセンサ値の更新周期が設定されています。)
micro;bitを絶えず動かしながら(取得されるべきセンサ値は不規則に変化するはず),
(1)インターバル無し
(2)インターバル10ms
(3)インターバル20ms
で16回連続測定し,得られた方角を観察してみました。
(1)インターバル無し(測定間隔ほぼ0)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,最速で測定します。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。(改行を削除して,1行で表示しています)
16回の取得データはすべて同じ値でした。
AD変換・I2C通信によるデータの更新が間に合わず,同じデータを受け取り続けていたと考えられます。
これでは使えません。
started
32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
(2)インターバル10ms(測定間隔10ms)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,10msのpause(一時停止)を行っています。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。(改行を削除して,1行で表示しています)
ところどころで,同じデータが2回続けて得られています。
AD変換・I2C通信によるデータの更新が完全には間に合わず,同じデータを受け取ってしまうことがあると考えられます。
これでは使えません。
started
64 66 63 63 58 58 56 59 58 57 57 61 60 59 58 58
(3)インターバル20ms(測定間隔20ms)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,20msのpause(一時停止)を行っています。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。(改行を削除して,1行で表示しています)
同じデータが繰り返し取得されることなく,測定できています。
started
67 64 47 57 68 62 65 76 74 77 93 84 95 92 88 98
このテストから,方角の測定には,20msほどのインターバルが必要なことがわかりました。
なお,「ずっと」ブロックでは舞台裏において20msのpause(一時停止)が行われているため,「ずっと」ブロック中ではプログラム中にpause(一時停止)を書かなくても最新の測定値を得ることができます。
参考 「ずっと」ブロックの動作
≫