超声波测距
本节课来学习使用 Arduino 控制超声波传感器并获取距离数据,最终搭配一个蜂鸣器实现倒车雷达的效果。
实验原理
超声波是一种频率高于 20000Hz 的声波,超声波的方向性好,反射能力强,易于获得较集中的声能,在水中传播距离比空气中远,可用于测距、测速、清洗、焊接、碎石、杀菌消毒等。
超声波可用于许多不同的领域。超声波设备用于检测物体和测量距离。超声成像或超声检查常用于医学。在产品和结构的无损检测中,超声波用于检测不可见的缺陷。在工业上,超声波用于清洁、混合和加速化学过程。蝙蝠和鼠海豚等动物使用超声波来定位猎物和障碍物。
本实验使用的超声波模块为 HC-SR04 超声波传感器,其原理为利用超声波在遇到障碍物后反射,结合声波在空气中的传播速度,可以得出传播的距离。该模块外观如下图所示:

超声波传感器使用声纳来确定与物体的距离。我们使用的超声波模块由 2 个超声波探头组成:
T
:表示Transmitter(发射)
,负责发送超声波信号;R
:表示Receiver(接收)
,负责接收回响信号;
注意
如果在使用过程中,对其中任意一个探头进行遮挡,都会使超声波无法正常测量距离。
底部有四个引脚:
VCC
:5V 供电引脚;GND
:接地;TRIG
:控制信号输入;ECHO
:回响信号输出;

以上时序图表示超声波模块的基本工作原理:
- 采用 IO 口 TRIG 触发测距,给一个 10us 的高电平信号;
- 模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
- 有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2
Trig 引脚是用来输入一个长为 10us 的高电平方波,通过输入这一方波,模块会自动发射 8 个 40KHz 的声波,并在这个时刻,Echo 引脚会由 0 变为 1,此时开启定时器定时。当超声波返回并被模块接收到后,Echo 端引脚电平从 1 变为 0,出现下降沿。这时候结束定时,通过计算定时器的值并乘上 340m/s 的声音传播速度,即可计算所测距离。
回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式如下:
距离 = 高电平时间 * 声速(340m/s)/2
硬件电路设计
物料清单(BOM 表):
材料名称 | 数量 |
---|---|
有源蜂鸣器 | 1 |
LED | 1 |
1KΩ 电阻 | 1 |
超声波模块 HC-SR04 | 1 |
杜邦线(跳线) | 若干 |
面包板 | 1 |
超声波模块 | 1 |

软件程序设计
Arduino 提供一个测量脉冲时间长度的 pulseln()
函数,语法格式:
pulseIn(pin, value)
pulseIn(pin, value, timeout)
该函数将返回微秒 us 单位的脉冲时间也就是说 pulseIn()
测出来的是超声波从发射到接收所经过的时间。
参数说明如下:
Pin
:需要读取脉冲的引脚;value
:需要读取的脉冲类型, HIGH 或 LOWtimeout
:超时时间,单位微秒,数据类型为⽆符号长整型。
pulseIn()
函数用于读取引脚脉冲的时间长度,脉冲可以是 HIGH 或 LOW。如果是 HIGH,函数将先等引脚变为高电平,然后开始计时,一直到变为低电平为止。返回脉冲持续的时间长短, 单位为 ms。如果超时还没有读到的话, 将返回 0。
1. 超声波测距
该程序的功能是通过超声波模块测算距离并打印在命令行中,代码如下:
// 定义超声波模块引脚
#define TRIG 27
#define ECHO 14
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
void loop() {
// 清除trigPin
digitalWrite(TRIG, LOW);
delay(5);
// 将trigPin设置为HIGH状态10微秒
digitalWrite(TRIG, HIGH);
delay(10);
digitalWrite(TRIG, LOW);
// 读取echoPin,返回声波传播时间(微秒)
float time = pulseIn(ECHO, HIGH);
// 计算距离
float distance = time * 0.3432 / 2;
Serial.print("距离: ");
Serial.print(distance);
Serial.println("mm");
delay(100);
}
2. 倒车雷达系统
最后,我们可以根据获取的距离来实现倒车雷达的效果,距离近的时候蜂鸣器会报警,LED 闪烁,随着距离越来越近,蜂鸣器发生频率与 LED 的闪烁频率都会越来越频繁,代码如下:
#define TRIG 27
#define ECHO 14
#define LED 2
#define BUZZER 15
int delay_time;
void setup() {
Serial.begin(9600);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
// 将 LED 与蜂鸣器设置为低电平
digitalWrite(LED, LOW);
digitalWrite(BUZZER, LOW);
}
void loop() {
// 清除trigPin
digitalWrite(TRIG, LOW);
delay(5);
// 将trigPin设置为HIGH状态10微秒
digitalWrite(TRIG, HIGH);
delay(10);
digitalWrite(TRIG, LOW);
// 读取echoPin,返回声波传播时间(微秒)
float time = pulseIn(ECHO, HIGH);
// 计算距离
float distance = time * 0.3432 / 2;
Serial.print("距离: ");
Serial.print(distance);
Serial.println("mm");
// 距离过近则报警
if (distance < 200) {
delay_time = int(distance);
Serial.println(delay_time);
digitalWrite(LED, HIGH);
digitalWrite(BUZZER, HIGH);
delay(delay_time);
digitalWrite(LED, LOW);
digitalWrite(BUZZER, LOW);
delay(delay_time);
} else {
digitalWrite(LED, LOW);
digitalWrite(BUZZER, LOW);
delay(100);
}
}