什么是超声波
超声波是频率高于20000赫兹的声波。
超声波是一种特定频率范围内的声波,其特点在于频率高于人耳能够感知的上限,即超过20千赫兹(Hz)。这种高频率的声波具有一些独特的性质:
- 方向性好:超声波几乎可以沿直线传播,这使得它们在定位和探测方面非常有用。
- 穿透能力强:超声波能够穿透许多对于普通声波不透明的材料,例如金属或固体。
- 能量大:在媒质中传播时,超声波能产生巨大的能量,有时足以引起材料的微小颗粒振动,甚至导致“破碎”现象。
HC-SR04硬件概述
HC-SR04超声波距离传感器的核心是两个超声波传感器。一个用作发射器,将电信号转换为40 KHz超声波脉冲。接收器监听发射的脉冲。如果接收到它们,它将产生一个输出脉冲,其宽度可用于确定脉冲传播的距离。该传感器体积小,易于在任何机器人项目中使用,并提供2厘米至400厘米(约1英寸至13英尺)之间出色的非接触范围检测,精度为3mm。
工作原理
超声波传感器使用声纳来确定与物体的距离。发生的情况如下:
- 超声波发射器(trig 引脚)发出高频声音 (40 kHz)。
- 声音在空气中传播。如果它找到一个对象,它会反弹回模块。
- 超声波接收器(回声针)接收反射声(回声)。
超声波传感器模块使用两个I0口分别控制超声波发送和接收,工作原理如下:
1、给超声波模块接入电源和地;
2、给脉冲触发引脚(trig)输入一个长为10us的高电平方波;
3、输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;(此时应该启动定时器计时)
4、当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长;
5、根据声音在空气中的速度为340米/秒,即可计算出所测的距离。
温度对距离测量的影响
HC-SR04对于我们的大多数项目来说都相当准确,例如入侵者检测或接近警报;但是有时候您可能想设计一种要在户外或在异常炎热或寒冷的环境中使用的设备。在这种情况下,您可能要考虑到空气中的声速随温度,气压和湿度而变化的事实。
由于声音因素进入HC-SR04距离计算的速度,因此可能会影响我们的读数。如果已知温度(°C)和湿度,请考虑以下公式:
声速 m/s = 331.4 +(0.606 * 温度)+(0.0124 * 湿度)
HCSR04的开源脚本
micropython中没有集成HC-SR04模块,HCSR04的开源脚本:
import machine, time
from machine import Pin
class HCSR04:
"""
Driver to use the untrasonic sensor HC-SR04.
The sensor range is between 2cm and 4m.
The timeouts received listening to echo pin are converted to OSError('Out of range')
"""
# echo_timeout_us is based in chip range limit (400cm)
def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
"""
trigger_pin: Output pin to send pulses
echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
echo_timeout_us: Timeout in microseconds to listen to echo pin.
By default is based in sensor limit range (4m)
"""
self.echo_timeout_us = echo_timeout_us
# Init trigger pin (out)
self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
self.trigger.value(0)
# Init echo pin (in)
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
def _send_pulse_and_wait(self):
"""
Send the pulse to trigger and listen on echo pin.
We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
"""
self.trigger.value(0) # Stabilize the sensor
time.sleep_us(5)
self.trigger.value(1)
# Send a 10us pulse.
time.sleep_us(10)
self.trigger.value(0)
try:
pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
return pulse_time
except OSError as ex:
if ex.args[0] == 110: # 110 = ETIMEDOUT
raise OSError('Out of range')
raise ex
def distance_mm(self):
"""
Get the distance in milimeters without floating point operations.
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.34320 mm/us that is 1mm each 2.91us
# pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582
mm = pulse_time * 100 // 582
return mm
def distance_cm(self):
"""
Get the distance in centimeters with floating point operations.
It returns a float
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.034320 cm/us that is 1cm each 29.1us
cms = (pulse_time / 2) / 29.1
return cms
我们将触发引脚(trigger_pin)连接到开发板的GPIO5,回声引脚(echo_pin)连接到GPIO4。
代码使用示例:
hcsr04=HCSR04(trigger_pin=5, echo_pin=4)
if __name__=="__main__":
while True:
distance=hcsr04.distance_cm()
print("distance=%.2fCM" %distance)
time.sleep(2)
实验结果: