超声波测距

罗大富 BigRich大约 5 分钟ESP32Arduino

本节课来学习使用 Arduino 控制超声波传感器并获取距离数据,最终搭配一个蜂鸣器实现倒车雷达的效果。

实验原理

超声波是一种频率高于 20000Hz 的声波,超声波的方向性好,反射能力强,易于获得较集中的声能,在水中传播距离比空气中远,可用于测距、测速、清洗、焊接、碎石、杀菌消毒等。

超声波可用于许多不同的领域。超声波设备用于检测物体和测量距离。超声成像或超声检查常用于医学。在产品和结构的无损检测中,超声波用于检测不可见的缺陷。在工业上,超声波用于清洁、混合和加速化学过程。蝙蝠和鼠海豚等动物使用超声波来定位猎物和障碍物。

本实验使用的超声波模块为 HC-SR04 超声波传感器,其原理为利用超声波在遇到障碍物后反射,结合声波在空气中的传播速度,可以得出传播的距离。该模块外观如下图所示:

超声波传感器使用声纳来确定与物体的距离。我们使用的超声波模块由 2 个超声波探头组成:

  1. T:表示 Transmitter(发射),负责发送超声波信号;
  2. R:表示 Receiver(接收),负责接收回响信号;

注意

如果在使用过程中,对其中任意一个探头进行遮挡,都会使超声波无法正常测量距离。

底部有四个引脚:

  1. VCC:5V 供电引脚;
  2. GND:接地;
  3. TRIG:控制信号输入;
  4. 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
LED1
1KΩ 电阻1
超声波模块 HC-SR041
杜邦线(跳线)若干
面包板1
超声波模块1
202504151305948

软件程序设计

Arduino 提供一个测量脉冲时间长度的 pulseln() 函数,语法格式:

pulseIn(pin, value)
pulseIn(pin, value, timeout)

该函数将返回微秒 us 单位的脉冲时间也就是说 pulseIn() 测出来的是超声波从发射到接收所经过的时间。

参数说明如下:

  • Pin:需要读取脉冲的引脚;
  • value:需要读取的脉冲类型, HIGH 或 LOW
  • timeout:超时时间,单位微秒,数据类型为⽆符号长整型。

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);
  }
}

上次编辑于:
贡献者: Luo,罗大富BigRich