什么是声纳
声纳是一种利用声波在介质中的传播特性,通过电声转换和信息处理,完成探测和通讯任务的电子设备。它有主动式和被动式两种类型,属于声学定位的范畴。
我们通常见到的声纳装置多用于水下通信水下探测,因为我们知道声音的传播是依靠介质的震动,而硬度越大的媒介更易传播震动,所以在水中声音的传播要远比空气中快(标准温度下,水中传输速率在1500m/s,空气中传输速率在340m/s)。而更多的应用到我们生活中的是以空气为介质的装置,比如汽车上的倒车雷达,它虽比在水中的传输速度远慢,但足以够我们的生活需要了,毕竟没谁每天超音速的跑。
今天我们采用的HC-SR04传感器,是工作于空气当中的。
HC-SR04
HC-SR04是一款集成的性价比高的超声波测距模块,通常量程在2cm--2m,量程主要收到噪声的影响,随着距离增长回声的能量减小,回声的相位变得复杂难以识别,而距离较近的时候,多次反射回声的能量依旧够强,也就造成了信号的难以辨识,所以信号处理通常情况下也是传感器量程精度的一大限制。
通常买到的模块及是这样子的。。
引脚描述
它有四个引脚,分别是Vcc Trigger Echo Gnd。
接法:
Vcc---5V
Trigger---D12
Echo---D11
Gnd---Gnd
其中,trigger为信号触发器,通常是芯片给模块发出一个至少10us时常的高平电位信号来触发,随后模块内部会激荡起一组8周期的40kHz的信号来激励超声波,预测同时模块在echo端产生一个高电平信号,直到收到回声信号转为低平电信号,整个过程中芯片只需测量出echo端信号上升沿至下降沿的时间,从而推算出距离。方法是:
$$测量距离=行程时间\times传输速度\div2$$
$$其中,传输速度就是当地声速,一般就取常值340m/s$$
Arduino程序:
define echo_Pin 11
#define trigger_Pin 12
#define factor 58.823 //空气速度340m/s,一个往返行程
float temp=0.0;
void setup()
{
Serial.begin(115200);
pinMode(echo_Pin,INPUT);
pinMode(trigger_Pin,OUTPUT);
digitalWrite(trigger_Pin,LOW);
}
void loop()
{
digitalWrite(trigger_Pin,HIGH);
delayMicroseconds(10);
digitalWrite(trigger_Pin,LOW);
// int n=0;
// for(int i=0;i<300;i++){
// n += digitalRead(echo_Pin);
// Serial.println(digitalRead(echo_Pin));
// }
temp = pulseIn(echo_Pin,HIGH,10000);//大概量程设置到1米5
if(temp==0)
{
Serial.println("over range");
}
else
{
Serial.print("\tdistance(cm): ");
Serial.println(temp/factor);
}
pinMode(echo_Pin,OUTPUT);
digitalWrite(echo_Pin,LOW);
delay(100);
pinMode(echo_Pin,INPUT);
}
首先,这里我们需要说明,通常情况下,大家在使用的时候会发现,当实际距离超出了测量量程时候,系统返回值为0。
对于这个问题,我们需要首先了解一下Arduino内置的函数pulseIn(pin,HIGH,TimeOut),它表示在TimeOut时间之内,测量到引脚pin为高电平的时间(单位为microsecondes)。
这就存在问题了,pulseIn函数既然是测量高电平时间的,那如果整个行程始终LOW或者HIGH怎么办,这样的情况下,我们测量不出来高低变化,于是函数自动返回0。而如果,行程开始是高电平,后来产生低电平,那么此时返回值便从行程开始计时,具体我们看一张贴图: 如果执行 pulseIn(pin, HIGH) 时在 A 点, 刚好是 HIGH 的状态, 就会开始计时, 在 B 点完结, 只计算了一部份的时间 (红线).
如果执行 pulseIn(pin, HIGH) 时在 C 点, 刚好是 LOW 的状态, 就会等到 D 点才开始计时, 在 E 点完结, 可以得到完整的时间 (绿线).
其次,在我们了解了这个情况下,我们要解决这个问题,就得明白模块的运作。。模块echo端是在发出信号时输出高电平,等到收到回传信号才输出低电平,,那么我们就得问了,如果没有回传呢?这里模块就存在了逻辑失误了,它会一直等到有数据时候才调为低电平。而且,我们观察的细致的话,还会发现,当模块出现问题时候,它不在发声,这个声音是内部激振时候电子流动声音。。
所以,我们才加入几行代码,将echo端,在一个周期结束时候强行拉低,这样就解决了我们的这个问题。