本文主要是介绍树莓派使用WiringPi库配合时间函数实现超声波测距,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
树莓派使用WiringPi库配合时间函数实现超声波测距
文章目录
- 树莓派使用WiringPi库配合时间函数实现超声波测距
- 一、HR-04超声波模块原理
- 1.1 超声波测距原理:
- 1.2 超声波时序图:
- 二、树莓派与超声波模块硬件连接
- 三、时间函数
- 3.1 时间函数gettimeofday()原型和头文件:
- 四、实现超声波测距
- 4.1 使用wiringOP库和时间函数实现超声波测距:
- 五、实现超声波测距并触发警报
- 5.1 硬件接线:
- 5.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):
一、HR-04超声波模块原理
1.1 超声波测距原理:
-
让它发送波:给Trig端口至少10us的高电平
-
开始发送波:Echo信号由低电平跳转到高电平
-
接收返回波:Echo信号由高电平跳转回低电平
-
计算时间 :Echo引脚维持高电平的时间!
-
开始发送波,启动定时器,接收到返回波,停止计时器
-
计算距离 :测试距离=(高电平时间*声速(340m/s))/2
1.2 超声波时序图:
二、树莓派与超声波模块硬件连接
三、时间函数
3.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 系统调用,用于获取当前的时间(包括秒和微秒)和时区信息(尽管时区信息在大多数现代系统中可能不太常用)
*/
四、实现超声波测距
4.1 使用wiringOP库和时间函数实现超声波测距:
#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>
#include <unistd.h>#define TRIG 2 //定义超声波的TRIG引脚为2
#define ECHO 3 //定义超声波的ECHO引脚为3void SR04_GPIO_Init() //初始化GPIO
{pinMode(TRIG, OUTPUT); //设置TRIG引脚为输出模式pinMode(ECHO, INPUT); //设置ECHO引脚为输入模式
}void sendTriggerPulse() //发送触发脉冲
{digitalWrite(TRIG, LOW); //拉低TRIG引脚usleep(2); //延时2微秒 digitalWrite(TRIG, HIGH); //拉高TRIG引脚usleep(10); //延时10微秒digitalWrite(TRIG, LOW); //拉低TRIG引脚
}double getDistance() //获取超声波距离
{double distance; //定义距离变量struct timeval Start; //定义开始时间变量struct timeval Stop; //定义结束时间变量sendTriggerPulse(); //发送触发脉冲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); distance = (double)diffTime/1000000 * 34000 / 2; //计算距离(单位:厘米)return distance; //返回距离值
}int main()
{double dis; //定义距离变量if(wiringPiSetup() == -1){ //初始化wiringPi库printf("初始化wiringPi库失败!\n");return -1;}SR04_GPIO_Init(); //初始化GPIOwhile(1){dis = getDistance(); //获取超声波距离printf("当前超声波距离为:%.2f cm\n",dis);usleep(500000); //没500ms采集一次}return 0;
}
五、实现超声波测距并触发警报
5.1 硬件接线:
5.2 实现超声波测距(距离小于10cm时蜂鸣器发出警报):
#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>
#include <unistd.h>#define TRIG 2 //定义超声波的TRIG引脚为2
#define ECHO 3 //定义超声波的ECHO引脚为3
#define BEEP 7 //定义蜂鸣器的引脚为7void SR04_BEEP_SGPIO_Init() //初始化GPIO
{pinMode(TRIG, OUTPUT); //设置TRIG引脚为输出模式pinMode(ECHO, INPUT); //设置ECHO引脚为输入模式pinMode(BEEP, OUTPUT); //设置BEEP引脚为输出模式
}void sendTriggerPulse() //发送触发脉冲
{digitalWrite(TRIG, LOW); //拉低TRIG引脚usleep(2); //延时2微秒 digitalWrite(TRIG, HIGH); //拉高TRIG引脚usleep(10); //延时10微秒digitalWrite(TRIG, LOW); //拉低TRIG引脚
}double getDistance() //获取超声波距离
{double distance; //定义距离变量struct timeval Start; //定义开始时间变量struct timeval Stop; //定义结束时间变量sendTriggerPulse(); //发送触发脉冲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); distance = (double)diffTime/1000000 * 34000 / 2; //计算距离(单位:厘米)return distance; //返回距离值
}int main()
{double dis; //定义距离变量if(wiringPiSetup() == -1){ //初始化wiringPi库printf("初始化wiringPi库失败!\n");return -1;}SR04_BEEP_SGPIO_Init(); //初始化GPIOwhile(1){dis = getDistance(); //获取超声波距离printf("当前超声波距离为:%.2f cm\n",dis);usleep(500000); //没500ms采集一次if(dis < 10){ //如果距离小于10cm,则蜂鸣器发出警报printf("警报!超声波距离为:%.2f cm\n",dis);digitalWrite(BEEP, LOW); delay(200);digitalWrite(BEEP, HIGH);}else{digitalWrite(BEEP, HIGH); //超声波距离大于10cm,则关闭蜂鸣器}}return 0;
}
这篇关于树莓派使用WiringPi库配合时间函数实现超声波测距的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!