【ITニュース解説】Interfacing an Industrial Laser Distance Sensor with Raspberry Pi via Python
2026年09月16日に「Dev.to」が公開したITニュース「Interfacing an Industrial Laser Distance Sensor with Raspberry Pi via Python」について初心者にもわかりやすく解説しています。
ITニュース概要
Raspberry PiとPythonを使い、産業用レーザー距離センサーで高精度な距離測定を行う方法を解説。屋外や長距離で±1mm精度が必要な場合に有効だ。配線、Raspberry Piのシリアル設定、Pythonコードによるデータ取得方法が示されている。
ITニュース解説
システムエンジニアを目指す初心者が、最新のIT技術を学ぶ上で、物理世界との接点を持つことは非常に重要だ。この解説では、産業用の高精度レーザー距離センサーを小型コンピューターのRaspberry Piとプログラミング言語のPythonを使って連携させる方法を具体的に説明する。普段、距離測定でよく使われる超音波センサーや赤外線センサーは、比較的安価で手軽に使えるメリットがあるが、屋外での使用時に太陽光などの強い外乱光の影響を受けやすかったり、ミリメートル単位の非常に高い精度が求められたり、数十メートルといった長い距離を正確に測る必要がある場面では、力不足になることがある。このような場合、産業グレードの光学センサー、つまりレーザー距離センサーが不可欠となる。本記事は、そうした産業用レーザー距離センサーをRaspberry Piに接続し、設定を行い、Pythonプログラムでデータを受け取って解析する一連の流れを解説する。
今回使用するレーザー距離センサーは、超小型の位相シフト方式光学モジュールであるLDL-Tシリーズだ。このセンサーは、最小0.03メートルから最大100メートルまでの広い範囲で距離を測定できる。その精度は、±(1 mm + D * 10^-4)と非常に高く、工業用途に十分耐えうる性能を持つ。Dは測定距離を意味し、距離が長くなるほどわずかに精度誤差が増えることを示す。また、1秒間に5回から最大100回まで測定が可能で、高速な応答が求められるシステムにも対応できる。特に注目すべきは、このセンサーが3.3V TTLという電圧レベルで動作する点である。Raspberry PiのGPIO(汎用入出力)ピンも同様に3.3V論理レベルで動作するため、センサーとRaspberry Piを直接接続でき、通常であれば必要となる電圧変換のためのロジックシフター回路が不要となる。これにより、配線が簡素化され、初心者でも扱いやすくなっている。消費電力も3.3Vで80mA未満と低く、Raspberry Piの電源から直接供給できる点も利点だ。インターフェースとしては、USART、RS-485、Modbusといった複数の選択肢があるが、このチュートリアルではUSARTを使用する。
センサーとRaspberry Piの配線は以下の通りに行う。まず、センサーのVCCピンをRaspberry Piの3.3V電源供給ピン(例: Pin 1またはPin 17)に接続する。次に、センサーのGNDピンをRaspberry Piの共通GNDピン(例: Pin 6またはPin 9)に接続して、電源を供給する。データ通信を行うためのシリアル通信ピンは、特に注意が必要である。センサーのTXD(送信)ピンは、Raspberry PiのRXD(受信)ピン(GPIO 15、Pin 10)に接続し、センサーのRXD(受信)ピンは、Raspberry PiのTXD(送信)ピン(GPIO 14、Pin 8)に接続する。データは常に送信側から受信側へ流れるため、送信と受信を逆のデバイスに接続する「クロス接続」が必要になることを覚えておこう。この接続を間違えると、データが正しく送受信されず、センサーとの通信ができない原因となる。
Raspberry Pi側の設定も必要だ。まず、ターミナルを開き、sudo raspi-configコマンドを実行して設定ツールを起動する。設定メニューの中から「Interface Options」に進み、「Serial Port」を選択する。ここで、「Would you like a login shell to be accessible over serial?」という質問には「No」を選択する。これは、シリアルポートをRaspberry Piにログインするための目的ではなく、センサーとのデータ通信のために使いたいからだ。次に、「Would you like the serial port hardware to be enabled?」という質問には「Yes」を選択して、シリアルポートのハードウェアを有効にする。設定を終えたら、「Finish」を選択し、sudo rebootコマンドでRaspberry Piを再起動することで、変更が適用される。これで、センサーと通信するための準備が整った。さらに、Pythonでシリアル通信を扱うためのライブラリであるpyserialをインストールする必要がある。ターミナルでpip install pyserialコマンドを実行すれば、簡単にインストールが完了する。
次に、センサーとRaspberry Piがどのように情報をやり取りするかの「通信プロトコル」を理解することが重要だ。産業用位相シフトセンサーは、通常、ASCII文字またはHex(16進数)形式のコマンドフレームを使って通信する。このチュートリアルでは、Hex形式のコマンドを使用する。例えば、センサーに1回だけ距離を測定するように指示する「シングルショットコマンド」は、AA 00 00 20 00 01 00 21という8バイトのデータ列で構成される。このコマンドをセンサーに送信すると、センサーは測定を行い、その結果を「応答フレーム」として送り返してくる。典型的な応答フレームは、AA 00 00 22 [D0 D1 D2 D3] [CS]という形式をしている。先頭のAA 00 00 22は応答ヘッダーで、これは「これから距離データが送られてきますよ」という合図のようなものだ。続くD0 D1 D2 D3は、4バイトのデータで、実際の距離値がミリメートル単位の整数として格納されている。この値は「ビッグエンディアン」という形式で、数値の最も大きな桁が最初に来るように並べられている。そして最後のCSは「チェックサム」と呼ばれる1バイトのデータで、これまでのバイトの合計を256で割った余り(モジュロ256)によって計算される。このチェックサムは、データが正しく送信されたかどうかを確認するために使われる。もし計算されたチェックサムと受信したチェックサムが異なれば、データ転送中にエラーが発生したと判断できる。
これらの通信プロトコルに基づいて、Pythonでセンサーを制御し、データを読み取るプログラムを作成する。read_sensor.pyという名前のファイルを作成し、以下のコードを記述する。まず、serialモジュールとtimeモジュールをインポートする。SERIAL_PORTはRaspberry PiのプライマリUART(Universal Asynchronous Receiver-Transmitter)である/dev/serial0を指定し、BAUD_RATEは産業用モジュールで一般的な19200に設定する。calculate_checksum関数は、バイト列の合計を計算し、256で割った余りを返すことで、チェックサムを生成する。この関数は、受信したデータのチェックサムを検証する際に利用する。
read_laser_distance関数は、センサーに距離測定を指示し、その結果を読み取る主要なロジックを担う。この関数の中で、まずシングルショットコマンドcmd_single_shotを作成し、ser.write()メソッドを使ってセンサーに送信する。コマンド送信後、センサーが測定と処理を行うための短い時間(0.05秒)をtime.sleep()で待つ。その後、ser.read(9)でセンサーからの9バイトの応答を読み取る。読み取った応答データに対しては、いくつかの検証を行う。まず、データの長さが9バイトあるか、次に、応答ヘッダーが期待通りの0xAAと0x22であるかを確認する。これらのチェックに合格したら、受信したデータのチェックサムを計算し、応答の最後のバイトである受信したチェックサムと比較する。もし計算されたチェックサムと受信したチェックサムが一致しなければ、データが破損している可能性があるため、エラーとして処理する。すべての検証をパスした場合、応答データの4バイト目から7バイト目までの4バイトを抽出し、int.from_bytes()メソッドを使ってビッグエンディアン形式の整数に変換する。この値がミリメートル単位の距離なので、/ 1000.0で割ってメートル単位に変換し、結果を返す。
main関数では、まずtry...except...finallyブロックを使って、シリアルポートの接続とデータの読み取りを行う。serial.Serialクラスのインスタンスを作成し、port、baudrate、timeoutなどのパラメータを設定してシリアルポートを初期化する。初期化が成功したら、無限ループwhile True:に入り、read_laser_distance関数を呼び出して距離を継続的に測定する。測定結果が有効であれば、小数点以下3桁のメートル単位で距離を表示する。測定サイクルごとに0.2秒間待機することで、一定の間隔でサンプリングを行う。SerialExceptionが発生した場合はシリアルポートのエラーとして扱い、KeyboardInterrupt(Ctrl+Cなど)でプログラムが終了した場合は、Measurement terminated.と表示する。最後にfinallyブロックで、シリアルポートがオープン状態であれば必ずser.close()を呼び出し、リソースを適切に解放する。
プログラムを実行する上で、いくつか遭遇する可能性のあるトラブルと、その解決策についても触れておく。まず「Permission Denied」(パーミッション拒否)エラーが発生した場合、それは現在のユーザーがシリアルポートへのアクセス権限を持っていないことが原因である。この問題は、sudo usermod -a -G dialout $USERコマンドを実行して、現在のユーザーをdialoutグループに追加し、一度ログアウトしてから再度ログインし直すことで解決できる。次に「Timeout Errors」(タイムアウトエラー)が発生する場合は、物理的な配線、特にセンサーのTXDとRaspberry PiのRXD、センサーのRXDとRaspberry PiのTXDが正しくクロス接続されているかを確認する必要がある。また、センサーモジュールに3.3Vの電源が安定して供給されているかも確認するべきだ。最後に、測定値が「Erratic Values」(不安定な値)を示す場合、それは測定対象の表面特性に原因があることが多い。特に、反射率の低い黒い表面や透明な物体を測定する際には、レーザー光がうまく反射されず、正確な値が得られないことがある。このような場合は、不透明で白色のマットなターゲットボードをレーザーの光路に垂直に設置することで、安定した測定値を得ることが可能になる。
この一連の解説を通じて、システムエンジニアを目指す初心者は、単にプログラムを書くだけでなく、実際にハードウェアを配線し、設定し、通信プロトコルを理解し、低レベルなデータ通信をPythonで実装する具体的なスキルを習得できる。これは、物理世界とコンピュータシステムを連携させるIoT(モノのインターネット)や組み込みシステム開発の基礎となる重要な経験であり、将来の多様なITプロジェクトに応用できる汎用的な知識となるだろう。高精度な産業用センサーを使いこなすことで、より複雑で要求の厳しいシステム開発への道が開かれる。