2017年7月16日日曜日

VL53L0X

 VL53L0Xというセンサを試してみた。
 STMicro製で、ToF(Time of Flight)というタイプの距離センサ。ざっくり説明すると、超音波距離計の光波バージョン。
 以前にSTMが似たセンサを出していたが、そっちはレンジがかなり狭かった。VL53L0Xでは最大2m程度までレンジングできるらしい。



 テスト環境。STBee F4miniの上にVL53L0X変換基板を載せてる。穴位置がかなりちょうどいい。センサ本体はかなり小型だけど、付加回路がいろいろ必用だったりコネクタが大きかったりで、結局DIP16の変換基板くらいの規模。

上からIRで撮影。さすがにレーザーなので明るい。焼付きが怖いので真上からは撮影しなかった。

ちょっと斜めから撮影。すぐ見えなくなる。

中央右下にセンサ、左上に手のひら。距離は5-10cmくらい? これくらいの距離ならIRで照らされてるのがわかるけど、指向性が低いのでちょっと離れればすぐわからなくなる。


 このセンサはSTMicro製でありながら、わかりやすいデータシートというのが一切ない。曰く「わかりやすいAPIを用意したからそっちを使ってね」ということらしいが、僕が試した限りではAPIは初期化でコケて動作しなかった。
 今回はサードパーティのArduinoライブラリをC言語で書き換えて移植した。一応測距はできるし、距離に応じて値も変化するが、精度はあんまり出ていない感じ。
 結局本家APIを動くようにする必要がありそうな気がする。メンドクサイ。


 センサ自体は0.94umの赤外線レーザーで、データシートにもeye safeとか書いてあるが、0.94umは網膜に結構吸収されるらしいので、あんまり直視しないほうが良いと思う。と言っても非可視光だから、レーザーが目に入っても全く気が付かないのだが。


 なつやすみのじゆうこうさく でVL53L0Xを使いたかったのだが、結構大変そうだ。本当に夏の間に終わるんだろうか。下手したら来年の夏とかになってしまうんじゃなかろうか。。。


追記:2017/07/19
 APIに付属するLinuxDriverMassMarket_1.0.6/kerner/drivers/input/misc/vl53L0X以下のソースを使ったらいちおうレンジングできた。移植するのがとっても、とっても!面倒くさいけど。

 あとLinuxってCCI(Camera Control Interface)にVL53L0Xを突っ込んで動作確認できるみたい。映像出力端子にもI2Cバスは出てるけど、こっちは標準化以外の信号は通すの大変なのかも。カメラインターフェースならメーカー独自機能とかを実装する余地があるとか? とにかく、Winみたいな、外部にマイコンを置いて、それ経由でI2Cを叩いて、みたいな七面倒臭いことはしなくていいらしい。
 それなら最初からマイコンで動くコードを公開しておけよ、という気もするけど。せいぜいI2C R/W回りの関数2個を書き換えれば移植できるだろうから、いちいちプラットフォームに依存した変なサンプルとか作らなくても良いはずなんだが。


追記:2017/07/20

 I2Cバスのパケットをキャプチャ。I2Cは200kbaud。立ち上げに250msecかかっており、1回のデータ転送にも35msecほどかかっている。とにかく1回のデータ転送でのパケット転送量が多い。

 あとLongRangeモードのExampleを試してみた。屋内でたぶん2mくらいまで計測できてるんじゃないかなぁ。だいたい150cmくらいは取れてるし、手のひらをかざせばそれに応じて結果も変化する。ただ精度は不明。

 今回の用途だともうちょっと狭角のほうが使いやすいんだけど、センサの本来の用途としてはこれくらいの角度が良いんだろうなぁ。
 データシートのApplicationsにUser detection for Personal Computers/Laptops/Tabletsとか書いてあって、顔の真正面からレーザーをガンガン浴びせるつもりでいてちょっとアレ。いくらアイセーフ(?)とは言えさぁ。
 でもVL53L0Xはレンジング中以外はレーザーを止めるので、人間がいない時は照射間隔を100msecとか500msecで応答性重視、近くに人間がいそうであれば5000msec周期くらいで照射間隔を広げて、みたいな安全策はできるかも。どこまで効果あるのか走らんけど。
 はっ、このレーザーを浴びれば虹彩の色が抜けて…?


 とにかく、VL53L0Xは使用コストがかなり高そうだ。特に30msec周期近い高レートで測距を行う場合、I2Cバスはほぼ100%近くの使用率になる。当然ポーリングで通信を書いているとCPU使用率も同程度になる。
 I2Cバスに他のセンサをつけたり、VL53L0Xを複数個使おうとすると、相当面倒なことになりそうだ。高レートで2-4個使いたいと思ってたんだけどなぁ。I2C転送中も大抵は1バイト単位での転送だから、DMAとか使ってもほとんどCPU使用率は変わらなそう。1バイトの転送はせいぜい数十usecだから、割り込みとか使ってもOSのオーバーヘッドであんまり効果なさそう。

1 件のコメント:

  1. バス専有はサンプルがVL53L0Xのレジスタを全力でポーリングしながら待っているせいですね。GPIOを使うか、1msec間隔とかでポーリングすればOKでした。

    返信削除