--- tags: Raspberry Pi --- 建立时间:20240920 更新时间:20240920 [成果影片](https://youtu.be/mKbwCONllsU) # Raspberry Pi 4 连接 HC-SR04 超音波測距/ 避障模組超聲波傳感器 ## 图片 1.HC-SR04 ![image](https://hackmd.io/_uploads/SyI0W8c60.png) 2.Raspberry Pi 4 ![image](https://hackmd.io/_uploads/H188fU5p0.png) 3.Raspberry Pi 4 GPIO ![image](https://hackmd.io/_uploads/rJglGIcT0.png) ### 硬体接线 1.总图 ![3483cc41bf22edf7e5250c46adfb047](https://hackmd.io/_uploads/SJaGmUcaA.jpg) 2.Raspberry Pi 4 ![533bf276459973d1831e2a972ebd55c](https://hackmd.io/_uploads/r1lVm896R.jpg) 3.面包版 ![12c9f2a9ab99f1361a8be314a61c233](https://hackmd.io/_uploads/HkRVQUcpC.jpg) 4.HC-SR04 ![b3728c89e5fd88a1cec1c71e448c399](https://hackmd.io/_uploads/rkm87856C.jpg) #### 硬体接线 更新版:202409201104 1.总图 ![73b84d307093a7a5ed8d7bf338d91fc](https://hackmd.io/_uploads/SJcFIw5TC.jpg) 2.Raspberry Pi 4 ![1b5f77db35d6caf2272affa6f3ee01f](https://hackmd.io/_uploads/r1QcLvc6C.jpg) 3.面包版 ![7a6db5cb37694b595c4e606787d13dc](https://hackmd.io/_uploads/Syo9LD5pR.jpg) 4.HC-SR04 ![51d126a7e8be9a211307a24c67fa9be](https://hackmd.io/_uploads/Sy-sLvcTC.jpg) ### Raspberry Pi 4 资料结构 ![image](https://hackmd.io/_uploads/B1wBUI960.png) ## 理论 ### 1.raspberry pi 4 可以直接连 Hc-sr04 吗 Raspberry Pi 4 可以直接连接 HC-SR04 超声波传感器,但需要注意以下几点: 1. **电压问题**:HC-SR04 的工作电压为 5V,而 Raspberry Pi 的 GPIO 引脚使用的是 3.3V 电平。HC-SR04 的 Echo 引脚输出的是 5V 的信号,直接连接到 Raspberry Pi 的 GPIO 引脚可能会损坏它。你需要使用一个电压分压器(如两个电阻)或逻辑电平转换器,将 5V 的信号降到 3.3V。 2. **接线说明**: - VCC: 连接到 Raspberry Pi 的 5V 引脚(比如 Pin 2 或 Pin 4)。 - GND: 连接到 Raspberry Pi 的 GND 引脚(比如 Pin 6)。 - Trig: 连接到 Raspberry Pi 的 GPIO 引脚,比如 GPIO 23(Pin 16)。 - Echo: 通过电压分压器或逻辑电平转换器连接到 Raspberry Pi 的 GPIO 引脚,比如 GPIO 24(Pin 18)。 3. **电压分压器**: - 可以使用两个电阻(比如 1kΩ 和 2kΩ)来构建一个简单的电压分压器。将 Echo 引脚输出的 5V 信号通过电压分压器降到 3.3V,再连接到 Raspberry Pi 的 GPIO。 4. **软件控制**: - 你可以使用 Python 编写代码来控制 HC-SR04。典型的步骤是通过 Raspberry Pi 的 GPIO 引脚发送一个 10μs 的脉冲信号给 Trig 引脚,然后测量 Echo 引脚返回的高电平持续时间,以此来计算距离。 通过这些步骤,你就可以安全地将 HC-SR04 连接到 Raspberry Pi 4 上并进行测距实验。 ### 2.raspberry pi 4 运行读取 HC-SR04 的 Python 程式码 以下是一个用于 Raspberry Pi 4 的 Python 程序,能够读取 HC-SR04 超声波传感器的数据,并计算距离: ```python import RPi.GPIO as GPIO import time # 设置GPIO模式 GPIO.setmode(GPIO.BCM) # 定义引脚 TRIG = 23 # Trig 引脚连接到 GPIO 23 ECHO = 24 # Echo 引脚连接到 GPIO 24 # 设置引脚方向(IN / OUT) GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) def distance(): # 发送高电平信号到 Trig 引脚 GPIO.output(TRIG, True) # 持续 10 微秒 time.sleep(0.00001) GPIO.output(TRIG, False) # 记录发射时间 while GPIO.input(ECHO) == 0: start_time = time.time() # 记录接收时间 while GPIO.input(ECHO) == 1: stop_time = time.time() # 计算时间差 time_elapsed = stop_time - start_time # 声速为34300 cm/s,计算距离 distance = (time_elapsed * 34300) / 2 return distance try: while True: dist = distance() print(f"Measured Distance = {dist:.2f} cm") time.sleep(1) # 清理GPIO设置 except KeyboardInterrupt: print("Measurement stopped by User") GPIO.cleanup() ``` #### 程序解释: 1. **设置 GPIO 模式**: - `GPIO.setmode(GPIO.BCM)`:使用 BCM 引脚编号模式。 - `TRIG` 和 `ECHO`:分别定义为 Trig 和 Echo 引脚连接的 GPIO 编号。 2. **发送超声波脉冲**: - `GPIO.output(TRIG, True)`:发送一个 10 微秒的高电平脉冲。 - `GPIO.output(TRIG, False)`:立即将脉冲设置为低电平。 3. **接收回波信号并计算距离**: - 程序通过检测 Echo 引脚的高低电平变化来记录信号的发射和接收时间。 - 距离的计算公式为 `距离 = (时间差 × 声速) / 2`,声速约为 34300 cm/s。 4. **循环读取和显示距离**: - 程序以每秒一次的频率读取并打印距离值。 5. **清理 GPIO**: - 按 `Ctrl+C` 停止程序运行时,程序会调用 `GPIO.cleanup()` 来清理 GPIO 引脚的设置。 #### 运行代码: 将上述代码保存为 `hc_sr04.py`,然后在 Raspberry Pi 终端中运行: ```bash python3 hc_sr04.py ``` 程序将持续读取距离,并在终端中显示。 ### 3.如何用兩個電阻 做分壓電路 將5V降為3.3V 要用兩個電阻做分壓電路將5V降為3.3V,可以使用以下公式來計算電阻的值: #### 分壓公式 \[ V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2} \] 其中: - \( V_{out} \) 是期望的輸出電壓(3.3V) - \( V_{in} \) 是輸入電壓(5V) - \( R_1 \) 是連接到電源的電阻 - \( R_2 \) 是接地的電阻 ![image](https://hackmd.io/_uploads/S1SlsL9TR.png) #### 計算步驟 1. **設定參數:** - \( V_{out} = 3.3V \) - \( V_{in} = 5V \) 2. **重排公式:** 我們可以重排公式來求出 \( R_2 / (R_1 + R_2) \): \[ \frac{R_2}{R_1 + R_2} = \frac{V_{out}}{V_{in}} = \frac{3.3}{5} = 0.66 \] 3. **設置比例:** 設定 \( R_1 \) 和 \( R_2 \) 的比例: \[ R_2 = 0.66(R_1 + R_2) \] 進一步變形得: \[ R_2 - 0.66R_2 = 0.66R_1 \] \[ 0.34R_2 = 0.66R_1 \] \[ \frac{R_1}{R_2} = \frac{0.34}{0.66} \approx 0.515 \] 4. **選擇電阻值:** 假設選擇 \( R_2 = 1kΩ \),那麼: \[ R_1 = 0.515 \times 1kΩ \approx 515Ω \] 可以選擇標準電阻值 \( R_1 = 510Ω \)(常見標準值),然後重新計算 \( R_2 \): \[ \frac{R_2}{510Ω + R_2} = \frac{3.3}{5} \] 這會給出一個非常接近的值。 ![image](https://hackmd.io/_uploads/HJkzjLq60.png) #### 結論 最終,你可以使用: - \( R_1 = 510Ω \) - \( R_2 = 1kΩ \) #### 連接方式 1. 將 \( R_1 \) 連接在5V電源和 \( R_2 \) 的上端。 2. 將 \( R_2 \) 的另一端接地。 3. 輸出電壓 \( V_{out} \) 將在 \( R_1 \) 和 \( R_2 \) 連接的節點上取。 這樣就可以將5V降至大約3.3V。確保測量輸出電壓來驗證結果是否符合預期! ![image](https://hackmd.io/_uploads/r1z7sUcTC.png) ## 遇到问题 ### 1.SyntaxError: Non-ASCII character ``` pi@raspberrypi:~/Python $ python HC-SR04.py File "HC-SR04.py", line 4 SyntaxError: Non-ASCII character '\xe8' in file HC-SR04.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details ``` 這個錯誤是因為你的 Python 文件中包含了非 ASCII 字符(如中文字符或特殊符號),但沒有指定文件的編碼格式。為了解決這個問題,你可以在 Python 文件的開頭添加一行來指定編碼。 在 `HC-SR04.py` 的第一行添加以下內容: ```python # -*- coding: utf-8 -*- ``` 這樣 Python 就能正確地處理文件中的非 ASCII 字符了。完整的文件開頭應該看起來像這樣: ```python # -*- coding: utf-8 -*- # 其他代碼... ``` 這樣做後,再次運行你的程式應該就不會出現這個錯誤了。 ### 2.SyntaxError: invalid syntax ``` pi@raspberrypi:~/Python $ python HC-SR04.py File "HC-SR04.py", line 43 print(f"Measured Distance = {dist:.2f} cm") ^ SyntaxError: invalid syntax ``` 這個錯誤通常是因為你使用的 Python 版本不支持 f-string。f-string 是從 Python 3.6 開始引入的,如果你的版本低於這個,會出現 `SyntaxError`。 你可以通過以下命令檢查 Python 的版本: ```bash python --version ``` 如果你使用的是 Python 3.6 或更高版本,f-string 應該是可以正常工作的。如果不是,你可以將該行改寫為傳統的格式化方式,例如: ```python print("Measured Distance = {:.2f} cm".format(dist)) ``` 這樣就可以兼容較舊的版本了。希望這樣能幫到你!如果還有其他問題,隨時告訴我。 ### 3.ImportError: No module named RPi.GPIO ``` pi@raspberrypi:~/Python $ python HC-SR04.py Traceback (most recent call last): File "HC-SR04.py", line 16, in <module> import RPi.GPIO as GPIO ImportError: No module named RPi.GPIO ``` 這個錯誤是因為系統中沒有安裝 `RPi.GPIO` 模塊。這個模塊是用來控制 Raspberry Pi 的 GPIO 腳位的。 你可以通過以下命令來安裝 `RPi.GPIO`: ```bash sudo apt-get update sudo apt-get install python3-rpi.gpio ``` 如果你使用的是 Python 2,可以用以下命令: ```bash sudo apt-get install python-rpi.gpio ``` 安裝完成後,再次運行你的程式,應該就能正常使用了。如果還有其他問題,隨時告訴我! ## Raspberry Pi 4 Python3 程式码 ``` # -*- coding: utf-8 -*- # 好的!這個錯誤是因為你的 Python 文件中包含非 ASCII 字符(比如中文或特殊符號),但沒有指定編碼格式。你可以在文件的開頭添加以下一行來解決這個問題: # ```python # # -*- coding: utf-8 -*- # ``` # 這行代碼告訴 Python 使用 UTF-8 編碼來讀取文件。完整的文件開頭應該是這樣: # ```python # # -*- coding: utf-8 -*- # # 其他代碼... # ``` # 加上這一行後,再次運行程式應該就不會出現這個錯誤了!如果還有其他問題,隨時問我。 import RPi.GPIO as GPIO # 這個錯誤是因為系統中沒有安裝 `RPi.GPIO` 模塊。這個模塊是用來控制 Raspberry Pi 的 GPIO 腳位的。 # 你可以通過以下命令來安裝 `RPi.GPIO`: # ```bash # sudo apt-get update # sudo apt-get install python3-rpi.gpio # ``` # 如果你使用的是 Python 2,可以用以下命令: # ```bash # sudo apt-get install python-rpi.gpio # ``` # 安裝完成後,再次運行你的程式,應該就能正常使用了。如果還有其他問題,隨時告訴我! import time # 设置GPIO模式 GPIO.setmode(GPIO.BCM) # 定义引脚 TRIG = 23 # Trig 引脚连接到 GPIO 23 ECHO = 24 # Echo 引脚连接到 GPIO 24 # 设置引脚方向(IN / OUT) GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) def distance(): # 发送高电平信号到 Trig 引脚 GPIO.output(TRIG, True) # 持续 10 微秒 time.sleep(0.00001) GPIO.output(TRIG, False) # 记录发射时间 while GPIO.input(ECHO) == 0: start_time = time.time() # 记录接收时间 while GPIO.input(ECHO) == 1: stop_time = time.time() # 计算时间差 time_elapsed = stop_time - start_time # 声速为34300 cm/s,计算距离 distance = (time_elapsed * 34300) / 2 return distance try: while True: dist = distance() # 這個錯誤通常是因為你使用的 Python 版本不支持 f-string。f-string 是從 Python 3.6 開始引入的,如果你的版本低於這個,會出現 `SyntaxError`。 # 你可以通過以下命令檢查 Python 的版本: # ```bash # python --version # ``` # 如果你使用的是 Python 3.6 或更高版本,f-string 應該是可以正常工作的。如果不是,你可以將該行改寫為傳統的格式化方式,例如: # ```python # print("Measured Distance = {:.2f} cm".format(dist)) # ``` # 這樣就可以兼容較舊的版本了。希望這樣能幫到你!如果還有其他問題,隨時告訴我。 ## Python 3.6 Up # print(f"Measured Distance = {dist:.2f} cm") ## Python 2.7.18 print("Measured Distance = {:.2f} cm".format(dist)) time.sleep(1) # 清理GPIO设置 except KeyboardInterrupt: print("Measurement stopped by User") GPIO.cleanup() ``` 执行语法: ``` python3 HC-SR04.py ``` python `HC-SR04.py` 的python有时候安装的版本太旧,所以用python3运行问题会少点。