wiringpi 库的应用 -- 超声波测距HC-SR04

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 1

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值