micro:bit Makecodeで超音波距離センサ(Grove Ultrasonic Ranger)の動作テスト

2021.7.25 Coskx Lab  

1 はじめに

micro:bitに超音波距離センサ(Grove Ultrasonic Ranger)を接続して周囲の対象物までの距離を測定します。



超音波距離センサ(Grove Ultrasonic Ranger)を使うと,超音波パルスの往復時間を測定し,4m程度までの距離を測定することができます。
超音波距離センサを基板上に取り付けた製品はHC-SR04もありますが,動作電圧5V仕様なので,micro:bit3.3Vとは相性が悪いのでここでは扱いません。


2 使用環境

3 端子の割り付け

Grove Ultrasonic Rangerに測距指示を与えたり,超音波反射往復時間のパルスを測定するために,micro:bit 端子P1を使うことに決めます。P1以外でも使用されていない端子であればどこでもよい(例えばP2など)です。この段階でどの端子を使うか決めておき,接続においても,プログラムにおいてもP1を使うことで一貫する必要があります。

参考 micro:bit端子一覧

4 接続

センサのソケット部に書いてある,GND,VCC,NC,SIGはそれぞれグランド(0V),3.3V,何もつながない(Non Connection),信号線(Signal line)です。
電源3.3V,GND,入出力兼用信号ラインをつなげます。
入出力兼用信号ラインはP1とつなぎます。
micro:bitの3VのところはUSB電源供給時に3.25V供給されていました。電源3.3Vにはこれを使います。
すなわち,次のようにつなげることを目指せばよいことになります。micro:bit端子一覧

ケーブルの白い線(NC)は使いません。


端子に直接はんだ付けしてしまってもよいのですが,そのようなことはしたくないため,micro:bitの端子を引き出して扱いやすくなっているブレイクアウトボードなどを使います。細工が必要な場合もあります。
接続端子変更例1
接続端子変更例2

(1) ブレイクアウトボード KITRONIK-5601Bの場合
3V,0V,P1の端子が見えているのでそのままつなぎます。3VとGNDは他の場所にも引き出されているので,そちらを使用することもできます。
センサの信号ケーブルの先端はGROVEコネクタがついているので,これを取り外して,メスコネクタを付ける必要があります。自分でメスコネクタをかしめ取り付けしても,メスコネクタ付きのジャンプワイヤを切ってはんだ付けでつないでもOKです。


(2) モータドライバボード KITRONIK-5698の場合
3V,0V,P1の端子が見えているのでそのままつなぎます。3VとGNDは他の場所にも引き出されているので,そちらを使用することもできます。
センサの信号ケーブルの先端はGROVEコネクタがついているので,これを取り外して使います。(針先で白い爪を持ち上げると,コネクタからケーブルを抜くことができます。)


5 テストプログラム

MakeCodeを使います。
MakeCode画面で「拡張機能」を開くと,拡張機能の一覧にGroveがありますので,これを組み込みます。(一部品しか使いませんが)



拡張機能Groveが取得出来たら,あとは,組み立てるだけです。
配線の段階でP1を使うことにしたので,プログラムにおいても,データ取得は「P1」であることを設定します。
取得できた距離を四捨五入して小数点以下1桁でコンソールに表示します。
なお,micro:bit v1とv2では使用すべきブロックが異なります。

  Grove Ultrasonic Rangerの動作テスト用プログラム
  (1) micro:bit v1のとき



  (1) micro:bit v2のとき



コピペする場合は,拡張機能の一覧からGroveを取り込んでから,次のソースコードをPythonソースとして貼り付ければ完了です。
  (1) micro:bit v1のとき

range_URS = 0

def on_forever():
    global range_URS
    range_URS = Math.round(grove.measureInCentimeters(DigitalPin.P1) * 10) / 10
    serial.write_line("range = " + convert_to_text(range_URS))
basic.forever(on_forever)

  (2) micro:bit v2のとき

range_URS = 0

def on_forever():
    global range_URS
    range_URS = Math.round(grove.measureInCentimeters_v2(DigitalPin.P1) * 10) / 10
    serial.write_line("range = " + convert_to_text(range_URS))
basic.forever(on_forever)

距離Lを求めるには,音波の往復時間Tと音速Vsを使って
L = T × Vs ÷ 2
で求められます。Tはμsの単位で求められるので,音速(20℃)を 344 m/s = 334/10000 cm/μsとすると
L = T × 344/10000/2 = T × 0.0172 単位cmで求められるはずです。

Groveの拡張機能にはmicro:bit v1(v1とは書いてない)用とv2用のブロックがあります。

〇v1用のソースコードには
RangeInCentimeters = duration * 153 / 29 / 2 / 100
とありますので,これは
RangeInCentimeters = duration×0.0264 で計算していることになります。
GroveUltrasonicRangerの音波の往復時間のパルスが,1.53倍長いパルスに見えていることになります。

〇v2用のソースコードには
RangeInCentimeters = duration * 153 / 44 / 2 / 100
とありますので,これは
RangeInCentimeters = duration×0.0174 で計算していることになります。
これは先の計算通りです。

どうして,このようなことが起こっているのか調べてみました。
GroveUltrasonicRangerで測距しているときに,オシロスコープに見えているパルス幅は9.6msでした。
パルス幅を測定するプログラムを書いて,micro:bit v1とv2で比べてみました。
micro:bit v1で,プログラム上で測定したパルス幅は6.28msになりました。
micro:bit v2で,プログラム上で測定したパルス幅は9.65msになりました。(同じプログラムを使っています)
micro:bit v2ではプログラム上でも正しく計測されています。
micro:bit v1ではなんと6.28/9.6=1/1.53倍になっています。これはパルス幅測定機能のバグですね。
Mu環境で作成したプルログラムのパルス幅測定機能は正しく動作しているので,このバグはmicro:bit v1+MakeCodeで使用しているパルス幅測定機能に特有のものと思われます。 この差をGroveの拡張機能は計算上で補正していたことになります。(偉い!拍手)
この話の続きは こちらです。

またこのソースコードでは1回の測定につき,50msのpauseが組み込まれています。すなわち,最低でも50msの間隔を空けて使うようになっています。


6 まとめ

超音波距離センサ(Grove Ultrasonic Ranger)を使用して,4m程度までの距離測定ができました。


7 サーボモータの応用

サーボモータに超音波距離センサを載せて周囲をスキャンして物体認識 



補足

オシロスコープで信号線(micro:bit P1)を観察してみました。
この信号線はmicro:bitからセンサに向けての測定要求と,センサからmicro:bitに向けた「超音波一往復の時間を表す信号」の2つの用途に使われています。
このような双方向の信号を1本の信号線でやり取りするのは奇抜な信号線の使い方です。
micro:bitの舞台裏では,測定要求を表すパルスを送り,戻ってきた「超音波一往復の時間を表す信号」の長さを測定して,それに音速をかけて,距離に変換して,ユーザプログラムに教えてくれています。
この例では「超音波一往復の時間を表す信号」の長さは1200μ秒なので,音速を341m/sとすると距離は20.5cmとなります。