以前、「M5Stackで距離を測る」という記事でいくつかの測距センサで距離を測りましたが、10mぐらいの距離が測れる安価なセンサが欲しかったので、TFMini-Sという赤外線測距センサを使ってみました。

TFMini-S – Micro LiDAR Module

TFMini-S – Micro LiDAR Moduleは赤外線を使い、対象物まで赤外線が往復する時間から距離を測るセンサです。測れる距離は対象物の反射率によって異なり、反射率90%の白い物体の場合10cmから12mまで、反射率10%の黒い物体の場合10cmから7mまで測れます。

マイコンとはシリアルかI2Cで通信し、初期状態ではシリアルで通信するように設定されています。

M5Stackで距離を測る」で評価した測距センサとTFMini-Sのスペックを比較すると次のようになります。

接続

TFMini-Sは初期状態で、シリアルで通信するので、M5StickCともシリアルで通信することにします。TFMini-SとM5StickCとは次のように接続しました。

TFMini-S M5StickC
① 黒 GND GND
② 赤 5V 5V
③ 白 RXD/SDA G0
④ 緑 TXD/SCL G26

2020/12/20: ③白と④緑の接続を入れ替えて、③白-G0、④緑-G26にしました。

プログラム

TFMini-Sのマニュアルによると、シリアル通信は次のような仕様です。

ボーレート 115200
データビット 8
ストップビット 1
パリティチェック None 

M5StickCでG26をTXD、G0をRXDにして同じ条件で通信するには、次のように初期設定します。

Serial1.begin(115200, SERIAL_8N1, 0, 26);

シリアル通信のデータは次のような9バイトのフォーマットになっています。距離の単位はセンチ(cm)です。

バイト0 0x59 フレームヘッダ
バイト1 0x59 フレームヘッダ
バイト2 Dist_L 距離(下位バイト)
バイト3 Dist_H 距離(上位バイト)
バイト4 Strength_L 信号強度(下位バイト)
バイト5 Strength_H 信号強度(上位バイト)
バイト6 Temp_L 温度(下位バイト)
バイト7 Temp_H 温度(上位バイト)
バイト8 Checksum  チェックサム

フレームヘッダを見つけ、9バイトのフレームを受信し、チェックサムを計算するプログラムは次のようになります。

動作確認

プログラムを動かし、机から天井までの距離を測り、結果をシリアルプロッタに表示してみました。

値はほぼ134cmです。個体差かもしれませんが、LIDAR-Lite v3HPが測るたびに5〜6cmの幅で値がぶれたのに対して、TFMini-Sの出力値は非常に安定していて、複数回測って平均を取る必要もありません。

上記のプログラムはTFMini-Sで対象物までの距離を測り、距離と信号強度をM5StickCのLCDに表示します。134cm離れた白い壁までの距離を測ったときの信号強度は3880程度、5m離れた焦げ茶色のドアで300ぐらいでした。信号強度が100未満になると測定結果は信頼できなくなるとのことでした。

I2Cで通信する

1台のマイコンで複数台の測距センサを扱いたい場合があります。TFMini-Sは初期状態ではシリアルで通信するので、このままでは複数台つないで制御できません。そこで、TFMini-SをI2Cモードに切り替えて通信しました。

I2C通信モードに切り替える

TFMini-SをI2Cモードに切り替えるには、シリアル通信でコマンドを送ります。M5StickCにTFMini-Sを接続し、次のプログラムを動かすことで、I2Cモードに切り替えられます。

TFMini-Sのシリアル通信は通信速度115200bps、データ8ビット、ストップビット1ビット、パリティチェックなしなので、次のようにSerial1オブジェクトを初期設定して通信します。TFMini-SのRDX(白)線をM5StickCのG0、TXD(緑)線をG26につなぎます。

Serial1.begin(115200, SERIAL_8N1, 26, 0);

このプログラムを実行すると、M5StickCの液晶画面に「set I2C mode」「save settings」と表示され、TFMini-SはI2Cモードに切り替わります。それ以降はシリアルでは通信できなくなるので、注意が必要です。

シリアル通信モードに切り戻す

TFMini-Sをシリアル通信モードに戻すには、I2C通信でコマンドを送ります。TFMini-SをI2Cでアクセスするライブラリがあるので、Arduino IDEにインストールします。Arduino IDEの「ツール」メニューから「ライブラリを管理…」を選択してライブラリマネージャを立ち上げます。検索窓に「tfmpi2c」と入力し、TFMPI2Cというライブラリを探し、「インストール」をクリックします。

TFMini-Sをシリアルモードに切り替えるプログラムは次のようになります。

このプログラムを実行すると、M5StickCの液晶画面に「set Serial Mode..」「save settings..」と表示され、TFMini-Sはシリアルモードに切り替わります。それ以降はI2Cでは通信できなくなります。

I2C通信で距離を測る

TFMini-SをI2Cでアクセスするライブラリには getData という関数があり、この関数で距離と信号強度、センサ温度が取得できます。

bool getData( int16_t &dist, int16_t &flux, int16_t &temp);

getData 関数を使って距離を測り、M5StickCの液晶画面に表示するプログラムは次のようになります。

複数台のTFMini-Sを制御する

TFMini-SのデフォルトI2Cアドレスは0x10ですが、コマンドでI2Cアドレスを変更できます。複数台のTFMini-Sを制御するには、それぞれのI2Cアドレスを別の値に変えておいて、TFMini-Sをバス接続して制御することもできます。

別の方法として、I2Cハブを使う方法があります。M5Stackのユニットに「M5Stack用Port A(I2C)拡張ハブユニット」があり、これ使うと、同じI2Cアドレスのデバイスであっても複数制御できます。プログラムは次のようになります。この他に
* https://github.com/m5stack/M5Stack/tree/master/examples/Unit/PaHUB_TCA9548A
の下にある ClosedCube_TCA9548A.cpp と ClosedCube_TCA9548A.h というファイルをダウンロードして、同じフォルダに置きます。

プログラムはTFMini-Sを管理する TFMPI2C というオブジェクトを一つ定義し、1つのオブジェクトで複数台のTFMini-Sにアクセスしています。I2C通信でコマンドを送り、センサデータを取得するまでは通信対象のデバイスは切り替わらないので、1つのオブジェクトで複数台のデバイスと通信できます。