ぱらめでぃうす

"don" also known as "doumae" and "donz80"

電子工作

TOFセンサー VL53L0X をArduinoで使う (M5Atomで距離センサーを使う)

LINEで送る
Pocket

M5Stack VL53L0X
M5Stack VL53L0X

TOF (Time of Flight) センサー VL53L0X

TOFセンサーというのは距離を測るためのセンサーです。センサーから送信された信号(光)が対象物に跳ね返って帰ってくるまでの時間を計ることで、センサーから対象物までの距離を測ります。Time of Flightは「光が飛行している時間」という意味ですね)やっていること自体は定番の測距センサーSHARP GP2Y0A21YKと同じです。TOFセンサーによっては二次元平面に対して距離を測定する、つまり3次元の結果を得られるものもあるようです。

今回取り上げるSTMicroelectronics VL53L0XはシンプルなTOFセンサーで、対象との距離を一つだけ測ることができます。GP2Y0A21YKと比べると圧倒的にサイズが小さく、また光源が単なる赤外線LEDではなく赤外線レーザーを使っていて精度が高く、デジタルIF(I2C)で制御でき、測定値が絶対値(mm単位)で得られることがポイントです。値段は倍~三倍ぐらいですが。

このセンサーを使ったモジュールがいろいろ出ていますが、今回はM5Stackのものを入手しました。制御にM5Atomを使おうと思っており、Groveコネクタで接続できること、また、モジュールがケースに入っていることが選択理由です。ただ、その他のモジュールでも同じように利用できると思われます。

センサー仕様書

モジュール

VL53L0X Arduinoライブラリー

今回M5Stack製のモジュールを使用しますが、なぜかM5Stack提供のサンプルプログラムは制御部分がライブラリ化されていません。

Arduino IDEのLibrary Managerからインストールできるライブラリがいくつかあり、こちらを使う方が楽でしょう。よく使われているのはpololu/vl53l0x-arduinoのようですが、後述のモード変更のことを考えるとadafruit/Adafruit_VL53L0Xの方が使いやすそうなので、今回はこちらを使います。

VL53L0Xの仕様で注意すべき点

モジュールの説明には特に書かれていませんが、VL53L0Xには測定タイミングと測定精度(測定可能範囲)についてそれぞれ複数のモードがあります。STMicroの仕様書APIマニュアルには書かれているので、詳しくはそちらを参照してください。

測定タイミング

モード 説明
Single Ranging 単独計測モード
マイコンから指示したときのみ計測を行う。計測が完了するまでにラグがある。
Continuous Ranging 連続計測モード
センサーが常に計測を行う。即座に結果が得られる。
Continuous Timed Ranging 連続時限式計測モード
センサーが指定した間隔ごとに常に計測を行う。

こうしたモードの違いがあるのは消費電力を削減するかリアルタイム性を優先するかといった要求の違いによるものでしょう。また、これ以外にマイコンのGPIOを使った割り込みを使う方法もあるようです。(未調査)

測定精度(測定可能範囲)

モード(Profile) 測定時間 測定可能範囲
Default mode (標準) 30ms 1.2m
High accuracy (高精度) 200ms 1.2m
Long Range (長距離) 33ms 2m
High Speed (高速) 20ms 1.2m

ここでのポイントは、標準状態ではセンサーから1.2mの範囲しか測定できないということです。M5Stackのモジュールの説明にも「2mまで計測可能」と書かれていますし、他のモジュールの説明でも同様に書かれているものもありますが、そのままだと2mは測定できません。私はこれに気づかずにテストコードを書いて2mが計測できずにしばらく悩みました。

なお、VL53L0XのUser Manualにもなんとなく「モード」っぽく書かれていますが、VL53L0X自体にこれらのモードがあるわけではありません。アプリケーションがセンサに与える測定パラメータを変更すると、上記のような典型的プロファイルが作れる、というのが適切かもしれません。なお、Long Rangeにすると測定精度が低下する模様です。

ライブラリによってもこのあたりの扱いが異なり、pololu/vl53l0x-arduinoでは、パラメータをアプリケーション側から設定しなければならないようです。一方、adafruit/Adafruit_VL53L0XではconfigSensorメソッドからモード(プロファイル)を指定することができます。

このあたりを参照してください。

  /** Sensor configurations */
  typedef enum {
    VL53L0X_SENSE_DEFAULT = 0,
    VL53L0X_SENSE_LONG_RANGE,
    VL53L0X_SENSE_HIGH_SPEED,
    VL53L0X_SENSE_HIGH_ACCURACY
  } VL53L0X_Sense_config_t;

それ以外の仕様

測定対象が暗い(黒い)場合測定可能な距離が短くなる点は気をつけた方がいいでしょう。センサーのキャリブレーションを行うこともできるようですが、今回そこまでの精度を必要としないので未調査です。

サンプルコード

Adafruitのサンプルをベースに、Continuous RangingLong Range(2mまで計測)を行う場合のサンプルコード。M5Atomで使うことを想定していますが、ヘッダとWire.begin()あたりを修正すればほかのArduino互換環境でも使えると思います。

17行目が計測モード(プロファイル)の設定、18行目がContinuousモードの起動です。

#include <M5Atom.h>
#include "Adafruit_VL53L0X.h"

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

void setup() {

  M5.begin(true, false, true);
  Wire.begin(26, 32);
  Serial.begin(115200);

  Serial.println("Init M5Atom");

  if (!lox.begin()) {
    Serial.println("VL53L0X Error");
  }
  lox.configSensor(Adafruit_VL53L0X::VL53L0X_SENSE_LONG_RANGE);
  lox.startRangeContinuous(100);
  Serial.println("Init VL53L0X");

}

void loop() {

  if (lox.isRangeComplete()){
    Serial.print("Distance in mm: ");
    Serial.println(lox.readRange());
  }
  delay(200);

}