センサー・アクチュエータ

測距センサー(ToF / 超音波)

距離を測るセンサー。

概要

測距センサーは、対象物までの距離を非接触で測定するセンサーです。光・超音波・電磁波などを照射し、その反射が戻ってくるまでの時間や位相差から距離を計算します。

組み込みシステムでよく使われる測距センサーは大きく3種類あります。

  1. ToFセンサー(Time of Flight): レーザー光(赤外線)のパルスを照射し、往復時間から距離を計算。数mmの高精度、数cm〜数mのレンジ。
  2. 超音波センサー: 超音波パルスを照射し、反射(エコー)の往復時間から距離を計算。広いビーム角、数cm〜数mのレンジ、安価。
  3. 赤外線センサー(三角測距): 赤外線LEDを斜め照射し、受光素子上の反射スポット位置から三角法で距離を計算(例:シャープGP2Y0A21)。

ロボット、ドローン、自動車(パーキングセンサー)、スマートフォン(顔認識オートフォーカス)、産業用安全センサーなど幅広い用途で使われています。

歴史・背景

超音波測距の原理はソナー(SONAR)技術に由来します。第一次世界大戦中の1917年に潜水艦探知用として水中音響探知機(ASDIC/SONAR)が開発され、空気中の超音波距離計として民間転用されたのは1950〜60年代です。ポラロイド社が1978年に超音波オートフォーカスカメラ向けセンサーを開発し、後にロボット向け測距センサーの標準となりました。

光を使った測距では、レーザーレーダー(LiDAR:Light Detection and Ranging)が1960年代のレーザー発明直後から研究されました。1970年代には月面測距(月からの反射レーザー光の往復時間を計測)に使われ、精度を証明しました。

組み込み向け小型ToFセンサーの普及は2010年代からです。STMicroelectronicsのVL53L0X(2015年)はスマートフォンのカメラオートフォーカス向けに量産され、$1〜2という低価格と小型サイズ(2.4×4.4mm)がホビーロボット・IoT分野での普及を加速しました。2018〜2020年代には後継のVL53L1X・VL53L3CX・VL53L5CXが登場し、より長距離・マルチゾーン検出が可能になっています。

技術仕様

測距センサーの方式比較

方式原理測距範囲精度ビーム角価格代表品
ToF(パルス)光パルス往復時間2cm〜4m±1mm25°以下VL53L1X, TMF882x
ToF(CW変調)光の位相差0.1〜5m±1cm20〜40°中〜高OPT3101
超音波音波往復時間2cm〜5m±3mm15〜60°安価HC-SR04, US-100
赤外線三角測距三角法+PSD4〜80cm±5%狭い安価GP2Y0A21(Sharp)
LiDAR高速ToFスキャン0.1〜100m±2cm360°(回転型)高価RPLiDAR, Hokuyo
レーダー(mmW)電磁波反射0.1〜10m±cm広い中〜高IWR1843(TI)

ToFセンサー(VL53L1X)の主要スペック

パラメータ
測距範囲4〜400cm(条件による)
精度±1mm(短距離)〜±3%(長距離)
FOV(視野角)27°(通常) / 15°(長距離モード)
最大サンプリングレート50Hz(最大)
インターフェースI2C(最大400kHz)
電源電圧2.6〜3.5V
消費電流19mA(計測時)/ 5μA(スタンバイ)
動作温度-20〜70°C
パッケージ2.4×4.4×1.0mm(28ピンLGA)

超音波センサー(HC-SR04)の主要スペック

パラメータ
測距範囲2〜400cm
精度±3mm
ビーム角15°以下
測定周期60ms以上推奨
電源5V
トリガー信号10μs以上のHIGHパルス
エコー信号測距時間に比例するHIGHパルス幅

動作原理

ToFセンサーの原理

ToF(Time of Flight)センサーは光の往復時間を測定します。赤外線レーザーダイオードがパルス(数ns幅)を照射し、対象物で反射した光を光子検出器(SPADアレイ等)で受信します。

距離計算:
d = (c × t_flight) / 2

c: 光速(3×10⁸ m/s)
t_flight: 光の往復時間
2: 往復なので1/2

例: t_flight = 6.67ns の場合
d = (3×10⁸ × 6.67×10⁻⁹) / 2 = 1.0 m

1mm精度には:
Δt = 2×0.001 / (3×10⁸) ≈ 6.67ps の時間分解能が必要
→ 実際はヒストグラム積算法や変調波位相差で解決

**変調CW ToF(AMCW: Amplitude Modulated Continuous Wave)**は高周波変調した連続光の送受信位相差から距離を求めます。スマートフォンの顔認識(Face ID等)に採用されています。

位相差法:
変調周波数 f = 10MHz の場合
波長 λ = c/f = 30m(位相距離の最大)
位相差 φ で距離:
d = φ / (4π) × λ = φ × 30 / (4π) [m]

超音波センサーの原理

超音波センサーは音波(超音波:20kHz以上)の往復時間を測定します。圧電素子が40kHz程度の超音波パルスを照射し、反射波(エコー)を同じか別の圧電素子で受信します。

距離計算:
d = (v_sound × t_echo) / 2

v_sound: 音速(20°C空気中 ≈ 343m/s)
t_echo: エコーの往復時間

例: t_echo = 5.83ms の場合
d = (343 × 0.00583) / 2 ≈ 1.0 m

温度補正:
v_sound(T) = 331.5 + 0.6 × T [m/s]
(T: 気温 [°C])
15°C: 340m/s, 30°C: 349m/s

HC-SR04 タイミング図

  Trigger  ─┐10μs├─
  
  Echo      ─────┤ 距離に比例 ├─────
  
  距離 d = (Echo HIGH期間 [μs]) / 58 [cm]
         = (Echo HIGH期間 [μs]) × 0.0172 [cm/μs]
         (音速340m/s = 0.034cm/μs, 往復なので1/2 = 0.017cm/μs)

用途・ユースケース

ロボット障害物検知・自律走行

移動ロボット・AGVの前面・側面に超音波またはToFセンサーを複数配置し、障害物を検知して衝突回避します。360°スキャンが必要な場合はLiDARを使います。

ロボット衝突回避の例:
前方ToF → 距離 < 30cm → 停止または方向転換
超音波×3(左・前・右) → 多方向障害物検知

ドローンの高度保持(地面距離センサー)

ドローンの機体下面にToFまたは超音波センサーを搭載し、地面からの高度を直接計測します。気圧センサーと組み合わせることで低空飛行時の定高制御精度が向上します。

スマートフォン・カメラのオートフォーカス

スマートフォンのカメラモジュールには小型ToFセンサー(VL53系)が搭載され、被写体との距離を計測して高速・正確なオートフォーカスを実現します。iPhone Proシリーズの「LiDARスキャナー」は同様の原理の高精度版です。

液面計・タンク水位測定

タンク上部から超音波センサーで液面までの距離を測り、水位・液量を算出します。接液部がないため、腐食性液体・食品タンクにも適用できます。

自動車パーキングセンサー・バックカメラ補助

バンパー内蔵の超音波センサー(複数個)で後方・側方の障害物距離を検知し、警告音の間隔で距離を通知します。

人検知・入退室センサー

ToFセンサーで通路を横断する人を検知し、入退室カウント・混雑度推定に使います。プライバシーを侵害しない(カメラでなく点群データのみ)点が利点です。マルチゾーンToFセンサー(VL53L5CX等)では複数人の同時検知も可能です。

実装・開発のポイント

HC-SR04 超音波センサーの実装(C言語)

#include "stm32f4xx_hal.h"

#define TRIG_PIN   GPIO_PIN_5
#define ECHO_PIN   GPIO_PIN_6
#define SOUND_SPEED_CM_US  0.01716f  // 343m/s / 2 = 0.01716cm/μs

// タイマーでマイクロ秒計測(TIM2をμsカウンタとして設定済み)
extern TIM_HandleTypeDef htim2;

uint32_t get_us(void) {
    return __HAL_TIM_GET_COUNTER(&htim2);
}

float hcsr04_measure_cm(void) {
    // トリガーパルス送信(10μs HIGH)
    HAL_GPIO_WritePin(GPIOA, TRIG_PIN, GPIO_PIN_SET);
    uint32_t t = get_us();
    while (get_us() - t < 10);
    HAL_GPIO_WritePin(GPIOA, TRIG_PIN, GPIO_PIN_RESET);
    
    // エコー立ち上がり待ち(タイムアウト: 500μs)
    t = get_us();
    while (HAL_GPIO_ReadPin(GPIOA, ECHO_PIN) == GPIO_PIN_RESET) {
        if (get_us() - t > 500) return -1.0f;  // タイムアウト(近すぎ)
    }
    
    // エコーHIGH期間を計測(タイムアウト: 25000μs ≈ 4m)
    uint32_t echo_start = get_us();
    while (HAL_GPIO_ReadPin(GPIOA, ECHO_PIN) == GPIO_PIN_SET) {
        if (get_us() - echo_start > 25000) return -2.0f;  // タイムアウト(遠すぎ)
    }
    uint32_t echo_duration = get_us() - echo_start;
    
    return echo_duration * SOUND_SPEED_CM_US;
}

VL53L1X ToFセンサーのI2C読み取り(Arduino/Python)

# MicroPython / Raspberry Pi Pico + VL53L1X
from machine import I2C, Pin
import time

class VL53L1X:
    """VL53L1X ToFセンサードライバ(簡略版)"""
    ADDR = 0x29
    
    def __init__(self, i2c):
        self.i2c = i2c
        self._init_sensor()
    
    def _write16(self, reg, val):
        self.i2c.writeto_mem(self.ADDR, reg, bytes([(val>>8)&0xFF, val&0xFF]),
                             addrsize=16)
    
    def _read16(self, reg):
        data = self.i2c.readfrom_mem(self.ADDR, reg, 2, addrsize=16)
        return (data[0] << 8) | data[1]
    
    def _init_sensor(self):
        """デバイス初期化(簡略)"""
        # ソフトウェアリセット
        self._write16(0x0000, 0x00)
        time.sleep_ms(100)
        # タイミングバジェット: 50ms(中精度モード)
        self._write16(0x0022, 0x0032)  # 50ms
        # 長距離モード設定
        self._write16(0x001E, 0x01)
        # 計測開始
        self._write16(0x0087, 0x40)
    
    def read_distance_mm(self):
        """距離を読み取る [mm]"""
        # データ準備完了待ち
        timeout = 100
        while timeout > 0:
            status = self._read16(0x0089) & 0x07
            if status in (0, 3, 4):  # 有効データ
                break
            time.sleep_ms(1)
            timeout -= 1
        
        dist = self._read16(0x0096)  # RESULT_FINAL_CROSSTALK_CORRECTED_RANGE_MM
        
        # データクリア
        self._write16(0x0086, 0x01)
        
        return dist

# 使用例
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=400000)
sensor = VL53L1X(i2c)

while True:
    dist = sensor.read_distance_mm()
    print(f"距離: {dist} mm")
    time.sleep_ms(100)

複数センサーの誤検知対策

import statistics

class RobustDistanceSensor:
    """外れ値除去付き測距"""
    
    def __init__(self, sensor, n_samples=5):
        self.sensor = sensor
        self.n = n_samples
    
    def read_stable_mm(self):
        """n回計測してメディアンを返す"""
        readings = []
        for _ in range(self.n):
            d = self.sensor.read_distance_mm()
            if 0 < d < 4000:  # 有効範囲チェック
                readings.append(d)
        
        if not readings:
            return None
        
        return statistics.median(readings)

検出不能領域(デッドゾーン)への対応

超音波センサーはトリガーパルス直後(数cmの範囲)が検出不能なデッドゾーンになります。HC-SR04では約2cm以内が検出不能です。ToFセンサーも最短距離(通常4〜10cm)以下では不正確になります。近距離が重要な用途では、センサー選定時に最小計測距離を確認します。

他技術との比較

用途別センサー選定ガイド

用途推奨センサー理由
ロボット一般障害物検知超音波HC-SR04安価・十分な精度
ドローン着陸高度ToF VL53L1X軽量・低消費電力・mm精度
自律走行マッピングLiDAR360°スキャン可能
スマートフォンAFToF(SPAD型)超小型・低遅延
工場安全センサー超音波(産業用)環境耐性・長距離
液面計測超音波(非接触)接液なし・耐腐食
人検知(プライバシー保護)マルチゾーンToF画像なし・点群のみ

ToFセンサー vs 超音波センサーの詳細比較

比較項目ToFセンサー超音波センサー
精度±1mm〜数mm±3mm〜数cm
更新レート最大50Hz最大17Hz(60ms間隔必要)
ビーム角(FOV)狭い(15〜27°)広い(15〜60°)
対象物依存性透明・鏡面に弱い軟質吸音材に弱い
光干渉外光・他ToFセンサーに影響影響なし
複数台同時使用クロストーク対策必要タイミング管理が必要
消費電力中(数mA〜数十mA)低(数mA)
インターフェースI2C(デジタル)GPIO(TRIG/ECHO)
パッケージサイズ非常に小型(2〜10mm角)大きい(数cm)
価格中(数百〜数千円)安価(数十〜数百円)
水濡れ対応不可(通常)防水型あり

超音波センサー vs 赤外線三角測距(シャープGP2Y0Aシリーズ)

比較項目超音波(HC-SR04)赤外線三角測距(GP2Y0A21)
測距範囲2〜400cm10〜80cm
精度±3mm±5%(非線形)
出力デジタル(TRIG/ECHO)アナログ電圧(要ADC)
暗所動作問題なし問題なし
外光干渉なし強い外光(日光)に弱い
対象物表面吸音材に弱い黒色(吸収)に弱い
価格数十〜百円数百〜千円

関連用語

参考リンク