在树莓派上测试防水型超声波测距模块

  • 内容
  • ....
  • 相关

当我们需要测量水桶里的水位或者在室外环境下进行距离测量时,那么会用到防水的超声波测距模块。它的使用与普通的超声波模块 HC-SR04 的方式是相同的。

防水型超声波传感器模块

防水型超声波传感器
防水型超声波传感器

是不是和我们常见的倒车雷达的探头是一样的。没错倒车雷达也就是在室外环境下使用的防水型超声波测距模块。除了上面的探头外,它还有一个控制板。

控制板背面
控制板背面
控制板正面
控制板正面

这个控制板的4个引脚功能与HR-SR04模块一样,分别是: Trigger (触发)、 Echo 、5V和GND, 模块能提供25厘米- 450厘米之间的测量范围。

超声波传感器模块与树莓派的连接

本文中,超声波模块直接从树莓派的5V和GND引脚取电,对应树莓派R1版是Pin 2和Pin 6引脚。超声波模块上的输入引脚称为“触发端”,用于发送超声波脉冲。它可以在树莓派GPIO引脚3.3V电压下很好的工作,所以模块的触发端 Trigger 引脚直接可以连接到树莓派R1版的引脚16 (GPIO23)。

该模块的输出脚称为“echo”,输出引脚默认是低电平状态(0V),当模块开始进行距离测量后,它进入高电平状态。这个引脚的高电平持续时间与脉冲返回的时间是相同的。所以我们的代码需要测量这个引脚保持高电平状态的时间。模块使用+5V电平表示“高电平”,但是对于树莓派上GPIO引脚的电压值来说太高了,GPIO引脚只能是3.3V。为了确保树莓派的安全,我们可以使用一个由两个电阻组成的简单分压器。

分压电路

由两个电阻组成的简单分压器。

如果R1和R2相等,则电压平分,这就得到2.5v电压。如果R2是R1的两倍那么就可以得到约3.33v电压。理想情况下,R2的值应该在R1和R1 x2之间。在示例电路中,使用了330欧和470欧的电阻。另外也可以使用使用1K和1.5K电阻。

下面是最终的电路连接图。使用了GPIO23和GPIO24,也可以使用其他的GPIO引脚,需要记住相应的引脚编号并在Python脚本中更新即可。

超声波传感器模块与树莓派的连接
超声波传感器模块与树莓派的连接

Python脚本

这里提供了两个测试脚本。分别是只读取一次测量数据和连续读取测量数据,详细如下:

一、读取一次测量数据并以厘米为单位显示结果:

#!/usr/bin/python
# -----------------------

# Import required Python libraries
from __future__ import print_function
import time
import RPi.GPIO as GPIO

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 23
GPIO_ECHO    = 24

# Speed of sound in cm/s at temperature
temperature = 20
speedSound = 33100 + (0.6*temperature)

print("Ultrasonic Measurement")
print("Speed of sound is",speedSound/100,"m/s at ",temperature,"deg")

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Send 10us pulse to trigger
GPIO.output(GPIO_TRIGGER, True)
# Wait 10us
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()

while GPIO.input(GPIO_ECHO)==0:
  start = time.time()

while GPIO.input(GPIO_ECHO)==1:
  stop = time.time()

# Calculate pulse length
elapsed = stop-start

# Distance pulse travelled in that time is time
# multiplied by the speed of sound (cm/s)
distance = elapsed * speedSound

# That was the distance there and back so halve the value
distance = distance / 2

print("Distance : {0:5.1f}".format(distance))

# Reset GPIO settings
GPIO.cleanup()

二、连续读取测量数据并以厘米为单位显示结果:

#!/usr/bin/python
# -----------------------
# Import required Python libraries
# -----------------------
from __future__ import print_function
import time
import RPi.GPIO as GPIO

# -----------------------
# Define some functions
# -----------------------
def measure():
  # This function measures a distance
  GPIO.output(GPIO_TRIGGER, True)
  # Wait 10us
  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time()
  
  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()

  elapsed = stop-start
  distance = (elapsed * speedSound)/2

  return distance

def measure_average():
  # This function takes 3 measurements and
  # returns the average.

  distance1=measure()
  time.sleep(0.1)
  distance2=measure()
  time.sleep(0.1)
  distance3=measure()
  distance = distance1 + distance2 + distance3
  distance = distance / 3
  return distance

# -----------------------
# Main Script
# -----------------------

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 23
GPIO_ECHO    = 24

# Speed of sound in cm/s at temperature
temperature = 20
speedSound = 33100 + (0.6*temperature)

print("Ultrasonic Measurement")
print("Speed of sound is",speedSound/100,"m/s at ",temperature,"deg")

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Wrap main content in a try block so we can
# catch the user pressing CTRL-C and run the
# GPIO cleanup function. This will also prevent
# the user seeing lots of unnecessary error
# messages.
try:
  while True:
    distance = measure_average()
    print("Distance : {0:5.1f}".format(distance))
    time.sleep(1)

except KeyboardInterrupt:
  # User pressed CTRL-C
  # Reset GPIO settings
  GPIO.cleanup()