2017年12月10日日曜日

デジタル積雪計を作る③ -距離センサVL53L0Xを動かす-

前回:デジタル積雪計を作る②

12月になりました。
ブログの更新が滞っているせいで進捗が無いように思えますが、ブログが遅いだけで進捗は出まくってます。


今回はESP32を使って距離センサVL53L0Xを動かします。

VL53L0XはマイコンとI2Cを使って通信するので、ケーブルは電源、GND、SDA、SCLの4本あれば動きます。すぐ出来そうな気がします。



センサは前回スイッチサイエンスにてESP32と一緒に購入しています。
センサの入っている袋にはまっすぐなピンヘッダとL字型のピンヘッダが入っていますが、今回はL字型を使うことにして、センサをテープなどで固定しながらハンダ付けします。

そうしたら、下の画像のようにつなぎます。

[VL53L0X] - [ESP32]
VIN - 3V3 (VOUTが5.5V以下でればVOUTでも良い)
GND - GND (ESP32はいっぱいあるけどどこでも良い)
SDA - 21ピン
SCL - 22ピン
下の画像ではESP32とVL53L0XがぶつかりそうだったのでESP32を逆向きに挿していますが、USBコネクタがブレッドボードの外側になるように配置しても大丈夫でした。
むしろ、画像のようにやるとVIN-3V3間が遠くなるのでアレです。



ハードが終わったら次はソフトです。
VL53L0Xはレジスタが公開されていないらしくかなり大変な作業になる予感がしていましたが、幸いにしてArduino用にはセンサモジュールの発売元がらライブラリが公開されています。
ということで、GitHub - pololu/vl53l0x-arduino: Pololu Arduino library for VL53L0X time-of-flight distance sensor にアクセスし、緑色の[Clone or download]ボタン内にあるDownload ZIPからZIPをダウンロードします。
その後、解凍せずに、プログラムを書き込むArduinoIDEを起動して[スケッチ]->[ZIP形式のライブラリをインストール]でライブラリをインストールします。


また、同じく[スケッチ]->[ライブラリを管理]でライブラリマネージャを開き、[検索をフィルタ...]で「VL53L0X」と入力して出てきたPolulu製ライブラリをインストールしても同様のことができるはずです。

ライブラリをインストールしたら、
C:\Users\(ユーザ名)\Documents\Arduino\libraries\VL53L0X\examples\Continuous
あたりにあるContinuous.inoを開きます。

コードに何も手を加えることなく右矢印ボタンで書き込み、書き込み終了後シリアルモニタを開きます。
ボーレート(ビットレート)を9600に設定すると、センサの値がうじゃーっと表示されていく光景を見ることが出来ます。



ここで、値が8160だったかそれくらいになっている場合は、測定可能距離をオーバーしているので、センサから対象物までの距離が約1200ミリ以内になるようにしてください。
また、値が65535の場合はセンサの通信に失敗している可能性があるので、電源がしっかり供給されているか、SDAとSCLの接続ピンを間違っていないかなどを確かめてみてください。

詳しく検証していませんが、このサンプルプログラムだと初めは正常に距離を取得できていても数十秒経過すると65535になることがあります。
この問題の原因はおそらくコードに対してシリアル出力が間に合っていないことにあるので、loop()関数の最初か最後あたりにdelay(100);でも突っ込んで、コードのループをゆっくりにしてあげると65535にならずちゃんと動いてくれると思います。



今回はContinuousのサンプルプログラムを使いましたが、Singleのプログラムも同様に使用することが出来ます。

Singleのほうでは距離測定範囲の設定などの項目が色々入っていて一見難しそうですが、内容はシンプルです。
SingleにあるコードをいくつかContinuousに移植してみます。
コードの詳しい説明はGitHubのreadmeに載っています。

sensor.setSignalRateLimit(0.1);
setSignalRateLimit関数では距離測定に使用する赤外線信号の最小振幅を設定します。
デフォルトでは0.25に設定されています。目安として、0.25で1200ミリ、0.1で2000ミリ程度まで測れるということだと思います。
ただ値を小さくすると太陽光などのノイズを拾いやすくなるので測定精度が落ちる場合があります。

sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);

setVcselPulsePeriod関数では、赤外線レーザーのパルス周期を設定します。
readmeいわく、値を大きくするほど長距離まで測れるとのことです。
Pre:12~18(偶数のみ、デフォルト14)
Final:8~14(偶数のみ、デフォルト10)

sensor.setMeasurementTimingBudget(20000);
距離測定時間(マイクロ秒)を設定します。デフォルト200000。
よく検証していませんが、こちらの環境ではこの関数を使うとGuruエラーが発生するので使用していません。

以上の関数を使ってContinuousをアレンジすると以下のようになります。

#include <wire.h>
#include <vl53l0x.h>

VL53L0X sensor;

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  sensor.init();
  sensor.setTimeout(500);
  sensor.setSignalRateLimit(0.1);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
  sensor.startContinuous();
}

void loop()
{
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();

  delay(100);
}


これを書き込んで動かせば、おそらく2000ミリあたりまではちゃんと出ると思います。


測ってみた感想としては、ミリ単位だから当然といえば当然ですがデータのバラ付きが大きいのでどうにかしたいなってのがあります。
これは、setMeasurementTimingBudget関数を使ったり、データを集めて統計値を出したりして精度を高くしていけば解決しそうです。




さて、これで距離センサVL53L0Xを使うことが出来ました。
次回は積雪計としてのプログラムを書いていきましょう。

0 件のコメント:

コメントを投稿