1 简介
Hi,大家好,今天向大家介绍一个学长做的单片机项目
基于单片机的超声波测距系统实现
大家可用于 课程设计 或 毕业设计
2 主要器件
主控:stm32
LCD显示屏
HC-SR04超声波模块
HC-SR04超声波模块,如下
3 实现效果
测量手到试验台的距离
4 设计原理
4.1 声波雷达原理
超声波也是声波,它在1个标准大气压下,15℃的空气中的传播速度为340m/s。而声波在传播的过程中遇到障碍物时,会反射也会衍射,所以当我们测量出发出声波和听到回声的时间差,就能估算出声音传播的距离。同时因为超声波频率高波长短,所以衍射低,拘束性好,因此能量衰减也更少,传播的距离也更长,更比耳朵能听到的低频率声音更适合做长距离测量。
测量步骤为:
- 发出n个mHz的超声波脉冲,超声波脉冲发射结束时开始计时,记作t0
- 开始监听mHz的超声波脉冲的回声,监听到n个后结束计时,记作t1
- 计算时间差t = t1 - t0,为超声波来回两程所花费的时间
- 计算超声波走过的距离s = v * (t1 - t0) / 2(v为声速)
声波速度与空气温度的关系
声波传播速度与传播介质的温度成正比,与传输介质的密度成正比。声波在1个标准大气压下的传播速度与空气温度的关系为:
v = 331.5 + 0.607t
v为声波的速度,单位m/s
t为空气的温度,单位℃
5 部分实现代码
代码流程
部分核心代码:
#define ULTRASONIC_ECHO_PIN 2
#define ULTRASONIC_TRIGGER_PIN 4
#define ULTRASONIC_DISCOVERING_STATE_PIN 13
#define ULTRASONIC_DISCOVERING_INTERVAL 500000
volatile bool mReadyToDiscovering = true;
unsigned long mEchoStartTime = 0;
unsigned long mEchoEndTime = 0;
float mDistance = 0.0f;
void trigger();
void calcDistance();
void onEcho();
bool isReadyToDiscovering();
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Ultrasonic ranging ready");
// UltraSonic pins setup
pinMode(ULTRASONIC_ECHO_PIN, INPUT);
pinMode(ULTRASONIC_TRIGGER_PIN, OUTPUT);
pinMode(ULTRASONIC_DISCOVERING_STATE_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(ULTRASONIC_ECHO_PIN), onEcho, CHANGE);
// UltraSonic pins initialization
digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
digitalWrite(ULTRASONIC_DISCOVERING_STATE_PIN, LOW);
}
void loop() {
if (isReadyToDiscovering()) {
calcDistance();
trigger();
}
}
bool isReadyToDiscovering() {
if (mReadyToDiscovering) {
unsigned long now = micros();
if (now - mEchoEndTime > ULTRASONIC_DISCOVERING_INTERVAL) {
mReadyToDiscovering = false;
return true;
}
}
return false;
}
void trigger() {
digitalWrite(ULTRASONIC_TRIGGER_PIN, HIGH);
delayMicroseconds(50);
digitalWrite(ULTRASONIC_TRIGGER_PIN, LOW);
}
void onEcho() {
uint8_t echo = digitalRead(ULTRASONIC_ECHO_PIN);
unsigned long now = micros();
if (echo == HIGH) {
mEchoStartTime = now;
digitalWrite(ULTRASONIC_DISCOVERING_STATE_PIN, HIGH);
} else {
mEchoEndTime = now;
digitalWrite(ULTRASONIC_DISCOVERING_STATE_PIN, LOW);
mReadyToDiscovering = true;
}
}
void calcDistance() {
long deltaTime = mEchoEndTime - mEchoStartTime;
mDistance = 340L * deltaTime / 2000000.0; // s = vt = 340 m/s * time / 2
Serial.print("Distance = ");Serial.print(mDistance * 100.0);Serial.print("cm, Time = ");Serial.print(deltaTime);Serial.println("us");
}