National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 72 24°C PM2.5 13
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 12

超音波測距與人體感測

超音波測距原理、PIR 人體感測與事件
Interaction 25 minute(s)

Learning Objectives

  • 說明超音波測距如何由回音時間算出距離,並把 Echo 腳的 5V 安全地接到樹莓派
  • 用 gpiozero 的 DistanceSensor 讀距離,依距離分段控制警示燈與蜂鳴器
  • 說明 PIR 人體感測器偵測什麼、偵測不到什麼,以及延遲與暖機
  • 用 when_motion、when_no_motion 寫事件驅動的程式

讓作品知道「前面有東西」「有人來了」

倒車雷達會在快撞到時嗶嗶叫,走廊的燈在有人經過時自己亮起來。這兩件事用的是兩種常見又便宜的感測器:

  • 超音波測距模組(HC-SR04):發出人耳聽不到的聲音,聽回音,算出距離。
  • PIR 人體感測器(例如 HC-SR501):感應人體發出的紅外線有沒有變化,知道「有人在動」。

這一課要回答:

  1. 回音的時間怎麼變成公分?
  2. 5V 的感測器怎麼安全地接到 3.3V 的樹莓派?
  3. 「有人經過時才做事」的程式,為什麼不必一直寫迴圈去檢查?

超音波測距:聽回音算距離

HC-SR04 有四支腳:VCC(5V)、Trig、Echo、GND。量一次距離的流程:

  1. 樹莓派在 Trig 送出至少 10 μs 的高電位脈波。
  2. 模組發出 8 個 40 kHz 的超音波,同時把 Echo 拉高。
  3. 聲波碰到物體反彈回來,模組收到回音就把 Echo 拉低。
  4. Echo 維持高電位的時間,就是聲音來回一趟的時間。
距離 = 回音時間 × 聲速 ÷ 2            (除以 2:聲音走了來回兩倍的路)
聲速約 340 m/s = 0.034 cm/μs
例:回音時間 1160 μs → 1160 × 0.034 ÷ 2 ≈ 19.7 cm
規格書的簡便算法:μs ÷ 58 ≈ 公分

規格書寫的量測範圍約 2 cm~400 cm,兩次量測之間建議隔 60 ms 以上,免得上一次的回音干擾下一次。 軟的、斜的表面會讓回音變弱或彈到別處,讀值就不準。

Echo 是 5V:樹莓派的 GPIO 只能承受 3.3V,直接接 Echo 可能燒壞腳位。要用兩顆電阻分壓: 例如 Echo 串 330Ω 到 GPIO,GPIO 再經 470Ω 接地,GPIO 看到的大約是 3V。也有 3.3V 就能工作的 HC-SR04P 版本,不需要分壓。

gpiozero 的 DistanceSensor 負責送 Trig、量 Echo、換算距離:

from gpiozero import DistanceSensor
sensor = DistanceSensor(echo=24, trigger=23)   # max_distance 預設 1 公尺
sensor.distance                                # 單位是公尺,最大就是 max_distance

逐步看:讀距離

模擬的物體在 2.5 秒內從 80 cm 靠近到 15 cm。注意讀 distance 那一步,時間多走了約 60 ms:那是送出超音波、等回音的時間。

逐步看:倒車雷達

物體從 120 cm 靠近到 10 cm。程式依距離分三段:50 cm 以上不警示、20~50 cm 亮燈、20 cm 以內燈亮加蜂鳴器。 這裡把 max_distance 設成 2 公尺,否則 1 公尺以外都會讀成 100 cm。

PIR:感應「有人在動」

PIR 是 Passive Infrared(被動紅外線)的縮寫。它不發出任何東西,只接收:人體會發出紅外線,有人在感測範圍內移動時, 感測器收到的紅外線發生變化,輸出腳就變成高電位。因此:

  • 它偵測的是變化:一個人靜靜坐著不動,過一陣子就可能被當成「沒有人」。
  • 它不知道距離、也不知道是誰,只回報「有動靜」或「沒有」。

常見的 HC-SR501 模組:

項目 說明
電源 接 5V(模組的工作電壓範圍比較寬)
輸出 偵測到時輸出約 3.3V 的高電位,可以直接接 GPIO
延遲旋鈕 偵測到之後輸出維持高電位多久,可調(約數秒到數分鐘)
靈敏度旋鈕 調整偵測距離
觸發模式跳線 可重複觸發:有人一直動就一直延長;不可重複:時間到就先拉低
暖機 剛通電時要等一段時間(數十秒左右)才穩定,這段時間的讀值不要採信

gpiozero 的 MotionSensor 讀它:motion_detected 是目前有沒有偵測到,when_motion、when_no_motion 是事件。

事件驅動:登記好,等它發生

第 06 課的按鈕用過事件。寫法的重點是「登記」而不是「檢查」:

pir.when_motion = on_motion      # 有動靜時,請呼叫 on_motion(注意沒有括號)
pir.when_no_motion = on_still
pause()                          # 程式停在這裡等,事件發生時 gpiozero 會呼叫你登記的函式

和自己寫 while True 一直讀 motion_detected 比起來,事件寫法不會錯過短暫的變化,也不必決定「多久檢查一次」。 from signal import pause 的 pause() 讓主程式不要結束;如果主程式結束了,登記的事件也就沒有機會執行。

登記時寫 on_motion,不是 on_motion():加了括號會立刻執行一次,再把它的回傳值(None)登記上去。

需要「等到有人才繼續往下做」的流程時,也可以用 pir.wait_for_motion():程式會停在這一行,直到偵測到移動。

逐步看:有人經過就開燈

模擬有人在 0.8~1.8 秒、2.6~3.3 秒經過。主程式執行到 pause() 就停住了, 之後的每一步都是 gpiozero 在事件發生時呼叫你的函式:注意左上角的時間直接跳到事件發生的那一刻。

互動練習:會自己關的走廊燈

PIR 接 GPIO4、走廊燈接 GPIO17。「輸入設定」可以改有人經過的時間。依序完成任務:

  1. 直接執行起始程式:燈跟著有沒有人亮暗。
  2. 改程式:偵測到人之後燈亮 2 秒才熄(就算人已經走了);之後再有人經過,又亮 2 秒。
  3. 回答一個問題。

互動練習:自己做倒車雷達

超音波模組的 Trig 接 GPIO23、Echo(經分壓)接 GPIO24;警示燈接 GPIO17、有源蜂鳴器接 GPIO27。 模擬期間物體從 150 cm 靠近到 5 cm(可以在「輸入設定」改)。依序完成任務:

  1. 直接執行起始程式,看輸出的距離。
  2. 距離小於 30 cm 時亮警示燈,否則關掉。
  3. 距離小於 15 cm 時蜂鳴器也要響,15 cm 以上不響。
  4. 回答一個問題。

小測驗:超音波

1.

下面的程式會印出什麼?(聲速 0.034 cm/μs)

echo_us = 2000
cm = echo_us * 0.034 / 2
print(round(cm))
2.

DistanceSensor(echo=24, trigger=23) 沒有設定 max_distance,物體在 1.5 公尺外,distance 大約會是多少?

3.

為什麼算距離時要除以 2?

第 1 次作答

小測驗:PIR 與事件

1.

寫成 pir.when_motion = on_motion()(多了括號),會發生什麼事?

2.

下面的程式模擬三次事件,會印出什麼?

count = 0

def on_motion():
    global count
    count = count + 1

handler = on_motion
for _ in range(3):
    handler()
print(count)
3.

HC-SR501 剛接上電源的前幾十秒,讀值忽有忽無,最合理的處理是?

第 1 次作答

重點整理

  • 超音波測距:Trig 送 10 μs 脈波,Echo 高電位的時間是聲音來回的時間;距離=時間 × 聲速 ÷ 2(μs ÷ 58 ≈ cm)。
  • HC-SR04 的 Echo 是 5V,要分壓(例如 330Ω/470Ω)才能接樹莓派;或改用 3.3V 版本。
  • DistanceSensor(echo=, trigger=, max_distance=):distance 單位是公尺,超過 max_distance 會停在最大值;讀一次存進變數再判斷。
  • PIR 偵測的是紅外線的變化(有人在動),人不動就可能偵測不到;HC-SR501 有延遲與靈敏度旋鈕,通電後要暖機。
  • MotionSensor 的 when_motion、when_no_motion 登記事件(不加括號),再用 pause() 讓程式等事件發生。

下一課換成攝影機:讓樹莓派「看見」,拍照並做簡單的影像處理。

這一課完成了!
Next lesson:攝影機與影像
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。