测距原理:
声波在空气中速度 =340m/s
超声波模块:
HC-SR04 的测距过程
1. 树莓派向 Trig 脚发送一个持续 10us 的脉冲信号。
2. HC-SR04 接收到树莓派发送的脉冲信号,开始发送超声波,并把 Echo置为高电平。 然后准备接收返回的超声波。
3. 当 HC-SR04 接收到返回的超声波时,把 Echo 置为低电平。
从上述过程可以看出, Echo 高电平持续的时间就是超声波从发射到返回所经过的时间间隔。
用到的一些函数:
#include<sys/time.h>
timeval
{
time_t tv_sec; //秒 [long int]
suseconds_t tv_usec; //微秒 [long int]
};
#include <sys/time.h>
int gettimeofday(struct timeval*tv, struct timezone *tz);
其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果:
struct timezone{
int tz_minuteswest; //格林威治时间往西方的时差
int tz_dsttime; //DST 时间的修正方式
}
timezone 参数若不使用则传入NULL即可。
程序:
#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>
#define Trig 0
#define Echo 1
void ultraInit() //设置管脚
{
pinMode(Echo,INPUT);
pinMode(Trig,OUTPUT);
}
float disMeasure(){
struct timeval tv1;
struct timeval tv2;
long start,stop;
float dis;
digitalWrite(Trig,LOW);
delayMicroseconds(2); //Trig 置0
digitalWrite(Trig,HIGH);
delayMicroseconds(10);
digitalWrite(Trig,LOW);//Trig 拉高 10us
while(!(digitalRead(Echo)==1));
gettimeofday(&tv1,NULL); //start time
while(!(digitalRead(Echo)==0));
gettimeofday(&tv2,NULL); //stop time
start=tv1.tv_sec*1000000+tv1.tv_usec;
stop=tv2.tv_sec*1000000+tv2.tv_usec;//微妙级时间
dis=(float)(stop-start)/1000000*34000/2;
return dis;
}
int main(){
float dis;
if(wiringPiSetup()==-1){ //初始化wiringPi
printf("setup wiringPi failed\n");
return -1;
}
ultraInit();
while(1)
{
dis=disMeasure();
printf("distance =%0.2f cm\n",dis);
delay(1000);
}
return 0;
}
运行结果: