版权声明:本文为博主原创文章,未经博主允许不得转载。 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,秒转微秒。
实验效果: