(十五)树莓派3B+ wiringPi库的使用--超声波测距HC-SR04

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuming3834/article/details/82964851

之前八月节气回家找了一下之前大学自己买的各种电子模块,记得有超声波模块的,也找到了,是HC-SR04超声波模块。这个实验也是上个月就测试好了的。

HC-SR04模块介绍

在这里插入图片描述
在这里插入图片描述
这些模块介绍,我都是直接截图的说明书的。淘宝上买模块,很多店家都会附带资料下载地址的。

HC-SR04模块原理图

在这里插入图片描述
通过这个原理图,可以看出,其实模块内部也有一个STC11的单片机处理了的,这里也可以看出为什么上面的时序图那么简单了。

HC-SR04模块和树莓派的连接

这里我使用的树莓派板子上的第38和40引脚,也就是wiringPi编码的第28和29引脚。
在这里插入图片描述
由于画图软件一直没找到3B+的板子,就一直使用的事3B的板子,示意图,看看就行。

代码实现

#include <wiringPi.h>
#include <stdio.h>  
#include <sys/time.h> 

#define Trig_pin 29     // 定义 排针的第40引脚接 模块的发射引脚
#define Echo_pin 28  // 定义 排针的第38引脚接模块的接收引脚

// 系统和管脚初始化
void systemInit(){
    wiringPiSetup();
    // 初始化发射引脚
    pinMode (Trig_pin, OUTPUT);
    // 初始化接收引脚
    pinMode (Echo_pin, INPUT);
}
// 测量 距离
float getDis(){
    struct timeval start_time;
    struct timeval stop_time;

    digitalWrite (Trig_pin, LOW); 
    delay(10); // 延时10 毫秒  等待让电平稳定
    digitalWrite (Trig_pin, HIGH);
    delayMicroseconds(10); // 给一个10us的高电平
    // 这里发现 delayMicroseconds(),这个函数是不准确的,实际是大于10us,具体结果如何,需要示波器测量一下。
    digitalWrite (Trig_pin, LOW);

    while(!(digitalRead(Echo_pin) == 1));      
    gettimeofday(&start_time, NULL);           // 获取当前时间 开始接收到返回信号的时候     
    while(!(digitalRead(Echo_pin) == 0));      
    gettimeofday(&stop_time, NULL);           // 获取当前时间 结束信号

    float start, stop;
    start = start_time.tv_sec * 1000000 + start_time.tv_usec;   //微秒级的时间  
    stop  = stop_time.tv_sec * 1000000 + stop_time.tv_usec;
    float dis = (stop - start) / 1000000 * 34000 / 2;  //计算时间差求出距离
    // 这里测试的 距离 实际就是上面时序图的回响时间长度乘以声速的结果。
    return dis;
}

int main (void)
{
    float dis; 
    systemInit();
	// 每秒 测试一次距离并输出
    while(1){  
        dis = getDis();  
        printf("distance = %0.2f cm\n",dis);  
        delay(1000);  
    }  
	return 0;
}

这里需要注意的是#include <sys/time.h>这个头文件,这是Linux系统的日期时间头文件。其中用到的gettimeofday()函数,gettimeofday是计算机函数,使用C语言编写程序需要获得当前精确时间(1970年1月1日到现在的时间),或者为执行计时,可以使用gettimeofday()函数。
结构体timeval的定义为:

struct timeval{
	long int tv_sec; // 秒数
	long int tv_usec; // 微秒数
}

这也是上面为什么要乘以1000000,秒转微秒。
实验效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhuming3834/article/details/82964851