声音是由物体的振动产生的,人们将每秒钟振动的次数称为声音的频率,它的单位是赫兹(Hz)。我们人类耳朵能听到的声波频率为20Hz~20000Hz。当声波的振动频率小于20Hz或大于20000Hz时,我们便听不见了。因此,我们把频率高于20000赫兹的声波称为“超声波”。由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量。

超声波测距原理

超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。超声波在空气中的传播速度为340m/s,根据计时器记录的时间t,就可以计算出发射点距障碍物的距离(s),即:s=340t/2 。这就是所谓的时间差测距法。
超声波测距的原理是利用超声波在空气中的传播速度为已知,测量声波在发射后遇到障碍物反射回来的时间,根据发射和接收的时间差计算出发射点到障碍物的实际距离。由此可见,超声波测距原理与雷达原理是一样的。
我们常用的超声波传感器是SR04、SR05两种,它们都是做好了电路集成的模块所以叫做超声波传感器模块。如图3.25.1所示。
image.png
图3.25.1 SR04超声波模块
真正的超声波传感器是没有模块化的,只是一个简单的发射器和一个接收器,如下图3.25.2所示,为了大家的实用方便,专门有厂商把超声波发射器和接收器做成了模块化,使用时只需要给模块供电,驱动发射引脚后就可以在接收引脚接收超声波传播的时间了。
image.png
图3.25.2 超声波传感器

超声波模块使用方法

image.png
图3.25.3 超声波模块测距时序图
如上图所示,在使用超声波模块时,只需要在触发信号引脚给一个大于10us的高电平的触发信号,触发后,模块模块会自动发送8个40KHz的超声波脉冲,并自动检测是否有信号返回。这步会由模块内部自动完成。如有信号返回,信号返回引脚会输出高电平,高电平持续的时间就是超声波从发射到返回的时间。此时,我们只需要能读取到这个高电平的时间,因为声速是已知的,我们就能计算出距被测物的实际距离。需要注意的是,通过这种方法测出的距离是实际距被测距离的2倍,因为超声波是发射出去,遇到障碍物又反射回来,走过的路程是实际测试距离的2倍。

常见超声波模块的参数

参数 SR04超声波模块
工作电压 DC 5V
工作电流 15mA
工作频率 40KHZ
最近测距 2cm
最远测距 400cm
测量角度 15度
输入触发信号 大于10us的脉冲
输出回响信号 输出高电平时长与测量距离成正比

超声波测距模块参考电路

image.png
图 SR04电路连接图
引脚连接参考下表

Arduino主板 SR04模块 备注
VCC VCC 电源引脚
GND GND 电源地线
2 Trig 触发信号引脚
3 Echo 回响信号引脚


超声波测距模块参考程序

  1. // 设定SR04连接的Arduino引脚
  2. int Trig_Pin = 2;
  3. int Echo_Pin = 3;
  4. unsigned long cm_dat; //测量数据存储变量
  5. void setup()
  6. { // 初始化串口通信及连接SR04的引脚
  7. Serial.begin(9600);
  8. pinMode(Trig_Pin, OUTPUT);
  9. // 要检测引脚上输入的脉冲宽度,需要先设置为输入状态
  10. pinMode(Echo_Pin, INPUT);
  11. Serial.println("超声波传感器测距测试:");
  12. }
  13. void loop()
  14. {
  15. // 产生一个10us的高脉冲去触发TrigPin
  16. digitalWrite(Trig_Pin, LOW);
  17. delayMicroseconds(2);
  18. digitalWrite(Trig_Pin, HIGH);
  19. delayMicroseconds(10);
  20. digitalWrite(Trig_Pin, LOW);
  21. // 检测脉冲宽度,并计算出距离
  22. cm_dat = (pulseIn(Echo_Pin, HIGH,500000)*0.0343)/2;
  23. // cm_dat = pulseIn(Echo_Pin, HIGH,500000) / 58.00;
  24. Serial.print(cm_dat);
  25. Serial.print("cm");
  26. Serial.println();
  27. delay(1000);
  28. }

知识拓展1

读取一个引脚的脉冲信号,信号可以是高电平(HIGH)或低电平(LOW)。例如,如果value 是HIGH,pulseIn(value)会等待引脚变为 HIGH,开始计时,再等待引脚变为 LOW 并停止计时。返回脉冲的长度,单位us。如果在指定的时间内无脉冲,函数返回0。此函数读取长时间的脉冲计时可能会出错,计时范围从 10 us至3 min。(1 s=1000 ms=1000 000 us)。
请注意,假如调用pulseIn(HIGH)函数时读取信号的引脚上已经为高电平,此时Arduino将等待该引脚变为低电平以后再开始检测脉冲信号。另外只有Arduino的中断是开启时,才能使用pulseIn()。

  1. pulseIn(pin, value);
  2. pulseIn(pin, value, timeout);
  3. pin: 需要进行脉冲计时的引脚号
  4. value: 要读取的脉冲类型,HIGH LOW
  5. timeout (可选):指定脉冲计数的等待时间,单位为微秒,默认值是 1 秒(unsigned long

知识拓展2:关于距离中除以58的说明

声音在干燥、20℃的空气中的传播速度大约为343米/秒,合34300厘米/秒。或者进行一次单位换算,34300/1000000厘米/微秒。即为:0.0343厘米/微秒,再换一个角度,1/(0.0343 厘米/微秒)即:29.15 微秒/厘米。这就意味着,也就是超声波走过1厘米需要时间29.15微秒。但是发送后接收到回波,声音走过的是2倍的距离。所以实际距离的1厘米距离,超声波需要走过2cm,对应所需要的时间就是29.15*2=58.3微秒。实际上整个测距过程是测得发出声波到收到回波的时间,而且单位是us。所以换成距离cm,要除以58,当然除以58.3可能更精确。所以程序中用 pulseIn(EcoPin, HIGH) / 58.00获取测得的距离。