树莓派使用HC-SR04超声波测距

Posted LxFly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派使用HC-SR04超声波测距相关的知识,希望对你有一定的参考价值。

超声波模块介绍

  超声波测距原理很简单:
  1、通过记录发送超声波的时间、记录超声波返回的时间,返回时间与发送时间相减得到超声波的持续时间。
  2、通过公式:(超声波持续时间 * 声波速度) / 2就可以得出距离;

  HC-SR04参数:
  工作电压: 5V
  工作电流:15mA
  最短测量距离:3cm
  最长测量距离:4m
  角度15度
  Trig引脚输入信号:10us TTL 脉冲
  Echo引脚输出信号:5v脉冲信号

超声波模块接线与工作过程

接线:

  总共4引脚:2电源引脚(Vcc、GND)和2个控制引脚Trig、Echo;
  Vcc为5v供电
  Trig引脚用于接收树莓派信号,可接所有GPIO口。
  Echo引脚用于发送测距结果给树莓派,可接所有GPIO口,返回5v信号。

测距工作过程:

  1、树莓派向Trig引脚发送持续10us的脉冲信号;
  2、HC-SR04发送超声波,将Echo置位高电平,准备接收超声波返回;
  3、HC-SR04收到超声波返回把Echo置位低电平;

程序实现

  通过上面HC-SR04超声波测距模块使用过程,原理的分析,使用Python很容易就写出了超声波测距的Demo程序,具体实现如下:
  程序的关键点:
  1、获取超声波发送时的时间
  2、获取超声波返回时的时间
  3、把超声波发送与返回的时间差带入公式:(超声波持续时间 * 声波速度) / 2 即可得到距离

Trig_Pin = 14
Echo_Pin = 4

GPIO.setmode(GPIO.BCM)
#设备GPIO工作方式IN/OUT
GPIO.setup(Trig_Pin,GPIO.OUT,initial = GPIO.LOW)
GPIO.setup(Echo_Pin,GPIO.IN)

def ultrasonic():
    #发送高电平到Trig引脚
    GPIO.output(Trig_Pin,GPIO.HIGH)
    #持续10us 微秒
    time.sleep(0.00001)
    GPIO.output(Trig_Pin,GPIO.LOW)
    #记录发送超声波时刻,发送前Echo_Pin为低电平,当变为高电平是说明超声波已发送
    while GPIO.input(Echo_Pin) == GPIO.LOW:
        pass
    t1 = time.time()

    #记录收到返回超声波时刻,当Echo_变为低电平时说明超声波已经返回
    while GPIO.input(Echo_Pin) == GPIO.HIGH:
        pass
    t2 = time.time()

    #超声波往返时间:t2-t1
    #声波在空气中传播速度340m/s 记录时间 t 来回 2
    #高电平时刻时间减去低电平时刻时间,得到超声波传播时间,单位转换为厘米乘以100
    distance = (t2-t1) * 340 *100 /2
return distance

《树莓派项目实战》第六节 使用超声波模块测距

目录

6.1 引脚介绍

6.2 工作原理

6.3 使用注意

6.4 连接到树莓派

6.5 编写代码输出距离


在本节,我们将学习如何使用HC-SR04超声波模块测量前方障碍物的距离,该项目设计到的材料有:

  1. 树莓派 * 1
  2. 面包板 * 1
  3. 杜邦线若干
  4. HC-SR04超声波模块* 1

6.1 引脚介绍

从上图我们可以看到超声波模块的4个引脚,它们的作用罗列如下:

1. VCC: 电源引脚,超声波模块工作电压为5伏。

2. Trig: 是Trigger(触发)这个单词的缩写,该引脚用于触发超声波脉冲。

3. Echo: 该引脚会在高电平和低电平之间转换,当检测到障碍物时,在高电平保持的时间就表示信号发射出去并反射回来的时间。

4. GND: 接地引脚。

6.2 工作原理

如果超声波模块前方没有障碍物,约4米),那当Trig引脚发射10μs的超声波脉冲后,Echo引脚会开始产生一个高电平并持续38毫秒,之后就会处于低电平状态,所以当得到38ms这个值时,我们就知道前方没有检测到障碍物了。

如果前方有障碍物,那在Trig引脚发射10μs的超声波脉冲后,信号就会反射回来,Echo引脚就会在接收到信号时立即切换到低电平状态,此时Echo引脚在高电平状态保持的时间就是信号发射并返回的所花的时间。

我们知道距离=速度 * 时间,要求出超声波模块到障碍物之间的距离,我们就需要知道速度和时间。速度就是340m/s,也就是声音在空气中传播的速度,转换城cm/μs单位就是0.034 cm/μs。时间的话,由于我们得到的是信号从发射到返回的时间值,所以需要除以2。

最终得到的计算公式为距离 =  0.034 cm/μs * 时间(μs) / 2

6.3 使用注意

以下情况可能会导致距离检测失败:

1. 目标障碍物太小。

2. 目标障碍物距离太远,超过13英尺(大约4米)。

3. 发射的信号以一定倾斜角度(小于45°)接触目标障碍物,导致信号无法被反射回来,如下图所示。

4. 目标障碍物材质特殊(比如毛绒玩具),可能会吸收信号,而不是将反射回来。

6.4 连接到树莓派

我们将超声波模块插到面包板上,然后连接引脚:

  • VCC引脚连到树莓派的2号5V引脚。
  • Trig引脚连到树莓派的16号GPIO引脚。
  • Echo引脚连到树莓派的18号GPIO引脚。
  • GND引脚连到树莓派的14号Ground引脚。

6.5 编写代码输出距离

import time
import RPi.GPIO as GPIO


# 设置编码方式
GPIO.setmode(GPIO.BOARD)

# 设置Trig和Echo的引脚编号
Trig = 16
Echo = 18

# 设置引脚模式
GPIO.setup(Trig, GPIO.OUT)
GPIO.setup(Echo, GPIO.IN)

def get_distance():
    # Trigh引脚发射10μs的超声波脉冲
    GPIO.output(Trig, GPIO.HIGH)
    time.sleep(0.1)
    GPIO.output(Trig, GPIO.LOW)

    # Echo引脚检测反射信号
    while GPIO.input(Echo) == GPIO.LOW:
        start_time = time.time()

    while GPIO.input(Echo) == GPIO.HIGH:
        end_time = time.time()
    
    # 持续时间大于38毫秒的话
    # 就表明前方无障碍物或者障碍物太远
    duration = (end_time - start_time)
    if duration * 1000 > 38:            # 将秒转换成毫秒
        return
    
    # 返回以cm为单位的距离值
    return 0.034*duration*1000000/2    # 将秒转换成微秒


if __name__ == "__main__":
    try:
        while True:
            distance = get_distance()
            if distance:
                print(f"障碍物距离是distance:.2fcm")
            else:
                print("前方无障碍物或障碍物离得太远!")
    except KeyboardInterrupt:
        print("停止检测")
        GPIO.cleanup()

我们重点来看下get_distance()函数。在发射了10μs的信号后,我们就分别通过start_time和end_time两个变量记录Echo引脚处于高电平状态的开始和结束时间。接着,将start_time减去end_time得到信号从发射到回来的时间间隔(单位:秒),保存到duration变量中。如果duration的值大于38毫秒,那么就表明前方没有障碍物或者障碍物离得太远;否则的话就通过0.034*duration*1000000/2计算得到目标障碍物的距离(单位:厘米)。

运行截图如下:

以上是关于树莓派使用HC-SR04超声波测距的主要内容,如果未能解决你的问题,请参考以下文章

《树莓派项目实战》第六节 使用超声波模块测距

linux系统下超声波测距(树莓派)

《树莓派项目实战》第六节 使用超声波模块测距

树莓派超声测距

树莓派学习目录

树莓派3b+ HC-SR04超声波模块驱动(C语音编写,wiringPi)