Orangepi Zero2使用外设驱动库wiringOP配合时间函数驱动HC-SR04超声波测距模块

目录

一、HC-SR04超声波模块原理和硬件接线

1.1 超声波测距原理:

1.2 超声波时序图:

1.3 HC-SR04超声波模块硬件接线:

二、时间函数

2.1 时间函数gettimeofday()原型和头文件:

2.2 使用gettimeofday()函数获取当前时间的秒数和微妙数:

2.3 使用gettimeofday()函数计算全志H616数10万次的耗时:

三、实现超声波测距

3.1 使用wiringOP库和时间函数实现超声波测距:

3.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):


一、HC-SR04超声波模块原理和硬件接线

1.1 超声波测距原理:

  • 让它发送波:给Trig端口至少10us的高电平

  • 开始发送波:Echo信号由低电平跳转到高电平

  • 接收返回波:Echo信号由高电平跳转回低电平

  • 计算时间 :Echo引脚维持高电平的时间

  • 开始发送波,启动定时器,接收到返回波,停止计时器

  • 计算距离 :测试距离=(高电平时间*声速(340m/s))/2

1.2 超声波时序图:

1.3 HC-SR04超声波模块硬件接线:

  • 超声波的VCC接到板子上的5V

  • 超声波的GND接到板子上的GND

  • 超声波的Trig口对应的物理引脚的3号,其对应的wPi的第0号

  • 超声波的Echo口对应的物理引脚的5号,其对应的wPi的第1号

二、时间函数

2.1 时间函数gettimeofday()原型和头文件:

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

int 					函数返回值,如果成功,gettimeofday 返回 0。如果失败,它返回 -1 并设置 errno 以指示错误。
    
struct timeval *tv		这是一个指向 timeval 结构体的指针,该结构体用于存储当前时间。timeval 的定义如下:
    
struct timeval {  
        time_t      tv_sec;   /* 秒 */  
        suseconds_t tv_usec;  /* 微秒 */  
};

time_t      tv_sec		是一个整数,表示自 Unix 纪元(1970年1月1日 00:00:00 UTC)以来的秒数。
suseconds_t tv_usec		是一个整数,表示微秒数(0 到 999,999)。

struct timezone *tz		这是一个指向 timezone 结构体的指针,用于存储时区信息。但在现代系统中,这个参数通常被忽略,因为大多					      数系统都使用 UTC 时间,并且不再使用本地时区偏移。这个参数我们通常设置为NULL

/*函数说明:
gettimeofday 是一个 Unix 和 Linux 系统调用,用于获取当前的时间(包括秒和微秒)和时区信息(尽管时区信息在大多数现代系统中可能不太常用)
*/

2.2 使用gettimeofday()函数获取当前时间的秒数和微妙数:

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

int main()
{
    struct timeval tv;

    //int gettimeofday(struct timeval *tv, struct timezone *tz);
    if(gettimeofday( &tv, NULL) == 0){                              //获取当前时间的秒数和微妙数
        printf("自1970-01-01 00:00:00的秒数:%ld\n",tv.tv_sec);
        printf("微妙:%ld\n",tv.tv_usec);
    }else{
        perror("gettimeofday");                                     //打印出错信息
    }
    return 0;
}

2.3 使用gettimeofday()函数计算全志H616数10万次的耗时:

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

void cntTest()                      //全志H616数数十万次
{
    int i;
    int j;

    for(i=0; i<100; i++)
        for(j=0; j<1000; j++);
}

int main()
{
    struct timeval timeStart;       
    struct timeval timeStop;
    long diffTime;

    //int gettimeofday(struct timeval *tv, struct timezone *tz);
    gettimeofday( &timeStart, NULL);    //获取数数之前的时间
    cntTest();                          //数数十万次
    gettimeofday( &timeStop, NULL);     //获取数数之后的时间

    //秒之所以要乘以1000000是因为后面加了微妙,所以要将秒转化为微秒						//获取数数十万次的时间
    diffTime = 1000000 * (timeStop.tv_sec - timeStart.tv_sec) + (timeStop.tv_usec - timeStart.tv_usec); 
    printf("全志H616数10万次耗时:%ldus\n",diffTime);
    return 0;
}

三、实现超声波测距

3.1 使用wiringOP库和时间函数实现超声波测距:

#include <stdio.h>                  // 包含标准输入输出库头文件
#include <sys/time.h>               // 包含时间相关函数的头文件
#include <wiringPi.h>               // 包含wiringPi库的头文件,用于GPIO控制
#include <unistd.h>                 // 包含标准库函数,如sleep
#include <stdlib.h>                 // 包含标准库函数,如malloc和free

#define Trig 0                      // 定义Trig引脚为0
#define Echo 1                      // 定义Echo引脚为1

void startHC()
{
    digitalWrite(Trig, LOW);        //给Trig端口发送低电平信号    
    usleep(5);                                                                                   
    digitalWrite(Trig, HIGH);       //给Trig端口发送高电平信号 
    usleep(10);                                                                                                 
    digitalWrite(Trig, LOW);        //给Trig端口发送低电平信号    
}

double getDistance()
{
    double dis;                     //距离

    struct timeval Start;           //开始时间  
    struct timeval Stop;            //结束时间

    startHC();                      //给Trig端口10us的高电平
    while(!digitalRead(Echo));      //Echo信号由低电平跳转到高电平
    gettimeofday(&Start, NULL);     //获取时间
    while(digitalRead(Echo));       //Echo信号由高电平跳转回低电平
    gettimeofday(&Stop, NULL);      //获取时间

    long diffTime = 1000000 * (Stop.tv_sec - Start.tv_sec) + (Stop.tv_usec - Start.tv_usec);  //计算时间差   
    dis = (double)diffTime/1000000 * 34000 / 2;                                              //计算距离            
    
    return dis;
}

int main()
{
    double dis;                                     //距离

    if(wiringPiSetup() == -1){                      //初始化wiringPi库
        printf("初始化wiringPi库失败\n");
        exit(-1);
    }                                

    pinMode(Trig, OUTPUT);                          //设置超声波Trig引脚为输出模式
    pinMode(Echo, INPUT);                           //设置超声波Echo引脚为输入模式

    while(1){
        dis = getDistance();                        //获取超声波距离
        printf("当前超声波距离是:%.2lf\n",dis);
        usleep(500000);                             //每500ms获取一次
    }
    return 0;
}

3.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):

#include <stdio.h>                  // 包含标准输入输出库头文件
#include <sys/time.h>               // 包含时间相关函数的头文件
#include <wiringPi.h>               // 包含wiringPi库的头文件,用于GPIO控制
#include <unistd.h>                 // 包含标准库函数,如sleep
#include <stdlib.h>                 // 包含标准库函数,如malloc和free

#define Trig 0                      // 定义Trig引脚为0
#define Echo 1                      // 定义Echo引脚为1
#define Beep 2                      // 定义Beep引脚为2

void startHC()
{
    digitalWrite(Trig, LOW);        //给Trig端口发送低电平信号    
    usleep(5);                                                                                   
    digitalWrite(Trig, HIGH);       //给Trig端口发送高电平信号 
    usleep(10);                                                                                                 
    digitalWrite(Trig, LOW);        //给Trig端口发送低电平信号    
}

double getDistance()
{
    double dis;                     //距离

    struct timeval Start;           //开始时间  
    struct timeval Stop;            //结束时间

    startHC();                      //给Trig端口10us的高电平
    while(!digitalRead(Echo));      //Echo信号由低电平跳转到高电平
    gettimeofday(&Start, NULL);     //获取时间
    while(digitalRead(Echo));       //Echo信号由高电平跳转回低电平
    gettimeofday(&Stop, NULL);      //获取时间

    long diffTime = 1000000 * (Stop.tv_sec - Start.tv_sec) + (Stop.tv_usec - Start.tv_usec);  //计算时间差   
    dis = (double)diffTime/1000000 * 34000 / 2;                                              //计算距离            
    
    return dis;
}

int main()
{
    double dis;                                     //距离

    if(wiringPiSetup() == -1){                      //初始化wiringPi库
        printf("初始化wiringPi库失败\n");
        exit(-1);
    }                                

    pinMode(Trig, OUTPUT);                          //设置超声波Trig引脚为输出模式
    pinMode(Echo, INPUT);                           //设置超声波Echo引脚为输入模式
    pinMode(Beep, OUTPUT);                          //设置蜂鸣器Beep引脚为输出模式

    while(1){
        dis = getDistance();                        //获取超声波距离
        printf("当前超声波距离是:%.2lf\n",dis);
        usleep(500000);                             //每500ms获取一次
        if(dis < 10){                              //当距离小于10cm时,蜂鸣器发出警报){
            printf("警报!当前距离:%.2lf\n",dis);
            digitalWrite(Beep, LOW);               //打开蜂鸣器
            usleep(500000);                         //延时500ms
            digitalWrite(Beep, HIGH);              //关闭蜂鸣器
        }else{
            digitalWrite(Beep, HIGH);              //关闭蜂鸣器
        }                                        
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值