Jetson NanoでVL53L1X TOFセンサーを試す

VL53L1X TOFセンサーを試す

Pimoroni製のToFセンサーを購入。Jetsonで動作するか、何ができるのかをトライしてみました。(JetPack4.4)

https://shop.pimoroni.com/products/vl53l1x-breakout

tof000

エッジデバイスとは、I2Cで接続します。(アドレスは0x29)

Jetson-IO tool

Jetpack4.3からGPIO周りの設定を楽にするtoolが公開されています。

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra Linux Driver Package Development Guide/hw_setup_jetson_io.html

すでにインストール済みなので、早速起動

sudo /opt/nvidia/jetson-io/jetson-io.py

デフォルトのGPIO一覧。ラズパイの40ピンレイアウトと互換性があり、電源やGND、主要なI/Oは位置が合わせてある。

tof001

Configure Jetson for compatible hardwareを選択すると、互換のあるサードパーティ製ハードに接続するための設定が選択できる。今のところあんまりない。

tof002

Configure 40-pin expansion headerを選択すると、レイアウトが重複していて、一時的にオフになっている機能などの一覧が表示される。とりあえず2個のpwmなどは、デフォルトだとunuse状態なのでONにしてみる。(今回のToFでは関係ないけど)

tof003

設定を変更したら、再起動後に有効になる。

tof004

GPIOのセットアップ

ワイヤ接続

JetsonのGPIOとセンサを接続します。特筆すべきものはなく、一般的なI2Cセンサと同じように接続すればOK。3-6V(3.3V)、GND、SDA、SCLを接続します。

※INTは未接続

ちなみに、さきほどのjetson-ioだと、PIN3,5はi2c2となっているが、1始まりの2つまり2個目のバスになる。ただ、バス番号は0始まりなので、このPIN3,5はバス番号=1となるので注意する。

tof005

Jetson.GPIOインストール

> git clone https://github.com/NVIDIA/jetson-gpio.git
> sudo mv jetson-gpio /opt/nvidia/
> cd /opt/nvidia/jetson-gpio
> python3 setup.py install

> sudo groupadd -f -r gpio
> sudo -S usermod -a -G gpio $USER
> sudo cp lib/python/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
> sudo udevadm control --reload-rules
> sudo udevadm trigger

i2c-toolsでセンサの接続を確認

もしi2c-toolsがインストールされてない場合はインストールを先に行う

sudo apt install i2c-tools
sudo usermod -aG i2c $USER

i2c-toolsi2cdetectコマンドでバス一覧を表示してみる。7個もチャンネルがある。

i2cdetect -l
i2c-3   i2c             7000c700.i2c                            I2C adapter
i2c-1   i2c             7000c400.i2c                            I2C adapter
i2c-6   i2c             Tegra I2C adapter                       I2C adapter
i2c-4   i2c             7000d000.i2c                            I2C adapter
i2c-2   i2c             7000c500.i2c                            I2C adapter
i2c-0   i2c             7000c000.i2c                            I2C adapter
i2c-5   i2c             7000d100.i2c                            I2C adapter

今回使用するVL53L1Xセンサは1番のバスに接続したので、下記コマンドで0x29が検出されること。

> i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- 29 -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Pimoroni提供のPythonプログラムで動作を確認する

> sudo pip install smbus2
> sudo pip install vl53l1x

サンプルプログラムが実行できるか確認してみる。いくつかシチュエーションごとにサンプルが用意されているが、ほぼこのまま使える感じになっている。

まずはdistance.pyを使って、測定開始。

> git clone https://github.com/pimoroni/vl53l1x-python
> cd vl53l1x-python/examples

> python3 distance.py

Display the distance read from the sensor.

Uses the "Short Range" timing budget by default.

Press Ctrl+C to exit.


VL53L1X Start Ranging Address 0x29

VL53L0X_GetDeviceInfo:
Device Name : VL53L1 cut1.1
Device Type : VL53L1
Device ID :
ProductRevisionMajor : 1
ProductRevisionMinor : 15
Distance: 963mm
Distance: 962mm
Distance: 963mm
Distance: 962mm

つづいて、graph.pyさきほどとほぼ同じだが、グラフ表示する。

> python3 graph.py

Display a bar graph that ranges up to 80cm and turns yellow/red as the range decreases.

Press Ctrl+C to exit.


VL53L1X Start Ranging Address 0x29

VL53L0X_GetDeviceInfo:
Device Name : VL53L1 cut1.1
Device Type : VL53L1
Device ID :
ProductRevisionMajor : 1
ProductRevisionMinor : 15

37.1cm ██████████████████████████████████████████████        

distance.pyとほぼ同じだが、動作モードが違う。distance.pyよりもキビキビ動作している。sleep違うが少し短いが、下記のオプションが有効になっている。詳細は別途確認するとして、測定精度が関係しているんじゃないかと思われる。

UPDATE_TIME_MICROS = 66000
INTER_MEASUREMENT_PERIOD_MILLIS = 70
tof.set_timing(UPDATE_TIME_MICROS, INTER_MEASUREMENT_PERIOD_MILLIS)
tof.start_ranging(0)

あとは、ROI(Region of Interest)モードもある。

以下のアプリケーションマニュアルの「2.5.6 Region of Interest (ROI) setting」に情報がある。

https://strawberry-linux.com/pub/en.DM00474730.pdf

ただ単純に距離を求めるのではなく、一定エリアをグリッド状に測定できないか?と思っているが、別途検証してみる。