HC-SR04超音波センサーを使用して距離を測定します。

Timer関数で作動させた。
TRIGピンを使って超音波を送信しECHOピンで反射音を受信し、かかった時間から距離を計算します。
2秒ごとにタイマーで自動測定します。
from machine import Timer, Pin # タイマーとGPIOピン制御のためのモジュールをインポート
import time # 時間制御のためのモジュールをインポート
# 使用するGPIOピン番号を定義
TRIG_PIN = 17 # 超音波センサーのTRIGピンをGPIO17に接続
ECHO_PIN = 16 # 超音波センサーのECHOピンをGPIO16に接続
# TRIGピンを出力に、ECHOピンを入力に設定
TRIG = Pin(TRIG_PIN, Pin.OUT)
ECHO = Pin(ECHO_PIN, Pin.IN)
def distance():
"""
超音波センサー(HC-SR04)を使って距離を測定する関数。
戻り値:
測定に成功した場合: 距離(mm 単位)
測定失敗(タイムアウト)の場合: -1 を返す
"""
# TRIGピンに10マイクロ秒のパルスを送って測定を開始
TRIG.low() # 念のためLOWにしてからスタート
time.sleep_us(2)
TRIG.high() # 10マイクロ秒だけHIGHにする
time.sleep_us(10)
TRIG.low()
# ECHOピンがHIGHになるのを待つ(超音波の送信開始)
timeout_start = time.ticks_us() # タイムアウト用の開始時刻を記録
while not ECHO.value(): # LOWのままの場合、待つ
if time.ticks_diff(time.ticks_us(), timeout_start) > 30000:
return -1 # 30ms以上応答がなければ失敗
# ECHOがHIGHになった瞬間の時間を記録(超音波が戻ってくるのを測定)
time1 = time.ticks_us()
# ECHOピンが再びLOWになるのを待つ(超音波が戻ってきた)
while ECHO.value(): # HIGHが続いている間は待つ
if time.ticks_diff(time.ticks_us(), time1) > 30000:
return -1 # パルスが長すぎる=失敗
# LOWになった瞬間の時間を記録
time2 = time.ticks_us()
# パルスの継続時間を計算(エコーの往復時間)
duration = time.ticks_diff(time2, time1)
# 距離をミリメートル単位で計算
# 音速 343,000 mm/s(343 m/s)を使用
# 往復なので2で割る
distance_mm = duration * 343 / 2 / 1000
return distance_mm
def measure_distance(timer):
"""
タイマー割り込みで定期的に呼び出される関数。
現在の距離を測定して表示する。
"""
dis = distance() # 距離を測定
if dis != -1:
print("Distance: %.0f mm" % dis) # 測定成功時に距離を表示
else:
print("Measurement failed") # 測定失敗時のメッセージ
# タイマーを初期化して、2秒ごとにmeasure_distance()を呼び出す
timer = Timer()
timer.init(period=2000, mode=Timer.PERIODIC, callback=measure_distance)
sleep関数で作動させた。
sleep関数で作動させた。
import machine # ハードウェア制御用のモジュール
import time # 時間制御用のモジュール
# 超音波センサー用のGPIOピンを定義
TRIG = machine.Pin(17, machine.Pin.OUT) # TRIGピン(出力):超音波の発信を制御
ECHO = machine.Pin(16, machine.Pin.IN) # ECHOピン(入力):反射波の受信を検出
def distance():
"""
HC-SR04超音波センサーを使って距離を測定する関数。
戻り値:
距離(mm単位のfloat値)、または
タイムアウト時は -1 を返す。
"""
# センサーをリセットするためにTRIGをLOWにする(少し待つ)
TRIG.low()
time.sleep_us(2)
# TRIGピンを10マイクロ秒だけHIGHにして、超音波パルスを送信
TRIG.high()
time.sleep_us(10)
TRIG.low()
# タイムアウト測定の開始時間を記録
timeout_start = time.ticks_us()
# ECHOピンがHIGHになるのを待つ(反射波の受信開始)
while not ECHO.value():
# 30ms以上HIGHにならなければ失敗と判断
if time.ticks_diff(time.ticks_us(), timeout_start) > 30000:
return -1 # タイムアウト(反射波が来なかった)
# ECHOがHIGHになった時刻を記録(パルスの開始)
time1 = time.ticks_us()
# ECHOが再びLOWになるのを待つ(反射波の終了)
while ECHO.value():
# 30ms以上HIGHが続く場合も失敗と判断
if time.ticks_diff(time.ticks_us(), time1) > 30000:
return -1 # タイムアウト(パルスが長すぎる)
# ECHOがLOWになった時刻を記録(パルスの終了)
time2 = time.ticks_us()
# パルスの継続時間を計算(単位はマイクロ秒)
duration = time.ticks_diff(time2, time1)
# 距離をミリメートル単位に変換
# 音速:340 m/s = 340,000 mm/s = 0.34 mm/µs
# 往復なので2で割る
return duration * 340 / 2 / 1000 # 単位:mm
# メインループ(1秒ごとに距離を測定)
while True:
dis = distance() # 距離を取得
if dis != -1:
print("Distance: %.0f mm" % dis) # 測定成功時に距離を出力(整数で表示)
else:
print("Measurement failed (timeout)") # 測定失敗時のメッセージ
time.sleep_ms(1000) # 1秒待機してから次の測定
短いプログラムにしてみた
from machine import Pin, time_pulse_us
import time
t, e = Pin(17, Pin.OUT), Pin(16, Pin.IN)
while True:
t.off(); time.sleep_us(2)
t.on(); time.sleep_us(10); t.off()
d = time_pulse_us(e, 1, 30000)
print(f"{d * 0.1715:.0f} mm" if d > 0 else "タイムアウト")
time.sleep(1)
from machine import Pin, time_pulse_us
import time
# HC-SR04のピン設定
trigger = Pin(3, Pin.OUT)
echo = Pin(2, Pin.IN)
# ブザーピン(パッシブ or アクティブブザー)
buzzer = Pin(15, Pin.OUT)
def get_distance():
trigger.low()
time.sleep_us(2)
trigger.high()
time.sleep_us(10)
trigger.low()
duration = time_pulse_us(echo, 1, 30000) # タイムアウト30ms
distance = duration * 0.0343 / 2 # 音速で距離換算(cm)
return distance
while True:
try:
distance = get_distance()
print("Distance: {:.1f} cm".format(distance))
if distance < 100: # 100cm以内に近づいたとき
interval = max(0.05, distance / 200) # 距離に応じて間隔短縮(近いほど速い)
buzzer.high()
time.sleep(0.05) # 短く鳴らす
buzzer.low()
time.sleep(interval)
else:
time.sleep(0.2) # 対象が遠いときは鳴らさない
except Exception as e:
print("Error:", e)
time.sleep(1)
参考にさせていただいたサイトです。

【Raspberry Pi Pico】ロボット制御入門③~I2C通信と障害物回避~【Python】
前回はライブラリの作成について学びました。 今回はセンサー入力を使って自動制御の一旦を体験して
コメント