本記事の概要
レーザー測距センサVL53L0Xを購入し、Zynqで動かせるようにしてみました。
VL53L0XはSTマイクロ社から販売されているレーザー測距センサです。このセンサは対象までの距離を測定する測距センサで、レーザーが対象に反射してから戻ってくるまでの時間から対象までの距離を計算しています。
VL53L0Xを扱うためのAPIがArduinoのスケッチやpythonのコードの形式で公開されており、ArduinoやRaspberry Piに手軽に実装することが可能です。
しかし、Zynqで使用している例はあまりなかったので、今回実装できるようにしてみました。
目標
図のようにして、Zynqが1秒おきに割り込みでVL53L0Xから距離をI2C通信で読み出すようにしました。読み出した距離をPCにUARTで送信し、PCは受信した距離を表示するようにしています。
レーザー測距センサVL53L0Xについて
冒頭でも記載しました通り、VL53L0XはTime-of-Flight(ToF)という原理で動いていて、「赤外レーザー光が対象に反射してから戻ってくるまでの時間から対象までの距離を測定する測距センサ」です。
世の中にはToFをカメラにして三次元測定できるものも流行っていますが、今回使用したのはカメラのように二次元アレイ化されているものではなく、奥行きのみわかる単一のセンサです。
VL53L0Xの主な仕様を表にまとめました。
項目 | 仕様 |
サイズ | 4.40 x 2.40 x 1.00mm |
動作電圧 | 2.6-3.5 V |
光源 | 940 nmレーザー (class 1) |
最大計測距離 | 2 m |
動作電圧は2.6-3.5Vですが、Amazonで販売される基板実装されたモジュールにはレギュレーターが入っていることがほとんどで、3.3Vだけでなく5.0Vにも対応しています。今回使用するZyboのPmod端子は3.3V出力ですので、問題なく使用できます。
サイズも、例えばスイッチサイエンスの基板で15mm四方ですので、家庭でIoTデバイスやラジコンカーを自作するときにほとんど邪魔にならないと思います。価格も1,000円前後ですので、趣味の電子工作にはお手頃の価格帯です。
ホスト側のデバイスからVL53L0XをI2C通信で制御することができます(I2Cアドレスは0x52)。
残念ながら、VL53L0Xのレジスタマップは公開されていません。しかし、ホスト側のデバイスで使用するための、API (Application Programming Interface)が公開されているので、APIを活用してアプリケーションを構築することができます。Seeed studioやPololuなどのサードパーティから、APIを利用したより使い勝手の良いArduinoのスケッチやpythonのコードも公開されていますので、これらを利用して開発工数を減らすことが可能です。
最後に、肝心の計測精度です。測定時間や計測対象の色や距離にも依存するので、一概に言えません。詳細はデータシートを参照ください。参考までに、測定時間200 msの高精度モードでの計測精度を述べると、計測距離1.2mの場合の精度が標準偏差で±3%とのことです。数cmくらいの誤差は出るようですね。
VL53L0XとZyboの接続
接続構成図
改めて、VL53L0XとZyboの接続のイメージ図を示します。
ZyboがI2C通信のマスター、VL53L0Xがスレーブの役割をします。
I2C通信を行うためのZyboの端子はPmod端子のJBとします。ピンの対応は表のとおりです。
I2C通信配線名 | Zyboピン | VL53L0X |
SCL | Pmod JB04 (W20) | SCLピン |
SDA | Pmod JB03 (V20) | SDAピン |
Vdd | Pmod JB06 | Vin |
GND | Pmod JB05 | GND |
接続はZyboのPmodの2.54mmピッチの12ピン(2×6)ソケットに、VL53L0Xの基板のピンヘッダを差し込むようにしました。
VL53L0Xのはんだ付け
私はKKHMF社のVL53L0Xモジュールを購入しました。
購入時点では、写真の通り基板にピンヘッダがはんだ付けされていない状態で納品されます。
はんだ付けをするだけですが、注意点として基板の表と裏を間違えないようにしましょう。写真で見えている面にVL53L0XのICチップが実装されていますので、こっちの面が外側(表側)に来るようにはんだ付けを行います。
Zyboとの接続
写真の通り、Zyboのピンソケットに差し込めば、完成です。
Zynq内部のブロック構成
構成イメージ
Pmod JBはZynqのProgrammable Logic (PL)の汎用I/Oと接続しています。
PS部をマスターとしてVL53L0XとI2C通信したいので、下のブロック図のようにPS部のEMIO (Extended MIO)からPL部を経由してPmod JBに信号を送るようにしました。
また、1秒おきに読み出しを行うためのタイマーからの割り込みをPS部に入力します。PS部から100 MHzのクロックをタイマーに送り、1秒分のカウント(100,000,000)が完了したら割り込みを発生させて、I2C通信を行うようにしました。
ブロックダイアグラム
この構成イメージに基づいて、Vivadoでブロックダイアグラムを作成します。
IPの配置と接続
ブロックダイアグラム上で、[ZYNQ7 Processing System]のIPと[AXI Timer]のIPを配置します。
2つのIPを配置し[Run Block Automation]を選択し、そのまま[OK]をクリック。
[Run Connect Automation]を選択し、こちらもそのまま[OK]をクリックします。
これで、[ZYNQ7 Processing System]と[AXI Timer]が接続され、PS部からAXI Timerを動かせるようになりました。
[ZYNQ7 Processing System]の設定
[ZYNQ7 Processing System]からI2C通信、そしてAXI Timerからの割り込みがかかるように設定します。まず、I2C通信について、EMIOからI2C通信ができるように設定を変更します。
計測した距離をPCにUARTで送信したいので、念のためUART1にもチェックが入っているか確認しましょう。[Run Block Automation]をクリックしたときに、自動でチェックが入っていると思います。
次に、AXI Timerからの割り込みを受信できるようにします。
Zynqの入力側にIRQ_F2Pのポートが出現しますので、そこにAXI Timerのinterruptを接続します。
構成は、タイマー割り込みでLEDを点滅させたときとほぼ同じです。違いは、LEDの点滅ではGPIOを介して外部に信号を出力していましたが、今回はI2Cのバスを外部に出力している点です。
最後に、IIC_0_0のポートを[Make External]で外部ポートにしたら完成です。
ブロックダイアグラムが完成したら、wrapperファイルに変換します。
制約ファイルの作成
IIC_0_0がFPGAのどのピンから出力されるか、制約ファイル上で定義します。ピン対応表に従い、記述を追加します。
I2C通信配線名 | Zyboピン |
SCL | Pmod JB04 (W20) |
SDA | Pmod JB03 (V20) |
制約ファイル[ZYBO_Master.xdc]に、以下の記述を追加しました。
#Pmod JB(Hi-Speed) JB4
set_property PACKAGE_PIN W20 [get_ports IIC_0_0_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC_0_0_scl_io]
#Pmod JB(Hi-Speed) JB3
set_property PACKAGE_PIN V20 [get_ports IIC_0_0_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC_0_0_sda_io]
制約ファイルの作成後、合成と配置配線を行って、bitstream、そしてXSAファイルを作成したら、Vivadoで行う作業は終了です。
測距センサを購入したので、実際に動かしてみました。
次回の記事では、ソフトウェア部分について解説しようと思います。
最後までご覧いただきありがとうございました!
コメント