HC-SR04
测距原理:
超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度,计算出模块到前方障碍物的距离
接线参考:
模块除了两个电源引脚外,还有TRIG,ECHO引脚
步骤:
怎么让它发波
Trig,给Trig端口至少10us的高电平
怎么知道开始发了
Echo信号,由低电平跳转到高电平,表示开始发送波
怎么知道接收了返回波
Echo,由高电平跳转回低电平,表示波回来了
怎么算时间
Echo引脚维持高电平的时间!
波发出去的那一下,开始启动定时器
波回来的那一下,我们开始停止定时器,计算出中间经过多少时间
怎么算距离
距离=速度(340m/s)*时间/2
时间函数
我们需要先学会求时间,才能算出距离,先来了解一下时间函数
函数原型
#include<sys/time.h>
int gettimeofday(struct timeval *tv,struct timezone *tz )
gettimeofday()会把目前的时间用tv 结构体返回,当地时区的信息则放到tz所指的结构中
对应的结构体:
struct timeval
{
long tc_sec; //秒
long tc_usec; //微秒
};
// 注意这里获得的时间是与1970年1月1日0时0分0秒的差值
1970年1月1日0时0分0秒是世界协调时间(UTC)的起始时间点,也被称为UNIX纪元(Unix Epoch)。UNIX操作系统及其衍生系统(如Linux)使用这个时间点作为计时的起点。
case1:简单使用
1 #include<stdio.h>
2 #include<sys/time.h>
3 //int gettimeofday(struct timeval *tv,struct timezone *tz )
4
5
6 int main()
7 {
8 struct timeval st;
9 gettimeofday(&st,NULL);
10
11 printf("sec: %ld usec: %ld\n",st.tv_sec,st.tv_usec);
12
13 return 0;
14 }
15
---------------------------------
case2: 计算 数100000的耗时,单位毫秒
1 #include<stdio.h>
2 #include<sys/time.h>
3 //int gettimeofday(struct timeval *tv,struct timezone *tz )
4
5 void cntTime()
6 {
7 int i,j;
8 for(i=0;i<100;++i)
9 for(j=0;j<1000;++j);
10
11 }
12
13 int main()
14 {
15 struct timeval st;
16
17 struct timeval ed;
18 gettimeofday(&st,NULL);
19 cntTime();
20 gettimeofday(&ed,NULL);
21
22 long diffTime= (1000000*(ed.tv_sec-st.tv_sec))+(ed.tv_usec-st.tv_usec);
23 printf("diffTime: %ld\n",diffTime);
24
25 return 0;
26 }
27
=======================================================
实现超声波测距:
pinMode(TRIG,OUTPUT); -- 对应 digitalWrite(TRIG,LOW);
pinMode(ECHO,INPUT); --对应digitalRead() -- 读取电平,不需要传参
输出 -- 写入 --> 这个管教输出信息,写入到板子中
输入 -- 读取 --> 这个管教输入信息,板子负责读取
分析时序图:

Trig:
A点前: 电平是从低开始
A~B: 高电平 -- 10us持续
B之后: 低电平
对应实现:
digitalWrite(TRIG,LOW); // A点前
usleep(5);digitalWrite(TRIG,HIGH); //A~B
usleep(10); // 高电平持续10us
digitalWrite(TRIG,LOW); //B之后
Echo:
在超声波发出之前一直是低电平
发出后开始计时 --st
返回停止计时 -- ed
对应代码实现:
while(!digitalRead(ECHO)); // st 之前一直读到低电平
gettimeofday(&st,NULL);//开始计时 -- 记录开始时间
while(digitalRead(ECHO)); //st~ed直接一直是高电平
gettimeofday(&ed,NULL);//停止计时 -- 记录结束时间
计算时间和距离:
时间 long diffTime=1000000*(ed.tv_sec-st.tv_sec)+(ed.tv_usec-st.tv_usec);
距离 dis=(double)diffTime/1000000 *34000/2;
( 不强转double可能出不完1000000,得到0,干扰最终结果
单位 cm/s /2 -- 得到的是来回距 离,实际距离 要/2 )
代码实现:
#include<stdio.h>
#include<unistd.h>
#include<wiringPi.h>
#include<stdlib.h>
#include<sys/time.h>
#define TRIG 0
#define ECHO 1double getDistance()
{double dis;
struct timeval st;
struct timeval ed;
pinMode(TRIG,OUTPUT); // 设置模式为输出 --Trig
pinMode(ECHO,INPUT);// 设置模式为输出 --Echo
digitalWrite(TRIG,LOW); //给引脚设置电平
usleep(5);digitalWrite(TRIG,HIGH);
usleep(10);
digitalWrite(TRIG,LOW);while(!digitalRead(ECHO));
gettimeofday(&st,NULL);
while(digitalRead(ECHO));
gettimeofday(&ed,NULL);long diffTime=1000000*(ed.tv_sec-st.tv_sec)+(ed.tv_usec-st.tv_usec);
dis=(double)diffTime/1000000 *34000/2;
return dis;
}int main()
{
double dis;if(wiringPiSetup()==-1){// 初始化 wiringpi,失败返回-1
fprintf(stderr,"%s","initwiringPi error");
exit(-1);}
while(1){
dis =getDistance();
printf("dis = %lf\n",dis);
usleep(500000);
}return 0;
}

被折叠的 条评论
为什么被折叠?



