树莓派超声波测距
树莓派引脚使用
直接给出树莓派引脚图:
![](https://img-blog.csdnimg.cn/img_convert/586b116962b1724fc49cc61d28cfd168.png)
![](https://img-blog.csdnimg.cn/img_convert/0e4aa38547753eb6f5a43b6347760921.png)
如上图所示,我们可以很清楚的看到各个引脚的功能。
例如我们想使用 pwm 引脚来控制舵机,则我们可以考虑使用其中的 BCM18(PWM0) 和 BCM13(PWM1)。
在使用 wiringPi 库时,我们定义的引脚即 BCM 引脚,例如:
pwmPinV = 18
pwmPinH = 13
如果这里使用 python 语言,直接引入对应的库即可:
#导入 GPIO库
import RPi.GPIO as GPIO
#定义 GPIO 引脚
GPIO_TRIGGER = 23
GPIO_ECHO = 24
树莓派获取超声波数据
前面我们已经多次介绍超声波 HC-SR04 模块的使用原理,这里我们就不再进行说明,我们只给出树莓派如何进行超声波测距
接线方式
-
4 个引脚由 2 个电源引脚(Vcc 、GND)和 2 个控制引脚(Trig、Echo)组成
-
Vcc 和 Gnd 接 5v DC 电源,但不推荐用独立电源给它供电,应使用树莓派或单片机的 GPIO 口输出 5v 和 Gnd 给它供电。不然会影响这个模块的运行
-
Trig 引脚用来接收来自树莓派的控制信号。接任意 GPIO 口
-
Echo 引脚用来发送测距结果给树莓派。接任意 GPIO 口
注意:Echo 返回的是 5v信号,而树莓派的 GPIO 接收超过 3.3v 的信号可能会被烧毁,因此需要加一个分压电路
HC-SR04 的测距过程
-
树莓派向 Trig 脚发送一个持续 10us 的脉冲信号
-
HC-SR04 接收到树莓派发送的脉冲信号,开始发送超声波 (start sending ultrasoun),并把 Echo置为高电平。 然后准备接收返回的超声波
-
当 HC-SR04 接收到返回的超声波 (receive returned ultrasound) 时,把 Echo 置为低电平
从上述过程可以看出, Echo 高电平持续的时间就是超声波从发射到返回所经过的时间间隔
![](https://img-blog.csdnimg.cn/img_convert/6102f01ccaa388d76f36dd47f980b635.png)
电路图
![](https://img-blog.csdnimg.cn/img_convert/eb321675981b342c991fd3207a296adb.png)
接线跟前文所说的一样。 GPIO 2 脚接 Trig , GPIO 3 脚接 Echo 。树莓派的 +5v 和 Gnd 与 HC-SR04 的 Vcc 和 Gnd 相连。还有一个分压电路,一端接 Echo ,另一端接 Gnd
1k 和 2k 电阻组成了一个分压电路,使 GPIO 3 脚的电压降到了 3.3v 左右
python 程序
初始化相关引脚:
#导入 GPIO库
import RPi.GPIO as GPIO
import time
#设置 GPIO 模式为 BCM
GPIO.setmode(GPIO.BCM)
#定义 GPIO 引脚
GPIO_TRIGGER = 23
GPIO_ECHO = 24
#设置 GPIO 的工作方式 (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
23 脚连 Trig ,设为输出模式; 24 脚连 Echo,设为输入模式
注意:这里的引脚 23 与 24 并不是板子上的引脚顺序编号,而是 GPIO 引脚号
然后向 Trig 引脚输入 10us 的脉冲:
GPIO.output(GPIO_TRIGGER, True)
# 持续 10 us
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
time.sleep() 接收的参数单位为 s ,于是把10 us 转换为 0.00001 s
接收到这个脉冲后,HC-SR04 发射出超声波,同时把 Echo 置为高电平。在发射之前,Echo 一直为低电平
据此编写程序,记录超声波发射时的时间
# 记录发送超声波的时刻1
while GPIO.input(GPIO_ECHO) == 0:
start_time = time.time()
然后记录超声波返回时的时间
# 记录接收到返回超声波的时刻2
while GPIO.input(GPIO_ECHO) == 1:
stop_time = time.time()
这样就获得了我们需要的数据 pulse_start 和 pulse_end ,可以算出距离了
测得距离(单位:m) = (pulse_end – pulse_start) * 声波速度 / 2
声波速度取 343m/s
然后再把测得的距离转换为 cm
测得距离(单位:cm) = (pulse_end – pulse_start) * 声波速度 / 2 * 100 = (pulse_end – pulse_start) * 17150
time_elapsed = stop_time - start_time
# 声波的速度为 343m/s, 转化为 34300cm/s。
distance = (time_elapsed * 34300) / 2
dist = distance()
print("Measured Distance = {:.2f} cm".format(dist))
time.sleep(1)
以下是完整代码:
#导入 GPIO库
import RPi.GPIO as GPIO
import time
#设置 GPIO 模式为 BCM
GPIO.setmode(GPIO.BCM)
#定义 GPIO 引脚
GPIO_TRIGGER = 23
GPIO_ECHO = 24
#设置 GPIO 的工作方式 (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
def distance():
# 发送高电平信号到 Trig 引脚
GPIO.output(GPIO_TRIGGER, True)
# 持续 10 us
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start_time = time.time()
stop_time = time.time()
# 记录发送超声波的时刻1
while GPIO.input(GPIO_ECHO) == 0:
start_time = time.time()
# 记录接收到返回超声波的时刻2
while GPIO.input(GPIO_ECHO) == 1:
stop_time = time.time()
# 计算超声波的往返时间 = 时刻2 - 时刻1
time_elapsed = stop_time - start_time
# 声波的速度为 343m/s, 转化为 34300cm/s。
distance = (time_elapsed * 34300) / 2
return distance
if __name__ == '__main__':
try:
while True:
dist = distance()
print("Measured Distance = {:.2f} cm".format(dist))
time.sleep(1)
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()