树莓派超声波C语言

树莓派超声波C语言

超声波测距原理:是在超声波发射装置发出超声波,它的根据是接收器接到超声波时的时间差,与雷达测距原理相似。 超声波发射器向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。
在这里插入图片描述
以上时序图表明你只需要提供一个10uS以上脉冲触发信号,该模块内部将发出8个40KHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此听过发射信号到的回响信号时间间隔可以计算得到距离。

  • 公式:uS/58=厘米或者uS/148=英寸:
  • 距离=高电平时间*声速(340M/S)/2:
  • 建议测量周期为60 ms以上,以防止发射信号对回响信号的影响。 超声波测距源代码
#include <wiringPi.h>
#include <stdio.h>
#include <sys/time.h>

#define Trig    4
#define Echo    5

void chaoshengboInit(void)
{
    
    
    pinMode(Echo, INPUT);//检测波什么时候发什么时候回来设置端口为输入
    pinMode(Trig, OUTPUT);//触发脉冲设置端口为输出
}

float disMeasure(void)//测距原理
{
    
    
    struct timeval tv1;
    struct timeval tv2;
    long start, stop;
    float dis;
	
    digitalWrite(Trig, LOW);//先让脉冲处于低平稳
    delayMicroseconds(2);

    digitalWrite(Trig, HIGH);//再拉高
    delayMicroseconds(10);      //发出超声波脉冲
    digitalWrite(Trig, LOW);//拉低至平稳
    
    while ((digitalRead(Echo) != 1));
    gettimeofday(&tv1, NULL);           //获取当前时间,开始接收到返回信号的时候

    while (!(digitalRead(Echo) == 0));
    gettimeofday(&tv2, NULL);           //获取当前时间,最后接收到返回信号的时候
    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(void)
{
    
    
    float dis;//用来存放测试的距离

    if (wiringPiSetup() == -1) {
    
     //硬件端口初始化
        printf("setup wiringPi failed !");
        return -1; 
    }

    chaoshengboInit();//调用超声波函数
    
    while (1) {
    
    //不断地测距
        dis = disMeasure();
        printf("distance = %0.2f cm\n", dis);
        delay(1000);
    }

    return 0;
}

代码运行结果:
在这里插入图片描述
函数解析:
1.delayMicroseconds (unsigned int howLong)
将线程暂停指定的微秒数(1000微妙=1毫秒=0.001s),因为Linux是多线程的,所以实际暂停的秒数可能比设置的更多一些
2.digitalRead (int pin)
读取一个引脚的电平值(LOW / HIGH),并且返回。其中pin是引脚的编号,该引脚的初始化类型必须为INPUT等输入类型。返回值也可以是1 / 0(当输入信号电压在0~1.16 V时该函数返回0,当输入信号在1.83~3.3 V时返回1。如果输入电压在1.16~1.83 V之间不确定会返回0还是1)
3.gettimeofday(struct timeval , struct timezone );
则个函数返回的是1970年0:00:00到现在经过的秒数,函数的正常传入时需要用到两个参数。第一个已经介绍过了,第二个因为在这里没有用处,所以暂且不表,传入参数时用NULL即可,这里关于这个问题还有一个小故事:timeval中的tv_sec是time_t类型的,即long的类型。在32位下为4个字节,能够表示的最大正整数是2147483647,而这个表示的时间最大能到2038-01-19 03:14:07,超过了之后就变为-2147483648,这就是linux2038年的问题。而64位系统下的time_t类型即long类型长度为8个字节,可以用到几千亿年,这么长的时间完全不用担心溢出的问题。
4.根据返回的秒数计算出微秒数
   start = tv1.tv_sec * 1000000 + tv1.tv_usec;
   stop = tv2.tv_sec * 1000000 + tv2.tv_usec;
    我们知道 timeval结构体中含有两个变量,tv_sec表示的是秒数,1秒=1000000微妙,第二个参数tv_usec表示的就是微秒数,所以通过这两个式子我们就求出了开始和结束时的微秒数,然后做差即可得到超声波传递所使用的时间

5.根据时间计算距离
    (stop - start) / 1000000 * 34000 / 2
    因为stop和start原本表示的微妙,所以做差之后处1000000换算回是多少秒。因为声音在物质中的传播受到物质材质的影响,这里我们暂且不考虑介质的种类,默认为声音是在空气中传播,所以取声音的速度为340m/s=34000cm/s,因为超声波测距的误差较小的范围200-300cm,所以我们这里计算速度时用cm表示。

猜你喜欢

转载自blog.csdn.net/weixin_51478436/article/details/113744676