Pico

【質問回答】RaspberryPi Pico MicroPythonでMTOF171000C0を動かす方法

はじめに

RaspberryPicoで、ToF測距センサ「MTOF171000C0」 を動かす方法について質問をいただきました。

MTOF171000C0は価格も安く、3.3VなのでPicoと直結することもできます。結線済みの配線も付属しているので、初心者や工作が苦手な方にもおすすめのセンサです。

良いセンサではあるのですが、残念ながら、販売元の秋月電子にはArduinoのコードのみしか公開されておらず、質問者様はPicoでの使用を断念しているとのことでした。

そこで今回は「MTOF171000C0」 をMicroPythonで動かす方法について解説したいと思います。

こんな人におすすめ
  • 安い費用の測距センサーで遊んでみたい。
  • 安い費用でI2C通信を試してみたい。
  • 手を動かしながら、MicroPythonを覚えたい。
  • 人についていくロボットカーを作りたい。

環境

この記事は以下の環境で作成しています。

環境バージョンなど備考
Thonny   3.3.13
OSWindows 10
センサMTOF171000C0 秋月電子 商品コード(M-14538)  
言語Micro Python

Picoのセットアップ方法や、開発環境については以下の記事をご覧ください。

ToFセンサ MTOF171000C0

税込み780円で購入できる赤外線レーザを使った測距センサです。
安価ですが、流行りのToF(Time of Flight)で距離を計測する方式を採用しており、Pico と同じ3.3Vで駆動します。配線付きのコネクタも付属しているので、半田付けなしで簡単にPicoと接続することができます。

詳細は秋月電子の商品ページをご覧ください。

※ 画像は秋月電子の商品ページより引用

※ 価格は記事作成時のものです。

PicoとMTOF171000C0の接続

以下のように、Picoと MTOF171000C0を接続します。
センサの4番RXDは、「モジュール選択ピン」も兼ねており、I2C通信をする前に「Low」にする必要があります。

RaspberryPi Pico とMTOF171000C0の結線を説明する画像

ピンとコネクタ番号の対応

接続したPicoのピン番号と、センサのコネクタの番号は以下の通りです。

RaspberryPi Pico MTOF171000C0
1番ピン:I2C0 SDA6番:SDA
2番ピン:I2C0 SCL5番:SCL
3番ピン:GND2番:GND
4番ピン:GPIO4番:RXD
-----3番:TXD 使用しません※
36番ピン:3V3 (OUT)1番:VDD

※ センサ側ピンアサインはメーカのアプリケーションノート(P2)に記載。
※ RxDを「モジュール切り替えピン」として使います。TxDは使用しません。

モジュール選択ピンの役割について

メーカ資料に説明はありませんが、このピンは複数のセンサを一つのI2Cのラインにつなげる際に使用するものと推測しています。MTOF171000C0はデバイスのアドレスが1種類のみのため、複数繋げた場合に相手を指定することできません。
そのため、センサを複数つなげた場合は、このピンで通信相手のセンサを指定して(通信したいセンサのみをLowにする)使うものかと思います。

動作は未確認ですが、センサが一つの場合は、このピンをGNDと接続してLowに固定してしまうのも良いかもしれません。(解説ではGPIOを使ってLowに設定します)。

実行結果

後述するコードで距離を測った結果です。固定なしの簡易的な方法で100mm先の白い紙を計測しています。10mm程度のずれは位置を変えても残ったので、センサ個体の製造時のばらつきによるものと思われます。

Thonnyで記事上のコードを実行したところの画像

全体コード

MTOF171000C0で距離を測るコードは以下の通りです。詳細は後述の「コードのポイント」で解説します。

from machine import Pin, I2C
import time

# MTOF171000C0のアドレス(ModuleID)です。
ADDRESS = 0x52

# I2Cのピンの設定です
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)

# GPIOのピンの設定です
# センサの「モジュール選択ピン(センサのRxD)」操作に使います
pin4 = machine.Pin(4, machine.Pin.OUT)

# Picoの処理待ちです。
time.sleep_ms(1000)
    
# センサにデータ送信を伝えるため、選択ピンをLowにします
pin4.value(0)

# センサの処理待ちで、5msec待ちます。
time.sleep_ms(5)
    
for i in range(1000):
    
    # データ取得要求を送信します(0xD3)
    # コマンドは配列として作成します。
    cmd = bytearray(1)
    cmd[0] =0xD3
    #i2c.writeto(ADDRESS, cmd)

    # NG 以下の指定では異常な値が返されます
    # i2c.writeto(ADDRESS, b'0xD3')

    # データを受信します
    data = i2c.readfrom(ADDRESS, 2 )

    # 受信データを距離に変換します
    distance = 0
    distance = data[0] << 8
    distance = distance | data

    # 距離を表示します
    print(str(distance) + " [mm]")  

    # ループ間隔の調整です    
    time.sleep_ms(1000)

# デバイスに通信終了を知らせるために、
# モジュール選択ピンをHighにします
pin4.value(1)
    
print("done")

コードのポイント

I2Cとモジュール選択ピンの設定

Pico側のI2C・GPIOに使うピンの設定をします。
I2Cの周波数はメーカの資料の記載(100kビット/秒 = 100kHz )に合わせて設定しています。

# I2Cのピンの設定です
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)

# GPIOのピンの設定です
# センサの「モジュール選択ピン(センサのRxD)」操作に使います
pin4 = machine.Pin(4, machine.Pin.OUT)

コマンドの送信には配列を使う

MTOF171000C0から距離を要求するのコマンドは「0xD3」のみですが、writeto関数で送信する場合、配列で指定する必要があります。

以下のNGの記載のように、コマンドを配列にせずに指定してもエラーにはなりませんが、受信データが異常な値となるので注意してください。

    # データ取得要求を送信します(0xD3)
    # コマンドは配列として作成します。
    cmd = bytearray(1)
    cmd[0] =0xD3
    #i2c.writeto(ADDRESS, cmd)

    # NG 以下の指定では異常な値が返されます
    # i2c.writeto(ADDRESS, b'0xD3')

受信データは8bitずらして結合する

センサからの距離データは8bit(1byte)のデータで、2つ送られてきます。
データの抜き出し等は不要で、一つ目のデータを8bit分左にずらし、二つ目のデータと結合することで距離データ「mm」が作成できます。

    # 受信データを距離に変換します
    distance = 0
    distance = data[0] << 8
    distance = distance | data

計測範囲外だと「8888」が返される。

計測対象が、測定可能な範囲にない場合は、「8888」が距離としてセンサから送られてきます。距離が「8888」となる場は、計測の対象物とセンサとの距離やセンサの向きを変えてみてください。

測距センサを使ったロボットカー

コメントにて、Picoと測距(距離)センサを使ったロボットカーの事例も紹介いただきました。今回のセンサと同じ I2C接続の「vl53l0x」という距離センサを使って製作されており、ソースはAdafruitのライブラリとサンプルのほぼコピーでOKとのことです。

まとめ

RaspberryPicoで、ToF測距センサ「MTOF171000C0」 を動かす方法について解説しました。みなさんの電子工作のお役に少しでも立てればうれしいです。

応援・要望お待ちしてます

ブログを見ていて「この辺を詳しく知りたい」「このライブラリの使い方を知りたい」「こんなことで困ってる」...etc があれば、コメント・問い合わせ・Twitterで教えてください。質問・ご要望に合わせて解説記事を作ります。

ブログを気に入っていただけたり、「応援してもいいよ」という方がいたら、ブログやSNSでの紹介をお願いします。 あたたかい応援は、中の人の更新の大きな励みになります。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です