树莓派+超声波模块测距

本文介绍了如何使用树莓派结合超声波模块实现测距功能,详细解析了超声波模块的工作原理和接线方式,并展示了利用pinMode函数配置GPIO引脚。同时,讲解了structtimeval结构体和gettimeofday()函数在计算超声波测距时间上的应用,提供了完整的C语言示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

记录pinMode(pin,mode)函数,有时候搞不清。。

pinMode函数用于配置引脚为输入或者输出模式,它是一个无返回值的函数,一般放在setup()函数体重,先设置再使用。

pinMode函数由两个参数–pin 和 mode,pin参数表示要配置的引脚代号,以Arduino Uno为例,它的取值范围是013,也可以把模拟引脚(A0A5)作为数字引脚使用,此时编号为14脚到19脚。mode参数表示设置的模式——INPUT输入模式或者OUTPUT输出模式,其中INPUT用于读取信号,OUTPUT用于输出控制信号。

配置数字引脚3位输出模式的语句如下所示:

pinMode(3,OUTPUT);

准备材料

  1. 超声波模块
  2. 树莓派3b
  3. 杜邦线母对母
  4. 树莓派电源线

超声波模块介绍

参数

在这里插入图片描述

测距原理

在这里插入图片描述
工作原理:

1.超声波模块和单片机进行连接。
2.触发信号,给Trig引脚发送一个大于10us的高电平。
3.发送高电平后,模块会循环发送8个40KHZ的脉冲,与此同时Echo引脚会由低电平变成高电平,这时候就需要开启定时器开始计算Echo引脚的高电平时间,
4.模块接收到返回的超声波时,Echo电平会由高电平变成低电平,此时应该关闭定时器,这个时候的算出来的定时器的时间就是Echo持续的高电平,也就是超声波从发射到传回来的总时间。
5.(除去温度的影响)根据声速为340m/s,来计算(高电平时间 * 340m/s) / 2。 计算的时候注意自己使用定时器获得的时间的单位。记得换算。

接线:

Vcc:超声波模块电源脚,接5V电源
Trig:接收来自树莓派的控制信号,接 GPIO 口
Echo:发送测距结果给树莓派,接 GPIO 口
(值得注意的是:Echo 返回的是 5v信号,而树莓派的 GPIO 接收超过 3.3v 的信号可能会被烧毁,因此可以加一个分压电路)
Gnd:接地,接 0v

注意:
(1)超声波模块的VCC电源要接5V的,如果接3.3V,模块的测距数值会不正确,在同一个数值范围波动;
(2)此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作;
(3)测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果;

struct timeval结构体

#include <sys/time.h>//头文件

struct timeval
{
__time_t  tv_sec;        /* Seconds. */
__suseconds_t  tv_usec;  /* Microseconds. */
};

其中,tv_sec为Epoch到创建struct timeval时的秒数,tv_usec为微秒数

gettimeofday()函数

/* Get the current time of day and timezone information,
   putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
   Returns 0 on success, -1 on errors.
   NOTE: This form of timezone information is obsolete.
   Use the functions and variables declared in <time.h> instead. */
extern int gettimeofday (struct timeval *__restrict __tv,
                         __timezone_ptr_t __tz) __THROW __nonnull ((1));

gettimeofday() 功能是得到当前时间和时区,分别写到 tvtz 中,如果tzNULL 则不向 tz 写入。

demo示例

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

#define Trig 4
#define Echo 5

void initFunc(){
        pinMode(Trig,OUTPUT);   //初始化超声波
        pinMode(Echo,INPUT);
}

float ultraFunc(){

        float dis;
        long start;
        long end;
        struct timeval tv1;
        struct timeval tv2;

        digitalWrite(Trig,LOW);
        delayMicroseconds(2);
        digitalWrite(Trig,HIGH);
        delayMicroseconds(10);
        digitalWrite(Trig,LOW);

        while(digitalRead(Echo) != HIGH);   // HIGH(1),检测到高电平时跳出循环
        gettimeofday(&tv1, NULL);   // 获取时间(此为高电平开始时间)

        while(digitalRead(Echo) != LOW);   // LOW(0),检测到低电平跳出循环
        gettimeofday(&tv2, NULL);   // 获取时间(此为低电平开始时间,即为高电平结束时间)
        start = tv1.tv_sec * 1000000 + tv1.tv_usec;   // 单位(微秒)
        end = tv2.tv_sec * 1000000 + tv2.tv_usec;   // 单位(微秒)

        dis = (float)(end - start) / 1000000 * 34000 / 2;   // 距离计算(高电平时间 * 音速 / 2)

        return dis;
}


int main(){
        float dis;
        if(wiringPiSetup()==-1){
                printf("setup wiringPi failed\n");
                exit(-1);
        }
        initFunc();
        while(1){
                dis = ultraFunc();
                printf("距离:%0.3fcm\n",dis);
                delay(1000);
        }

        return 0;
}	

工作图:
在这里插入图片描述
运行结果:
在这里插入图片描述

### 实现 HCSR04 超声波传感器在树莓派上的测距功能 #### 硬件连接说明 HC-SR04 模块参数能够测量 3cm 至 4m 的距离,精确度可以达到 3mm[^4]。此模块包括超声波发射器、接收器以及控制电路三个主要组成部分,并配备四个引脚用于连接。 具体接线方法如下: - **VCC**:连接至 Raspberry Pi 的 5V 输出端口。 - **GND**:连接至 Raspberry Pi 地线 (GND)。 - **TRIG**:触发输入信号,建议连接到 BCM 编号体系下的 GPIO 引脚,例如 GPIO17。 - **ECHO**:回响输出信号,同样推荐连接到另一个可用的 GPIO 引脚,比如 GPIO27。 值得注意的是,虽然 VCC 和 GND 可以通过外部电源供电,但是为了确保最佳性能和稳定性,应当优先考虑利用 Raspberry Pi 或者其他微控制器单元(MCU)所提供的 GPIO 接口来供应电力。 #### Python编程实现 下面是一个简单的Python程序例子,展示了如何配置GPIO接口并与HC-SR04交互完成基本的距离测量任务: ```python import RPi.GPIO as GPIO import time # 设置使用的BCM编号模式 GPIO.setmode(GPIO.BCM) # 定义 TRIG 和 ECHO 引脚对应的BCM编号 PIN_TRIGGER = 17 PIN_ECHO = 27 def setup(): # 初始化引脚方向 GPIO.setup(PIN_TRIGGER, GPIO.OUT) GPIO.setup(PIN_ECHO, GPIO.IN) def measure_distance(): try: while True: # 发送低电平脉冲持续至少10us使能传感器准备状态 GPIO.output(PIN_TRIGGER, False) time.sleep(0.5) # 向TRIG发送一个短促的高电平脉冲启动一次测量周期 GPIO.output(PIN_TRIGGER, True) time.sleep(0.00001) GPIO.output(PIN_TRIGGER, False) pulse_start_time = None pulse_end_time = None # 记录ECHO首次变为高的时刻作为起始时间戳 while GPIO.input(PIN_ECHO)==0: pulse_start_time = time.time() # 当ECHO再次变回到低的时候记录结束的时间戳 while GPIO.input(PIN_ECHO)==1: pulse_end_time = time.time() if pulse_start_time is not None and pulse_end_time is not None: duration = pulse_end_time - pulse_start_time distance = round(duration * 17150, 2) print(f"Distance: {distance} cm") finally: GPIO.cleanup() if __name__ == '__main__': setup() measure_distance() ``` 这段代码首先设置了必要的GPIO引脚为输出或输入模式,接着在一个无限循环内执行以下操作:先让`TRIG`保持一段时间的低电平以便初始化传感器;随后发出短暂的高电平脉冲激活测量过程;最后监听`ECHO`的变化情况计算往返时间从而得出目标物离传感器的实际距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石子君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值