问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

超声波测距原理与代码实现详解

创作时间:
作者:
@小白创作中心

超声波测距原理与代码实现详解

引用
CSDN
1.
https://blog.csdn.net/qq_59510647/article/details/138501586

超声波测距是一种常见的测距技术,广泛应用于机器人、自动化设备等领域。本文将详细介绍HC-SR04超声波测距模块的工作原理、接线方式以及具体的代码实现,帮助读者快速掌握这一实用技术。

超声波测距

1. 测距原理基本说明

超声波测距模块通过发送和接收超声波,利用时间差和声音传播速度,计算出模块到前方障碍物的距离。HC-SR04是常用的超声波测距模块型号,除了两个电源引脚外,还有TRIG(触发)和ECHO(回声)两个信号引脚。

2. 接线方式

  • VCC接5V电源
  • GND接地
  • TRIG接GPIO 0
  • ECHO接GPIO 1

发波与接收原理

  • 发波:给TRIG端口至少10us的高电平
  • 开始发波判断:ECHO信号由低电平跳转到高电平
  • 接收返回波判断:ECHO信号由高电平跳转回低电平
  • 时间计算:ECHO引脚维持高电平的时间
  • 距离计算:距离 = 速度(340m/s)* 时间 / 2

3. 时序图

(时序图部分原文未提供具体内容,可以补充相关时序图以增强理解)

4. 时间函数

在Linux系统中,可以使用gettimeofday函数获取高精度时间。该函数原型如下:

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

其中,struct timeval结构体定义如下:

struct timeval {
    long tv_sec; /* 秒 */
    long tv_usec; /* 微秒 */
};

下面是一个测试代码示例,用于计算程序在当前环境中数数10万次耗时:

#include <sys/time.h>
#include <stdio.h>

void mydelay() {
    int i, j;
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 1000; j++);
    }
}

int main() {
    struct timeval startTime;
    struct timeval stopTime;

    gettimeofday(&startTime, NULL);
    mydelay();
    gettimeofday(&stopTime, NULL);

    long diffTime = 1000000 * (stopTime.tv_sec - startTime.tv_sec) + (stopTime.tv_usec - startTime.tv_usec);

    printf("全志H6的Linux数100000耗时%ldus\n", diffTime);
    return 0;
}

5. 代码实现和验证

下面是完整的超声波测距代码实现:

#include <stdio.h>
#include <sys/time.h>
#include <wiringPi.h>
#include <stdlib.h>
#include <unistd.h>

#define Trig 0 // 定义触发引脚为GPIO 0
#define Echo 1 // 定义回声引脚为GPIO 1

// 函数用于测量距离并返回以厘米为单位的值
double getDistance() {
    double dis;
    struct timeval start;
    struct timeval stop;

    pinMode(Trig, OUTPUT);
    pinMode(Echo, INPUT);

    digitalWrite(Trig, LOW);
    usleep(5);

    digitalWrite(Trig, HIGH);
    usleep(10);
    digitalWrite(Trig, LOW);

    while (!digitalRead(Echo));
    gettimeofday(&start, NULL);
    while (digitalRead(Echo));
    gettimeofday(&stop, NULL);

    long diffTime = 1000000 * (stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec);
    printf("diffTime = %ld\n", diffTime);
    dis = (double)diffTime / 1000000 * 34000 / 2;

    return dis;
}

int main() {
    double dis;
    if (wiringPiSetup() == -1) {
        fprintf(stderr, "%s", "initWringPi error");
        exit(-1);
    }

    while (1) {
        dis = getDistance();
        printf("dis = %lf\n", dis);
        usleep(500000);
    }
    return 0;
}

5.1 验证结果

(验证结果部分原文未提供具体内容,可以补充实际测试数据或现象描述)

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号