今天我们来玩超声波测距传感器。我购买的是型号是US-015,长得是下面这个样子:
可以看到它有四个引脚,除了电源VCC和地线GND外,主要靠Trig(触发)引脚和Echo(回波)引脚来测距。其工作原理如下图
其工作的时序图如下:
由于超声波电源为5V,在树莓派的官方文档中,5V的电压如果接到GPIO引脚,会烧坏树莓派(树莓派使用3.3V电压)。所以推荐在连接Echo引脚时通过电阻来做分压处理,其电路如下图所示:
如果我们手边没有330欧和470欧的电阻,也可以使用2个完全相同的电阻来做分压,电阻的大小不限,这样分压后的GPIO引脚可以得到2.5V的电平,仍然会读入为高电位(一般集成电路会把超过2伏作为高电位),可以得到同样的效果。(多说一句:我看到网上很多文章提供的电路都是让5v的Echo直接连接GPIO,也可以成功,我自己也试了一下,从我的经历看,树莓派没有被5v的电压烧毁,其原因应该是Echo一直输出低电位,只有在trig触发后的检测到回波时才短暂的输出5v高电位,所以很幸运的没有对树莓派造成影响,但 不建议大家尝试,否则后果自负! )
最终的电路连接好后如下图所示:
然后执行下面的程序,这段程序的逻辑就是向Trig引脚发送10us的高电平,触发超声波模块发送8个40khz的方波,然后读取Echo的高电位时间,此时间就是超声波从发送到返回的时间,也就是2个从传感器到阻挡物体的距离。
import RPi.GPIO as GPIO
from time import sleep,time
TRIG = 6 #传感器tirg引脚接GPIO6
ECHO = 17 #传感器Echo引脚接GPIO17,大家需要根据自己电路连接情况修改
GPIO.setmode(GPIO.BCM) #设置为BCM模式。
GPIO.setup(TRIG,GPIO.OUT) #把 GPIO6设置为输出
GPIO.setup(ECHO,GPIO.IN) #把GPIO17设置为输入
GPIO.output(TRIG,0) # 给Trig输出低电平
i = 1 # 测距计数器
while True:
print("-----start----",i)
sleep(0.00002) #让低电平保持20us
GPIO.output(TRIG,1) #触发trig,设置为高电位10us
sleep(0.00001) # 保持高电位10us
GPIO.output(TRIG,0) # 然后把trig设置为低电位
while GPIO.input(ECHO) == 0: # 当Echo为低电位时在此循环等待
a = 1
time1 = time() # 当Echo为高电位时跳出上面的while循环,读取此时时间
while GPIO.input(ECHO) == 1: # 当Echo为高电位是循环,直到变为低电位
a = 2
time2 = time() # 当Echo变为低电位时跳出上面while循环,读取当前时间
#print("time2:",time2)
during = time2-time1 # 计算保持高电位的时间
#print("during:",during)
distance = during*340*100/2 # 高电位的时间 * 340米(声音速度)/2(往返),乘100转为厘米
print("time1:",time1)
print("time2:",time2)
print("during:",during)
print("distance:",distance) # 显示测算的距离
sleep(2)
i = i+1
运行程序时,在超声波前面移动书本,可以看到输出如下:
其实,GPIOZero其实已经实现了距离传感器,并且封装为可以直接使用的类DistanceSensor,用它的话代码会非常简单,其底层实现的机理和我们上面的代码其实是一样的。
from gpiozero import DistanceSensor
from time import sleep
sensor = DistanceSensor(echo=17, trigger=6)
while True:
print('Distance: ', sensor.distance * 100)
sleep(1)
运行结果如下:
全部0条评论
快来发表一下你的评论吧 !