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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/747417.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

经验分享,免费商标查询网站

有时候想快速查询商标状况&#xff0c;官方网站比较慢&#xff0c;这里分享一个免费快速的网站。 网址&#xff1a;https://www.sscha.com/ 截图&#xff1a;

platform 设备驱动实验

platform 设备驱动实验 Linux 驱动的分离与分层 代码的重用性非常重要&#xff0c;否则的话就会在 Linux 内核中存在大量无意义的重复代码。尤其是驱动程序&#xff0c;因为驱动程序占用了 Linux内核代码量的大头&#xff0c;如果不对驱动程序加以管理&#xff0c;任由重复的…

电脑没声音是什么原因?一篇文章帮你解决疑惑

在使用电脑时&#xff0c;声音是至关重要的一部分&#xff0c;无论是播放音乐、观看视频还是进行视频会议。然而&#xff0c;有时候电脑可能会出现没声音的情况&#xff0c;这让人感到非常困扰。那么电脑没声音是什么原因呢&#xff1f;本文将详细介绍解决电脑没声音问题的三种…

【Java Web】XML格式文件

目录 一、XML是什么 二、常见配置文件类型 *.properties类型&#xff1a; *.xml类型&#xff1a; 三、DOM4J读取xml配置文件 3.1 DOM4J的使用步骤 3.2 DOM4J的API介绍 一、XML是什么 XML即可扩展的标记语言&#xff0c;由标记语言可知其基本语法和HTML一样都是由标签构成的文件…

仓库管理系统12--物资设置供应商设置

1、添加供应商窗体 2、布局控件UI <UserControl x:Class"West.StoreMgr.View.SupplierView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://…

VLM系列文章1-LLaVA

作为VLM系列的第一篇文章&#xff0c;打算以LLaVA入手&#xff0c;毕竟是VLM领域较为经典的工作。 1. 核心贡献 多模态指令跟随数据&#xff1a;包括PT、SFT数据的构造流程&#xff1b;大型多模态模型&#xff1a;一种新的框架&#xff0c;结构较为简单高效&#xff1b;评估数…

深入了解 GPT-4 和 ChatGPT 的 API---使用 OpenAI Python 库

文章目录 OpenAI 访问权限和 API 密钥Hello World 示例程序使用 GPT-4 和 ChatGPTChatCompletion 端点的输入选项ChatCompletion 端点的输出格式 OpenAI 将 GPT-4 和 ChatGPT 作为服务提供。这意味着用户无法直接访问模型代码&#xff0c;也无法在自己的服务器上运行这些模型。…

牛客周赛 Round 48 解题报告 | 珂学家

前言 题解 这场感觉有点难&#xff0c;D完全没思路, EF很典&#xff0c;能够学到知识. E我的思路是容斥贡献&#xff0c;F很典&#xff0c;上周考过一次&#xff0c;引入虚拟节点质数(有点像种类并查集类似的技巧). 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 …

【第十八课】区域经济分析——探索性空间数据分析软件实操

一、前言 ArcGIS有专门处理探索性空间数据分析方法的工具,即地统计分析模块。 该模块主要由三个功能模块组成:探索性数据分析(Explore)、地统计分析向导(Geostatistical Wizard),以及生成数据子集(Create Subsets)。其中利用 这些基本功能模块,可以方便完成多种地统…

Thinkphp/Laravel高校竞赛管理系统的设计与实现_9pi7u

高校竞赛管理&#xff0c;其工作流程繁杂、多样、管理复杂与设备维护繁琐。而计算机已完全能够胜任高校竞赛管理工作&#xff0c;而且更加准确、方便、快捷、高效、清晰、透明&#xff0c;它完全可以克服以上所述的不足之处。这将给查询信息和管理带来很大的方便&#xff0c;从…

【Qt】Qt多线程编程指南:提升应用性能与用户体验

文章目录 前言1. Qt 多线程概述2. QThread 常用 API3. 使用线程4. 多线的使用场景5. 线程安全问题5.1. 加锁5.2. QReadWriteLocker、QReadLocker、QWriteLocker 6. 条件变量 与 信号量6.1. 条件变量6.2 信号量 总结 前言 在现代软件开发中&#xff0c;多线程编程已成为一个不可…

数字图像分析(第三部分)

文章目录 第11章 基于概率图模型的图像分析概率有向图模型因子分解生成式模型链式图条件独立性有向图模型的马尔科夫毯概率无向图模型模型定义概率无向图模型的因子分解条件随机场条件随机场的定义条件随机场的预测算法第12章 运动分析运动相机建模光流运动表达方法运动估计准则…

AI软件革新文本操作体验:从自动粘贴文本到一键提取保存手机号码

在当今数字化时代&#xff0c;AI技术的快速发展为各行各业带来了革命性的变革。特别是在文本处理领域&#xff0c;AI软件通过其强大的自动粘贴文本功能以及一键提取并保存手机号码的便捷操作&#xff0c;极大地提高了工作效率&#xff0c;为用户带来了全新的体验。本文将深入探…

CSS 文本输入框右下角的尺寸控件(三斜线:-webkit-resizer)消除,以及如何配置其样式,添加 resize 让标签元素可进行拖拽放大。

前言&#xff1a;在日常的前端开发中&#xff0c;不管是原始的和 还在在各类组件库中的文本输入框中&#xff0c;元素内容的右下角总是有一个三斜线的样式&#xff0c;本文简单了解它是什么&#xff1f;如何去控制并修改样式&#xff1f; 一、它是&#xff1f; 这三个斜线其实…

v0.9.6 开源跨平台个人知识管理工具 TidGi-Desktop

在这个信息爆炸的时代&#xff0c;知识管理变得尤为重要。太记(TidGi)&#xff0c;一款基于太微(TiddlyWiki)的知识管理桌面应用&#xff0c;正是为了满足人们对信息整理、知识管理和个人隐私保护的需求而设计的。它不仅能够帮助用户高效地管理和整理信息&#xff0c;还能够自动…

简化部署流程——无线UWB如何实现自标定?

一.什么是UWB信标自标定&#xff1f; UWB&#xff08;超宽带&#xff09;自标定是指在UWB系统中&#xff0c;基站或节点能够自动识别和确定自己的位置&#xff0c;无需外部干预或手动输入其地理位置信息。这种技术主要利用系统内部的信号测量和算法来自动计算节点之间的距离以…

使用PEFT库进行ChatGLM3-6B模型的LORA高效微调

PEFT库进行ChatGLM3-6B模型LORA高效微调 LORA微调ChatGLM3-6B模型安装相关库使用ChatGLM3-6B模型GPU显存占用准备数据集加载模型加载数据集数据处理数据集处理配置LoRA配置训练超参数开始训练保存LoRA模型模型推理从新加载合并模型使用微调后的模型 LORA微调ChatGLM3-6B模型 本…

【vue】vue响应式原理

vue响应式原理 vue2的响应式原理 vue2对对象类型的监听是通过Object.defineProperty实现的&#xff0c;给想要实现响应式的数据对象每个属性加上get,set方法&#xff0c;以实现数据劫持的操作。而对数组类型的监听是通过重写数组的方法实现的。 Object.defineProperty的定义…

组合数学、圆排列、离散数学多重集合笔记

自用 如果能帮到您&#xff0c;那也值得高兴 知识点 离散数学经典题目 多重集合组合 补充容斥原理公式 隔板法题目 全排列题目&#xff1a;

机械拆装-基于Unity-准备零件

目录 前言 1. 装配体模型的准备&#xff08;STEP格式保存为零件&#xff09; 1.1 关于不停提示“默认模板无效” 1.2 关于无法保存单个零件的解决 2. 整理装配体与零件 2.1 零件命名规则 2.2 建立子装配体 3. 装配体和零件转换格式 3.1 3DMax单位设置 3.2 装配体转换 3.3…