はじめに
ロボット戦車を組み立てるにあたって、これまでモーター制御、シリアル通信を試してきたわけですが、今回は距離センサーを試してみようと思います。モーター制御とモーターが筋肉、シリアル通信が神経とすれば、センサーは目ということになります。
距離センサーは超音波センサーや光センサー、レーザーセンサーなどがありますが、今回はレーザーセンサーの VL53L0X を選択してみました。理由は二つで、小さいことと安いことです。正面だけではなくて、斜め前方など最低3つは取り付けたいと思っているので、大きさは重要な要素。当然、数個買っても懐が痛まないことも重要(汗)
使ったもの
- D1 mini ESP32 ESP-WROOM-32
- VL53L0X ×2(AliExpressで購入したもの)
VL53L1Xの方が4mまで計測できるのですが、今回はL0Xの2mで充分です。正式なデータシートには書いていないようですが、一説では最短距離がL0Xの方が短い(3cm?)とのことで、それならL0Xの方が用途に合致しているとも言えます。まずは2個のセンサーの同時計測を実験です。
配線図
電源とI2Cは共通の配線、センサーのON/OFF制御のためのXSHUTだけ別々に配線します。
ESP32は、例によって内側のピンのみ利用しています。
プログラム
VL53L0X用のライブラリは、VL53L0X by Pololu と Adafruit_VL53L0X by Adafruit が良く使われているようですが、まずは Pololu の方を使ってみました。
VL53L0XのI2Cアドレスはデフォルトで0x29だそうですが、複数同時に使う場合にはプログラムから順番にアドレス変更をする必要があります。端的に言えば、すべてのセンサーのXSHUTをLOWにして、順番にHIGHにしつつアドレス変更をしていくことになります。
それらとサンプルプログラムを参考に作ったプログラムが下記です。
#include <Wire.h> #include <VL53L0X.h> VL53L0X sensor1, sensor2; void setup() { Serial.begin(9600); Wire.begin(); // 制御用ピンのセットアップ pinMode(16, OUTPUT); pinMode(17, OUTPUT); digitalWrite(16, LOW); digitalWrite(17, LOW); delay(10); // sensor1 初期設定 digitalWrite(16, HIGH); sensor1.setTimeout(500); if (!sensor1.init()) { Serial.println("Failed to detect and initialize sensor!"); while (1); } // 精度設定 sensor1.setMeasurementTimingBudget(20000); sensor1.setAddress(0x31); // sensor2 初期設定 digitalWrite(17, HIGH); sensor2.setTimeout(500); if (!sensor2.init()) { Serial.println("Failed to detect and initialize sensor!"); while (1); } // 精度設定 sensor2.setMeasurementTimingBudget(20000); sensor2.setAddress(0x33); } void loop() { // 計測してシリアル出力 Serial.print(sensor1.readRangeSingleMillimeters()); Serial.print(","); delay(100); Serial.println(sensor2.readRangeSingleMillimeters()); delay(500); }
10~15行目ですべてのXSHUTへの信号をすべてLOWにして、17~26行目でセンサー1の初期化とアドレス変更、28~37行目でセンサー2の初期化とアドレス変更をしています。あとは計測してシリアル出力するだけ。
測定結果
プログラムは無事に動いたのですが、困ったことになりました。2つのセンサーを並べて距離測定してみたのですが、何度やってもセンサー1とセンサー2で1~3㎝くらいのズレが発生してしまって、どうも芳しくありません。シリアル出力した結果の一部が下記です。精密な測定ではないですが、それにしても差が大きいように思います。
------
247,232
247,237
247,224
240,232
246,228
257,220
244,225
253,229
244,216
242,219
------
センサー不良かと他のセンサーに変えてもみましたが、大小の差はあれど同じような結果。センサーを入れ替えると数字は入れ替わるものの、誤差は相変わらずです。
そこで、試しにとAdafruitの方のライブラリを試してみました。サンプルスケッチをほぼそのまま使ったので、ここにプログラムを載せることはしません(著作権とかありそうだし)が、結果は以下の通り(1,2はセンサーの番号)
------
1: 222 2: 224
1: 222 2: 222
1: 225 2: 216
1: 220 2: 211
1: 227 2: 223
1: 225 2: 218
1: 220 2: 222
1: 218 2: 220
1: 222 2: 222
1: 224 2: 219
------
やはり差はあるものの、明らかに小さいように思います。
ううむ、この違いは何だろう...Pololuのライブラリも使っている人はたくさんいるわけで、変なものとは思えないのですよね。まあそもそも、使ったセンサー自体がPololuのモジュールでもAdafruitのモジュールでもないですし、そういうところにも原因があるのかもしれません。原因はおいおい探求することとして、とりあえず製作中のロボット戦車では Adafruitの方のライブラリを採用してみます。