使用Python进行超声波测距– Part 1

51

LED,蜂鸣器和开关是人们试图连接到Raspberry Pi的最常见物品’s. Something I found in eBay that is a little bit different is an 超音波 measurement module. This allows you to measure the distance to the nearest wall or solid object. 模块s are easy to buy, cheap and relatively straight forward to 接口 to the 通用输入输出 header.

因此,这是有关我使用超声波测量模块和Python进行实验的一些信息。在以后的项目中,我可以看到这些模块是为Pi驱动的机器人或汽车增加一些智能的绝佳方法。

超声波模块The HC-SR04 module cost approximately £3 ($5) and is the size of a box of matches. The two transducers give it a distinctive appearance. It is designed to be 功率ed by 5V, has 1 input pin and 1 output pin. 模块 works by sending an 超音波 pulse into the air and measuring the time it takes to bounce back. This value can then be used to calculate the distance the pulse travelled.

连接到Pi

为模块供电很容易。只需将+ 5V和接地引脚连接到Pi上的引脚2和引脚6’s 通用输入输出 header.

模块上的输入引脚称为“trigger” as it is used to 触发 the sending of the 超音波 pulse. Ideally it wants a 5V signal but it works just fine with a 3.3V signal from the 通用输入输出. So I connected the 触发 directly to Pin 16 (GPIO23) 上 my 通用输入输出 header.

您可以 use any 通用输入输出 pins you like 上 your RPi but you will need to note the references and amend your 蟒蛇 script accordingly.

分压器模块’的输出称为“echo” and needs a bit more thought. The output pin is low (0V) until the module has taken its distance measurement. It then sets this pin 高 (+5V) for the same amount of time that it took the pulse to return. So our script needs to measure the time this pin stays 高. 模块 uses a +5V level for a “high” but this is too 高 for the inputs 上 the 通用输入输出 header which 上ly like 3.3V. In order to ensure the Pi 上ly gets hit with 3.3V we can use a basic voltage divider. This is formed with two resistors.

如果R1和R2相同,则将电压分成两半。这将给我们2.5V。如果R2是R1值的两倍,那么我们得到3.33V,这很好。因此,理想情况下,您希望R2在R1和R1 x 2之间。在我的示例电路中,我使用了330和470欧姆电阻。另一种选择是使用1K和1K5值。

这是我的最终电路图。我选择了GPIO23和GPIO24,但是您可以使用GPIO接头连接器上的17个可用GPIO引脚中的任何一个。只要记住要更新脚本即可。

超声波模块电路

超声波模块电路

这是我的电路的照片。我用了一小块面包板和一些公对母跳线。

超声波传感器电路

超声波传感器电路

蟒蛇脚本

现在让脚本实际进行一些测量。在此示例中,我使用Python。为什么选择Python?它’是Pi上我最喜欢的语言,因此我倾向于在所有实验中使用它,但此处的技术可以轻松地应用于C。

您可以 either download the script directly using 这个连结Â或通过Pi上的命令行使用:

get //bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/ultrasonic_1.py

然后可以使用以下命令运行它:

sudo 蟒蛇 超音波_1.py

声音的速度

用于查找距离的计算取决于声音的速度。这随温度而变化。脚本根据预定义的温度计算要使用的正确值。您可以根据需要更改此值,也可以使用温度传感器动态地对其进行测量。

相片

这是我的超声波传感器通过GPIO头连接到Raspberry Pi的一些照片:

准确性

以下是有关准确性的一些要点:

  • 距离测量的精度取决于时间。 的Linux下的Python对于精确的时间安排不是理想的选择,但是对于一般的混乱工作就可以了。为了提高准确性,您需要开始着眼于使用C。
  • 配置了GPIO后,模块需要一些时间才能准备好进行第一次读取,因此我在脚本开始处添加了0.5秒的延迟。
  • 换能器具有宽广的灵敏度角。在混乱的环境中,由于模块侧面有物体,您可能会得到较短的读数。
  • 尺寸低至约2厘米。低于此限制,结果可能会给出奇怪的结果。
  • 如果超声换能器接触到任何东西,则结果是不可预测的。

由于有了这项技术,我现在知道从办公桌到天花板的距离为155厘米。

更新资料

如果有人想在C中试用这些设备,请查看此页面:
http://rasathus.blogspot.co.uk/2012/09/ultra-cheap-ultrasonics-with-hy-srf05_27.html
它还包括Python和C实现之间的比较。

学分

感谢Leroy Milamber纠正了我的代码中的错误。

相关文章

这是我的其他一些文章,如果您喜欢这篇文章,可能会觉得很有趣:

分享。

51条留言

    • 优秀的!绝对值得一玩。不知道我要用它做什么,但是如果我制造基于Pi的汽车,几乎肯定会有其中的一些。

    • 虽然我的照片似乎隐藏了我的照片,但我的照片仍被标记为SRF04。“4”。看了你的页面。好东西。一世’ll为有兴趣使用C的任何人添加我的文章到您的页面的链接。

      • 感谢您的链接。我可能应该挖出我的传感器,花些时间与它们一起玩。听起来我的某些测量值可能已经从我的桌子上拿走了,因此它们可能已经受到混乱的影响。

    • 这更多的是猜测,但我怀疑C会稍微快一点。尽管我看到的主要错误来源是周围表面的影响。如果传感器宽阔,清晰“tunnel”达到目标的准确性还不错。一旦您在环境中有点混乱,结果可能会出乎意料。

  1. 您所描述的内容与您的代码之间似乎存在差异:
    您提到,该模块将ECHO设置为HIGH(5V)的时间是脉冲离开并返回所需的时间…
    —quote—
    The output pin is low (0V) until the module has taken its distance measurement. It then sets this pin 高 (+5V) for the same amount of time that it took the pulse to return. So our script needs to measure the time this pin stays 高.
    —quote—
    Your code actually measures the time from the end of the 触发 until the end of the HIGH 回声…

    根据您的模块’的说明,而不应该是:

    # Send 10us pulse to 触发
    通用输入输出.output(GPIO_TRIGGER,True)
    时间。睡眠(0.00001)
    通用输入输出.output(GPIO_TRIGGER,假)

    # measure the time this pin stays 高
    #起始值是ECHO引脚的最后一个低电平
    而GPIO.input(GPIO_ECHO)== 0时:
    开始= time.time()

    # end value is the last 高 for ECHO pin
    而GPIO.input(GPIO_ECHO)== 1时:
    停止= time.time()

    #计算脉冲长度
    过去=停止启动

    也许你赢了’需要调整值。

    有什么想法吗?

    亲切的问候

    • 乐华,你是对的。不太确定为什么我要在等待脉冲开始时更新开始时间的同时记录停止时间。我已更新脚本并删除了调整值。我已经对硬件进行了快速测试,不再需要调整值。感谢您的宝贵意见!

  2. 该传感器的精度如何?分辨率是多少?例如,能否区分3英寸和4英寸?最大和最小范围是多少
    它可以用在吗?

    谢谢

    • 它可以分辨出3英寸和4英寸之间的差异。最小范围可能约为1英寸。我没有’尝试过更长的距离,所以不太确定最大值是多少。

  3. 卢卡斯(PJ Lucas)

    我在rev2 pi上有一些最初的问题。它正在感应初始脉冲,因此返回一些非常小的数字。查看此设备的规格表(我的设备是HC-SR04),建议在触发后等待60毫秒,以免检测到触发。那’s an easy fix:
    after the 通用输入输出.output(GPIO_TRIGGER,假) command just add
    time.sleep(0.00006)
    and all works fine.
    The specsheet also says it will measure upto 4m, but in reality it is a lot shorter, and using 蟒蛇 the distance is not very accurate (within 5cms per meter--ish) it also measures down to about 3cm in my experience.
    谢谢 for the code though, saved me a huge headache trying to fathom it.

  4. 无法等待得到我的Matt,应该很快到这里。
    即将将本文摘录到视频中ðŸ™,通过ðŸ™标准返回给您

  5. The 树莓派Guy

    嘿!

    感谢您的精彩教程!我遇到一些问题的一件事!我将如何连续显示数据?不只是一个价值?还有什么单位?厘米?

    谢谢!

    The 树莓派Guy

  6. 你好
    这是出色的文章/教程。
    我制作了20m长的UTP电缆,一端连接了传感器,另一端连接了raspi(使用单线连接)。一切运行正常(即使没有延迟,PJ Lucas在评论中提到)。
    我发现代码有问题…有可能:
    –gpio引脚已在使用中
    – program never gets 高 or low signal in while loop (happened two times)

    对于第一件事,需要检查是否正在使用gpio,在第二件事上,我将首先计算程序需要做多长时间的最大等待,然后仅将开始/结束时间与该值和退出循环进行比较。

    我在本教程中的应用是将传感器安装在40m长的电缆上,并将传感器安装在水井中,以测量水位(水位高约1m,并用温暖的塑料覆盖以防止水损坏),而raspi则在干燥的井中地点。

    感谢您的教程和想法,如何使用raspi。

  7. 你好
    你从哪里得到那些微小的分压器?我不能’甚至无法在亚马逊上找到它们!

    谢谢!很棒的网站!
    视线

  8. This wont work for me. Does not get any 回声 and therefore loops in line 43/44.

    However, if I directly connect the 回声 pin (no Rs) it gives me results.
    这是为什么?谁能告诉我?

    附言:
    最小范围是〜3.0,最大是120

    • 我只能建议您使用的模块不是’t outputting 5V 上 the 回声 pin. Is it the same module? Are you 功率ing it from 5V? If it is using a lower voltage the resistors would be feeding the 通用输入输出 pin with a voltage that is to low to register as a valid HIGH.

  9. 纳比尔·纳西尔(Nabeel Nasir)

    我对此有疑问。我感觉到,由于操作系统在RPi之上运行– 树莓派 is not a real-time operating system, the 触发 signal from the 超音波 can be missed 上 reflection. This can be due to the fact that there are several other processes running in the background of the RPi, and so the 回声 pin’s的读取命令可能错过了,或者比原本应该的时间晚了。

    我使用该模块找出行走在传感器下方的人员的身高。我尝试了在RPi(Python代码)以及Arduino上的实现。虽然Arduino平均为一个人行走记录了大约10个值,但是RPi代码只能记录大约4-5个值。我想这可能是因为我上面提到的原因。有什么想法吗?

  10. 嘿,马特
    我在项目中使用了您的ultra_2_2.py程序,我想在程序中添加提示音(意味着..当它计算距离或检测到障碍物时,它应该生成提示音),但是我无法做到这一点

  11. pingback: 树莓派–超声波距离传感器|保罗·格根

  12. 您好,我想将2个或可能更多的超声波传感器连接到1个覆盆子pi,您能告诉我我需要什么吗?造成即时通讯试图复制所有代码,我的意思是,定义2个新的引脚,设置它们,基本上只是复制所有内容,但对我不起作用。

  13. 罗纳德·阿塞维多

    你好
    谢谢您的精彩写作。不幸的是,当我尝试运行它时,我得到了虚假的读数。

    例如,无论我在其前面放置什么对象,其距离均为12.2厘米,这是我唯一更改的地方,即引脚分配


    import time
    import RPi.GPIO as gpio

    gpio.setmode( gpio.BCM )

    # setup pin assignments
    sonar_trigger = 27
    sonar_echo = 22

    print "Ultrasonic Measurement"

    gpio.setup( sonar_trigger, gpio.OUT )
    gpio.setup( sonar_echo, gpio.IN )

    while( True ):
    gpio.output( sonar_trigger, False )
    # allow module to settle
    time.sleep( 0.5 )

    # send 10us pulse to TRIG
    gpio.output( sonar_trigger, True )
    time.sleep( 0.00001 )
    gpio.output( sonar_trigger, False )

    while gpio.input( sonar_echo ) == 0:
    start_time = time.time()

    while gpio.input( sonar_echo ) == 1:
    end_time = time.time()

    # calculate pulse length (in cm)
    duration = end_time - start_time

    # convert pulse length to distance (cm/s)
    distance = duration * 34320
    distance = distance / 2

    print "Distance: %.1fcm" % distance
    time.sleep(1)

  14. 很棒的教程!完美地工作!

    对我而言,下一步是使步进电机停止一定距离。先生,您能帮我怎么办吗?

    就像超声波读数为2cm一样,停止电动机。

    如果您喜欢ðŸ™,我可以给您提供简短的代码

  15. 本·奥戈里克

    I’我也喜欢本教程。我在电子方面有一个问题。根据你的身材,我’m计算出从Echo到Raspberry Pi引脚的电压降为:

    5 *(330 /(330 + 470))= 2.06,

    我认为应该是3.3。我想念什么?

    谢谢,

    • 您可以’不要直接通过Pi上的GPIO引脚读取5V输出,因为它们只能接受最大3.3V的电压。如果在GPIO引脚上施加5V,则可能会损坏。

  16. 本·海沃德

    嗨,我真的很喜欢您的教程,谢谢您的发布。我购买了这些传感器之一,并尝试运行代码。但是森
    sor从不接收超声脉冲。我尝试更改脉冲长度,多次检查接线,更改面包板上的电线和布置,甚至还购买了新的传感器模块。这些都不能解决问题。我唯一的其他想法是我损坏了GPIO引脚。当我第一次将所有内容都挂钩时,我没有’不要使用电阻,因为我认为新的pi可以接收5V输入。我尝试通过读取加速度计的输入来检查引脚,该引脚仍然有效,但请记住它使用了不同的引脚。我想知道您是否对我的问题有任何想法?谢谢您的帮助ðŸ™,

    • 最好的办法是使用电阻,但尝试使用不同的GPIO引脚。只要更新代码中的引用,就可以使用所需的任何GPIO引脚。

  17. 您‘通过将测量值钳位到最大值,可以获得更稳定的结果。

    而(GPIO.input(GPIO_ECHO)== 1和(inRange == True)):
    停止= time.time()
    过去=停止– start
    如果(已过去> 0.017):
    inRange =假

  18. pingback: 互动式个人电脑Pi |抽象独角兽

  19. 很棒的教程。我现在正在做这个确切的项目。我想知道,如果系统未必要显示行驶距离,但如果到达某个点会通过电子邮件发送地址会有多困难?我认为这对于水位监控器会很好。有什么想法吗?再次感谢。

    • It’可以使用Python发送电子邮件,因此这是完全可能的。您只需要读取一个值,检查它是在某个值之上还是之下,然后调用一个函数来发送电子邮件。一世’有一个使用Python发送电子邮件的教程:

  20. 我正在考虑使用此东西来检测是否有人站在我的客厅前’的门。它可以检测到一个距离传感器1-3英尺的人吗?它还可以在与Pi3处于同一专用网络的移动设备上触发推送通知吗?

    • The resistors are 上ly required to divide the 5V to 3.3V which is what the 通用输入输出 pin requires. 您可以 use any values as long as the ratio is similar.

发表评论

该网站使用Akismet减少垃圾邮件。 了解如何处理您的评论数据.