DIST-ToF
LEGO社のサードパーティ製品を製造・販売しているmindsensors社から,ToF距離センサ(DIST-ToF)が販売されています.
ToFは"Time of Flight"の略で,(赤外)光が跳ね返ってくるまでの時間から距離を計測するという技術です1.
ToF技術により,対象物の位置をピンポイント,かつ,正確に計測できるようになりました.
mindsensorsが販売しているセンサの多くは,EV3MicroPythonのベースとなっているev3devで対応しています2.
そして,ev3devで対応しているセンサは,EV3MicoroPythoh(pybricks2.0)のiodevices
モジュールのEv3devSensor
クラスで簡単に制御することができます.
しかし,このDIST-ToFセンサは,ev3devに対応していません(コマンドが実装されていません).
ただし,このセンサはI2C通信により制御することができます.
そこで,今回はEV3MicroPythonで直接I2C通信を扱う方法について紹介していきます.
そして,Ev3MicroPythonでDIST-ToFセンサを扱えるようにしていきます.
I2C通信
I2Cは,フィリップス社(現NXP社)が開発したシリアルバス(シリアル通信の一種)で,シリアル・データライン(SDA)とシリアル・クロックライン(SCL)の2本の線を使ってデバイス間の通信を行う手法です.
少ない本数で複数のデバイスと通信できるため,組み込み機器や携帯電話などで利用されています.
なぜ,2本線で「複数のデバイス」間の通信ができるのかというと,それは,デバイス毎にアドレスが設定されているからです3.
また,I2C通信はマスター・スレーブ方式4を採用しています.今回の場合は,EV3がマスター,DIST-ToFがスレーブとなります.
EV3MicroPython(Pybricks2.0)では,I2C通信を扱うクラスとしてiodevices
モジュールにI2CDevice
クラスが用意されています.I2CDevice
クラスの仕様については,こちらを参照してください.
EV3MicoPythonでI2C通信
以下のソースコードは,EV3MicroPythonで,I2CDevice
クラスを用いてDIST-TOFのセンサ値を取得するプログラムの実装例です.取得した値は,EV3の液晶画面に表示されます.
実装したプログラムは,RobotC向けに公開されているGitHubのコードを参考にしています.
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.parameters import Port
from pybricks.tools import wait
from pybricks.media.ev3dev import Font
from pybricks.iodevices import I2CDevice
# Write your program here
ev3 = EV3Brick()
ev3.speaker.beep()
font = Font(size=20)
dist = I2CDevice(Port.S4, 0x02 >> 1)
def get_ms_dist(dist):
data = dist.read(0x42, length=2)
return (0xFF & data[0]) + ((0xFF & data[1]) << 8)
ev3.screen.set_font(font)
while True:
ev3.screen.clear()
ev3.screen.print("DIST :", get_ms_dist(dist))
wait(100)
まず,I2CDevice
クラスから,dist
インスタンス(クラスオブジェクト)を生成します(14行目).
コンストラクタの引数には,センサを接続するポート(Port
クラス)と,センサのアドレス(16進数)を入力します.
ここで,DIST-ToFの(デフォルト)アドレスは0x02
です.
ただし,アドレスを1ビット右にシフトしたものを入力するようにしてください3.
get_ms_dist
関数(16-18行目)では,以下の処理を行なっています.
- 引数として,
I2CDevice
クラスのクラスオブジェクトを渡す(dist
インスタンスを想定). -
I2CDevice
クラスのread
関数を呼び出し,センサの値を取得します.- ここで,DIST-ToFの距離情報を取得するためのアドレスは
0x42
で,データ長は2バイトとなります.
- ここで,DIST-ToFの距離情報を取得するためのアドレスは
- 2バイトのデータを足し合わせて,1つのデータにします.これを距離データとして返します.
DIST-ToF用のクラスを用意し,クラス内でget_dist
関数を実装する方がスマートなプログラムになりそうです.
前述のように,DIST-ToFは通信方式にI2Cを採用しているため,アドレスの異なる他のセンサと組み合わせることで,EV3の1つのポートで複数のセンサを制御することができます.