今回はM5Stackで距離を測ります。

測距センサー

測距センサーにはいくつかの方式があります。今回使うセンサは、超音波や赤外線レーザーなどを物体に向けて発信し、反射した音波なりレーザーなりを受信して、往復にかかった時間を測定し、それを音や光の速度で割って距離を計算するものです。

今回は三つのセンサーで距離を測り、比較してみます。写真の左からガーミン製のLIDAR-Lite v3HP、スイッチサイエンス製のVL53L0X、SparkFun製のHC-SR04です。今回使った距離センサーの仕様を表1にまとめました。

HC-SR04は超音波を使った測距センサーで、2cmから4mまでの距離が測れ、分解能は0.3cmとのことです。音速は約340m/sなので、1マイクロ秒で0.34mm進みます。1mmの往復で約6μ秒、1mの往復で約6m秒かかる計算になります。HC-SR04は物体までの超音波の往復時間をプログラムで測り、距離を計算します。

VL53L0Xはレーザーを使ったセンサーで、2mまでの距離が測れ、分解能は1mmです。最短の測定可能距離はデーターシートからは分かりませんでした。精度は測定対象の反射率で異なり、白い物だと120cm離れたところで4%、5cm程度、灰色の物だと70cm離れたところで7%、5cm程度とのことです。

LIDAR-Lite v3HPはレーザーを使ったセンサーで、測定可能距離はなんと5cmから40mまで測れます。精度は2m未満が5cm、2m以上が2.5cm。照射する赤外線のビーム拡散が8ミリラジアン、角度にすると0.46度ということで、10m先で8cmに広がる程度です。

光の速度は約30万km/sなので、1μ秒で300mも進みます。数センチの精度で距離を測るためにはピコ秒オーダーの時間測定が必要になります。レーザーを使った測距センサーはセンサー内部で時間を測定し、距離を計算して、結果をI2Cインタフェースでマイコンに通信します。

M5Stackに測距センサーをつなぐ

三つのセンサーをいっぺんにM5Stackにつなぎ、同時に距離を測って比べてみます。

HC-SR04はトリガ端子とエコー端子があります。トリガ端子を10μ秒以上HIGHにすると超音波パルスを発信し、発信してから反射波を受信するまでエコー端子がHIGHになるので、トリガ端子、エコー端子はGPIOにつなげば大丈夫です。M5StackのGPIO2とGPIO5につなぎました。

M5Stack HC-SR04
GPIO2 Trig端子
GPIO5 Echo端子 

VL53L0XとLIDAR-Lite v3HPはI2C接続なので、それぞれのSDAをM5StackのGPIO21に、SCLをGPIO22につなぎます。VL53L0Xの電源電圧は3.3〜6Vなので3.3Vに、LIDAR-Lite v3HPは4.5〜5.5Vなので5Vにつなぎました。また、LIDAR-Lite v3HPのデーターシートにあるように、5VdcとGNDに間に680μFのコンデンサを入れています。

M5Stack VL53L0X LIDAR-Lite v3HP
GPIO21 SDA SDA
GPIO22 SCL SCL
3V3 VDD  
5V   5Vdc
GND GND GND 

プログラム

HC-SR04

HC-SR04はトリガ端子を10μ秒以上HIGHにすると超音波パルスを発信し、発信してから反射波を受信するまでエコー端子がHIGHになります。HIGHの時間が物体までの往復時間なので、それを測り、その半分(片道)を音速で割ると距離が求められます。

エコー端子がHIGHになる時間はArduinoのpulseIn関数で測れます。

pulseIn(pin, value[, timeout]);

pulseInは、ピン番号pinがHIGHまたはLOWである時間を測り、結果をマイクロ秒で返します。timeoutを指定した場合、timeout μ秒経過すると0が返ります。

HC-SR04で距離を測るプログラムは次のようにライブラリにしました。

VL53L0X

VL53L0Xで距離を測るライブラリはPololu社が公開しているので、それを使います。Arduino IDEを立ち上げ、スケッチメニューの「ライブラリをインクルード」>「ライブラリを管理」でライブラリマネージャを立ち上げ、「VL53L0X」で検索し、「VL53L0X by Pololu」の最新版をインストールします。

ライブラリインタフェースは[Githubのページ](https://github.com/pololu/vl53l0x-arduino)にありますが、基本的な使い方は次のようになります。

* ヘッダファイルをインクルードし、インスタンスを作ります。
* setup関数で、初期化し、タイムアウト値を設定し、startContinuousで連続測定を開始します
* loop関数で、readRangeContinuousMillimetersで測定結果をmmで取得します

LIDAR-Lite v3HP

LIDAR-Lite v3HPのライブラリはガーミンが公開しています。Arduino IDEを立ち上げ、スケッチメニューの「ライブラリをインクルード」>「ライブラリを管理」でライブラリマネージャを立ち上げ、「lidar-lite」で検索し、「LIDAR-Lite by Garmin」の最新版をインストールします。

基本的な使い方は次のようになります。

* ヘッダファイルをインクルードし、インスタンスを作ります。
* setup関数で、初期設定します
* loop関数で、センサーがビジーの間待ち、距離を測定し、データを取得します

生データを見る

三つのセンサーをM5Stackにつなぎ、40cm程度の距離に物を置き、距離を測って、シリアルに表示してみました。

出力結果をシリアルプロッタに表示したのが次の図です。

青い線がHC-SR04、赤がVL53L0X、緑がLIDAR-Lite v3HPです。センサーを置いた位置やセンサーから対象物までの距離が微妙に違うので、絶対値には差がありますが、HC-SR04は値が比較的安定しているのに対し、特にLIDAR-Lite v3HPは測るたびに5〜6cmの幅で値がぶれました。測定に使った個体の問題なのか、センサーの特性なのか不明ですが、LIDAR-Lite v3HPは数センチのブレがあるようです。

そこでVL53L0Xは10回、LIDAR-Lite v3HPは20回測定して平均を取るようにしました。測定結果をM5StackのLCDに表示したのが次のプログラムです。

10cmから100cmまで測ってみる

三つのセンサーで対象物までの距離を10cmから100cmまで変えて測ってみました。結果が次のグラフです。

青がHC-SR04、赤がVL53L0X、緑がLIDAR-Lite v3HPです。10cmから100cmの範囲ではHC-SR04とVL53L0Xは比較的正しい値が得られているのに対し、LIDAR-Lite v3HPは特に10〜20cmといった近距離では低めの値になるようです。

速度を測る

LIDAR-Lite v3HPは40mまでの距離が測れるので、それを利用して物の速度を測定してみます。

例えば時速40kmで走っている車は1秒間に約11m進みます。そこで、対象物までの距離を0.5秒間隔で2回測り、移動距離から速度を計算してLCDに表示してみました。

測定用のビームが10m先で8cmにしか広がらないので、対象物を捉えるのが難しいですが、うまく捉えられれば速度が測定できます。なお、この製品はclass1のレーザーを使用しています。通常使用時には危険性はありませんが、人に向けては照射しないでください。