2025年8月12日火曜日

超音波センサ HC-SR04 を使ったリアルタイム距離測定と OLED 表示

  HC‑SR04 超音波距離センサを Raspberry Pi Pico から制御し、OLED(SSD1306 128×64)にリアルタイム表示するデモを MicroPython で作成します。センサが発した超音波が物体で反射し戻るまでの往復時間を計測し、Pico 内蔵温度センサで取得した気温を用いて音速を補正することで、測定精度を高めます。

配線(GPIO ピンアサイン)

機能デバイスPico GPIO
SDAOLED (I²C id 0)GP16
SCLOLED (I²C id 0)GP17
TRIGHC‑SR04GP14
ECHOHC‑SR04GP15

この構成で、約 0.3 秒ごとに “気温・距離” を更新しながら OLED に表示する MicroPython サンプルを実装します。

ライブラリのインストール(Thonny)

  1. Pico W を PC に接続し、Thonny を開きます。

  2. メニュー [ツール] → [パッケージを管理..] をクリック。

OLED 用ライブラリ

  • 検索窓に ssd1306 と入力 → micropython-ssd1306 を選び Install
    (詳しい手順や日本語解説は、前回の記事を参考にしてください)

ソースコード

from machine import Pin, ADC, I2C, time_pulse_us
import utime
import ssd1306

# ── GPIO 設定 ──────────────────────────────────────────────
TRIG = 14
ECHO = 15
SDA  = 16
SCL  = 17

trigger = Pin(TRIG, Pin.OUT)
echo    = Pin(ECHO, Pin.IN)

# ── OLED 初期化 ────────────────────────────────────────────
i2c  = I2C(0, sda=Pin(SDA), scl=Pin(SCL), freq=400_000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)

oled.fill(0)
oled.text("RP2040 + HC-SR04", 0, 0)
oled.text("TEMP:      C",     0, 24)
oled.text("L(cm):",          0, 40)
oled.show()

# ── 内部温度センサ ────────────────────────────────────────
adc   = ADC(4)
VREF  = 3.3
COEFF = VREF / 65535

def read_temperature():
    """内部温度センサから気温 (°C) を返す"""
    v = adc.read_u16() * COEFF
    return round(27 - (v - 0.706) / 0.001721, 1)

# ── HC‑SR04 距離計測 ─────────────────────────────────────
def read_distance(temp):
    """
    距離 (cm) を返す。タイムアウトなら None。
    temp: 気温 (°C) — 音速計算用
    """
    trigger.low()
    utime.sleep_us(2)
    trigger.high()
    utime.sleep_us(15)      # ≥10 µs 必要
    trigger.low()

    # 30 ms タイムアウト (≈5 m)
    t = time_pulse_us(echo, 1, 30_000)
    if t < 0:
        return None

    vs = 331.5 + 0.6 * temp       # 音速 (m/s)
    return round(vs * t / 20000, 1)  # 往復 → 片道換算

# ── OLED 表示ユーティリティ ───────────────────────────────
def show_value(x, y, width, text):
    oled.fill_rect(x, y, width, 8, 0)
    oled.text(text, x, y)

# ── メインループ ─────────────────────────────────────────
while True:
    temp = read_temperature()
    dist = read_distance(temp)

    show_value(48, 24, 40, "{:>4}".format(temp))
    if dist is None or dist > 400:        # HC‑SR04 公称最大 4 m
        show_value(48, 40, 56, "----")
    else:
        show_value(48, 40, 56, "{:>5}".format(dist))

    oled.show()
    utime.sleep(0.3)   # 更新周期(好みで調整)




処理の流れ

  • 🛠 GPIO とデバイス初期化

    • TRIG・ECHO ピンを Pin.OUT / Pin.IN で設定

    • I²C (id 0) を開始し、SSD1306 OLED (128 × 64) を生成

  • 🖥 OLED 画面クリア & ラベル表示

    • oled.fill(0) で全消去 → タイトル・TEMP・L(cm) を描画 → oled.show()

  • ♨️ 内部温度センサ読み取り (read_temperature)

    • ADC4 から電圧を取得

    • データシート公式で °C に換算し、小数 1 桁で返却

  • 📤 センサ TRIG パルス生成 (read_distance)

    • TRIG ↓→15 µs ↑→↓ で発信開始

  • ⏱ ECHO パルス幅取得

    • time_pulse_us() で High の長さを最長 30 ms 測定(≈5 m)

    • タイムアウト時は None を返す

  • 🧮 音速補正 & 距離計算

    • 音速 vs = 331.5 + 0.6 × temp (m/s)

    • 距離 L = vs × t / 20000 → cm 丸め

  • 🖋 OLED 数値更新 (show_value)

    • 古い数値領域を fill_rect で黒塗り

    • 温度と距離を右寄せ描画し oled.show()

  • 🔄 ループ

    • 0.3 秒スリープ後、再び温度 → 距離 → 表示を継続

0 件のコメント:

コメントを投稿

Google Spread Sheetの利用

  以前に ESP32 で作っていたものを、Raspberry Pi Pico W + MicroPythonで再現してみました。 1.Googleスプレッドシートの設定 1.Google Drive → 右クリック → Google スプレッドシート 2.作成して共有をクリック