Arduino UNO R4 Minimaでセンサ・インターフェーシング ㉓ 距離センサ VL53L0X
Adafruitから入手したTOF(Time of Flight Distance)センサ VL53L0X(ST Microelectronics)を利用します。
VL6180X | VL53L0X | VL53L1X | VL53L3CX | VL53L4CX | VL53L5CX | |
---|---|---|---|---|---|---|
手段 | 赤外線 | レーザー | レーザー | レーザー | レーザー | レーザー 4 x 4または8 x 8のマルチゾーン |
分解能 | 20cmでは1mm、60cmでは3mm | - | - | 1mm | - | - |
最大測定距離 | 100mm | 2m(反射面白色) | 4m | 3m | 1mmから最大6m | 4m |
インターフェース | I2C | I2C(最大400kHz) | I2C(最大1MHz) | I2C(最大1MHz) | I2C(最大1MHz) | I2C(400kHz~1MHz) |
動作電圧[V] | 2.7~3.0 | 2.6~3.5 | 2.8V | 2.6~3.5 | 2.6~3.5 | I/O 1.8~3.3V |
モジュール動作電圧[V] | 2.7~5.5 | 3.3~5V 2.6~5.5V |
3.3V | - | 3.3/5 | 2.8/3.3V |
●AdafruitのStemma QT/Qwiicボード
Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。
コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。
●距離センサVL53L0Xのおもなスペック
VL53L0XのデータシートはこのWebページから
- 直接ビーム内をルーペで見ても問題の起こらないclass1のレーザー(940nm)
- 動作電圧 2.6~3.5 V
- 電流 19mA、スタンバイ時5uA
- インターフェース I2C(0~400kHz)
- スレーブ・アドレス 0x29
- 測定距離 デフォルト・モードで約50mm ~ 1.2m、「長距離」モードでは、美しい白い反射面上で 1.5 ~ 2m
- 確度 白色室内120cm時;4%、室外60cm時;7%、灰色室内70cm時;7%、室外40cm時12%。いずれも10cm以上
●使用環境
- Arduino UNO R4 Minima
- Arduino IDE 2.2.1
- Windows10 22H2
●接続
Arduino UNO R4 MinimaのI2C信号とセンサ・ボードをJSTコネクタでつなぎます(Stemma QT/Qwiicボードの写真の比率は異なる)。
●スレーブ・アドレスを確認
従来からよく使われているi2cScanner.inoを動かしてスレーブ・アドレスを確認します。電源は3.3Vです。
0x29を見つけてきました。
●ライブラリの用意
VL53L0Xで検索して、見つかったAdafruit VL53L0Xライブラリをインストールします。
インストールを始めたとき、関連のライブラリや依存関係をインストールするかというパネルが出た場合は、全てをインストールを選びます。
●サンプル・スケッチ
メニューのファイル->スケッチ例から、Adafruit_VL53L0Xのvl53l0x.inoを選択し、コンパイル、実行します。ボードは机の上に置いているので、センサは上を向いています。少し離れたセンサの上部で、紙を上下に動かしているところです。
●4桁の7セグメントLED表示器をつないで測定結果を表示する
連載の第4回目の記事を参照しながら表示器を接続します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ④ 温湿度センサSi7021の測定結果を7セグメントLEDに表示
スケッチです。
7セグメントLED表示器は、第12回 温湿度センサ SHTC3でスレーブ・アドレスが重なったので、デフォルトの0x70から、ジャンパのA0をショートして0x71に変更してあります。デフォルトのまま使うときは0x70で使ってください。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_VL53L0X.h"
Adafruit_7segment matrix = Adafruit_7segment();
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
void setup() {
Serial.begin(115200);
// wait until serial port opens for native USB devices
while (! Serial) {
delay(1);
}
Serial.println("VL53L0X + 7segmentLED");
if (!lox.begin()) {
Serial.println(F("Failed to boot VL53L0X"));
while(1);
}
// power
Serial.println(F("VL53L0X API Simple Ranging example\n\n"));
matrix.begin(0x71);
matrix.setBrightness(0x05); // default 0x0E
}
void loop() {
VL53L0X_RangingMeasurementData_t measure;
Serial.print("Reading a measurement... ");
lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
float distanceMM = measure.RangeMilliMeter;
if (measure.RangeStatus != 4) { // phase failures have incorrect data
Serial.print("Distance (mm): "); Serial.println(distanceMM);
matrix.print(distanceMM, DEC);
matrix.writeDisplay();
} else {
Serial.println(" out of range ");
matrix.print("----");
matrix.writeDisplay();
}
delay(500);
}
実行例です。
●グラフィック・ディスプレイに測定結果を表示
次の記事を参考に、グラフィック・ディスプレイに測定した距離を表示します。
Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑤ 温湿度センサSi7021の測定結果をグラフィック・ディスプレイに表示
スケッチです。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Adafruit_VL53L0X.h"
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
void setup() {
Serial.begin(115200);
// wait until serial port opens for native USB devices
while (! Serial) {
delay(1);
}
Serial.println("VL53L0X + 7segmentLED");
if (!lox.begin()) {
Serial.println(F("Failed to boot VL53L0X"));
while(1);
}
// power
Serial.println(F("VL53L0X API Simple Ranging example\n\n"));
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.drawRect(0, 0, display.width(), display.height(), SSD1306_WHITE);
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(3,3);
display.println("Distance (mm): ");
display.display();
delay(200);
}
void loop() {
VL53L0X_RangingMeasurementData_t measure;
Serial.print("Reading a measurement... ");
lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
float distanceMM = measure.RangeMilliMeter;
if (measure.RangeStatus != 4) { // phase failures have incorrect data
Serial.print("Distance (mm): "); Serial.println(distanceMM);
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10,17);
display.fillRect(1, 17, 116, 44, SSD1306_BLACK);
display.println(distanceMM);
} else {
Serial.println(" out of range ");
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10,17);
display.fillRect(10, 17, 100, 40, SSD1306_BLACK);
display.println("out of range");
}
display.display();
delay(500);
}
実行例です。