摘要:本文介绍如何利用超声波传感器测量障碍物的距离
测量距离是智能小车经常要用到的功能,今天就来介绍一个最常用的测量距离的传感器——超声波传感器。
超声波传感器的测距原理是利用超声波发射器向某个方向发射超声波,与此同时,我们开始计时。当发射出去的超声波遇到障碍物时,它会立即被反射回来,当超声波接收器接收到反射波后我们停止计时。这时,接收器收到反射波与发射器发出超声波之间的时间就是超声波在空气中的飞行时间,在这段时间里,超声波从发射器飞到了障碍物,然后又从障碍物返回到了接收器。这样,根据空气中的声波速率为340米/秒,以及记录的时间t,就可以计算出发点和障碍物之间的距离s,即:s =340m/s * t/2。
下图就是最常用的超声波测距模块。
这种超声波测距模块的测量范围在2厘米~400厘米之间,测量的距离的精度可以达到3毫米。
超声波测距有以下几个特点:
- 超声波的频率越高,测量的精度也越高,但由于空气衰减的增大,检测距离会变越近。
- 超声波发射器输出功率越高、灵敏度越高,检测距离也越远。
- 通常超声波检测角度小的,测距范围会略远。
- 受被测物体表面状况、形状的影响大:例如一个刚性表面(例如钢板、水泥墙)会有很好的测量结果。而一根铁丝、或者在钢板表面铺满吸音绵、或者把钢板与探头法线的夹角是倾斜45度以上等等,可能会无法得到正确的测量结果。
- 多个工作频率相近的超声波测距模块同时工作,会互相影响,有可能无法区分出是哪个超声波发射器发出的超声波。
下面就来看一下超声测距模块的电器参数。
电气参数 | HC-SR04 超声波模块 |
工作电压 | DC 5V |
工作电流 | 15mA |
工作频率 | 40kHz |
最远射程 | 4m |
最近射程 | 2cm |
测量角度 | 15度 |
输入触发信号 | 10uS的TTL脉冲 |
输出回响信号 | 输出TTL电平信号,与射程成比例 |
规格尺寸 | 45*20*15mm |
超声波测距模块共有4个引脚,这些引脚的定义说明如下:
引脚 | 说明 |
VCC | 供电引脚,5V直流供电。 |
Trig | 触发控制信号输入引脚。 |
Echo | 回响信号输出引脚。 |
GND | 供电GND引脚。 |
下面来了解一下超声波测距模块的工作过程。
(1)超声波测距模块是IO口Trig触发测距,需要外部控制设备提供一个最少10us的高电平信号。
(2)超声波模块的超声波发射器自动发送8个40khz的超声波方波,超声波接收器自动检测是否有信号返回。
(3)如果超声波接收器收到信号返回,则通过IO口Echo输出一个高电平,该高电平持续的时间就是超声波从发射到返回的时间。因此,只要获得Echo引脚输出的高电平时间,就可以计算出距离障碍物的距离了。
具体的工作时序图如下图所示。
在以上时序图表明,只需要提供一个10uS以上脉冲触发信号,该模块内部在收到信号后将发出8个40kHz脉冲并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式:uS/58=厘米或者uS/148=英寸;或是:距离= 高电平时间*声速(340M/S)/2。
在使用超声波测距模块的时候,还应该注意一下几个问题:
- 建议测量周期为60ms以上,以防止发射信号对回响信号的影响。
- 此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。
- 超声波模块测距时,被测物体的面积不少于0.5平方米且平面尽量要求平整,否则可能影响测量的结果。
接下来,就把超声波测距模块与ESP32开发板用杜邦线连接起来了。一共需要4根导线,需要将超声波测距模块的VCC与开发板的5V相连接,Trig引脚连接到开发板的P18引脚,Echo引脚连接到开发板的P19引脚,GND与开发板的GND相连接就可以了。如下图所示:
接下来,就来进行软件的开发工作了。还是打开Mixly,选择“Arduino ESP32”。在这里实现的功能,就是把超声波测距模块测量的距离,通过串口打印出来。超声波测距模块功能“传感器”功能模块里面,只需要设置一下Trig和Echo使用的GPIO引脚号码就可以了。实现后的程序如下图所示:
接下来上传运行一下这个程序,可以看到,在下面的串口中,会陆续的输出一行行的数字,表示超声波前面物体距离超声波传感器的距离。如下图所示:
需要说明的是,Mixly中的超声波测距功能输出的测量距离的单位是厘米。下面来看一下Mixly生成的源代码。
float checkdistance_18_19() { digitalWrite(18, LOW); //将18引脚设置为低电平 delayMicroseconds(2); //保持2微秒 digitalWrite(18, HIGH); //将19引脚输出高电平 delayMicroseconds(10); //保持10微秒 digitalWrite(18, LOW); //将18引脚恢复低电平 float distance = pulseIn(19, HIGH) / 58.00; //返回19引脚高电平的时间,并计算结果 delay(10); return distance; } void setup(){ Serial.begin(115200); pinMode(18, OUTPUT); pinMode(19, INPUT); } void loop(){ Serial.println(checkdistance_18_19()); delay(1000); } |
在源代码中可以看到,setup()函数进行了初始化的工作,将引脚18初始化为输出工作模式,将19引脚初始化为输入工作模式。
整个代码的核心是生成的float checkdistance_18_19()函数,该函数的返回值为测量的距离(单位是厘米)。在这个函数中,按照超声波模块的工作流程,完成了一次测量工作。分为以下几个步骤:
- 将18引脚设置为低电平,并延迟2微秒,准备发出测量信号
- 将18引脚设置为高电平,并保持10微秒,通知超声波模块,开始测量
- 用pulseIn()函数返回19引脚高电平的时间,返回高电平时间的单位是微秒
- 利用返回的时间计算测量的结果
- 返回测量的结果
在这个测量里面的计算公式前边已经给出了。计算结果的单位是厘米。
对于使用MicroPython的开发者来说,超声波测距仪的使用方法与C语言是完全相同的,不同的是在MicroPython中,如果想连续多次测量,需要自己编写一个循环来实现。具体的实现方法如下所示:
Mixly生成的Python代码如下所示:
import machine import sonar import time while True: print(sonar.Sonar(32,33).checkdist()) time.sleep_ms(1000) |
在这里是利用了Sonar对象的checkdist()方法,返回的距离单位也是厘米。