树莓派控制HC-SR04超声波模块测距(新手向+C语言向)
因为作业要求使用c语言代码,这里先附上一段摘自网上的代码
感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/62892140
#include <wiringPi.h>
#include <stdio.h>
#include <sys/time.h>
#define Trig 4
#define Echo 5 void ultraInit(void)
{
pinMode(Echo, INPUT); //设置端口为输入
pinMode(Trig, OUTPUT); //设置端口为输出
} float disMeasure(void)
{
struct timeval tv1; //timeval是time.h中的预定义结构体 其中包含两个一个是秒,一个是微秒
/*
struct timeval
{
time_t tv_sec; //Seconds.
suseconds_t tv_usec; //Microseconds.
};
*/ struct timeval tv2;
long start, stop;
float dis; digitalWrite(Trig, LOW);
delayMicroseconds(); digitalWrite(Trig, HIGH);
delayMicroseconds(); //发出超声波脉冲
digitalWrite(Trig, LOW); while(!(digitalRead(Echo) == ));
gettimeofday(&tv1, NULL); //获取当前时间 开始接收到返回信号的时候 while(!(digitalRead(Echo) == ));
gettimeofday(&tv2, NULL); //获取当前时间 最后接收到返回信号的时候
/*
int gettimeofday(struct timeval *tv, struct timezone *tz);
The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone.
The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.
*/
start = tv1.tv_sec * + tv1.tv_usec; //微秒级的时间
stop = tv2.tv_sec * + tv2.tv_usec; dis = (float)(stop - start) / * / ; //计算时间差求出距离 return dis;
} int main(void)
{
float dis; if(wiringPiSetup() == -){ //如果初始化失败,就输出错误信息 程序初始化时务必进行
printf("setup wiringPi failed !");
return ;
} ultraInit(); while(){
dis = disMeasure();
printf("distance = %0.2f cm\n",dis);
delay();
} return ;
}
因为是刚开始接触树莓派开发,所以文章中可能会出现错误,希望大神们能多多指教,不胜感激。
PS:以下内容出现顺序按照代码阅读顺序
1.sys/time.h
360搜索链接:https://baike.so.com/doc/1233815-1304991.html
2.wiringPi.h
wiringPi是一个很棒的树莓派IO控制库,使用C语言开发,提供了丰富的接口:GPIO控制,中断,多线程,等等。
wiringPi.h详解:https://www.cnblogs.com/lulipro/p/5992172.html
3.wiringPiSetup(void)
在使用wiringPi.h库时,在执行任何操作前都必须初始化树莓派,否则程序便无法正常运行。当初始化操作未完成时,函数返回值为-1
其他的树莓派初始化函数还有wiringPiSetupGpio(void),此函数使用方法与wiringPiSetup(void)类似,当函数无法正常运行时返回值也是-1.不同的地方在于,wiringPiSetup(void)初始化树莓派引脚时使用的是wiringPi 引脚编号表。引脚的编号为 0~16;wiringPiSetupGpio(void)初始化树莓派引脚时使用的是BCM GPIO 引脚编号表。
其他两种函数还有wiringPiSetupPhys(void)和wiringPiSetupSys (void) ,因为不常用,所以在此处不做介绍。
4.void pinMode(uint8 pin, WiringPinMode mode)
这个函数是用来确定引脚的功能的,如果在使用某个引脚之前没有确定这个引脚的功能或者引脚设置模式不正确,就会出现一些不可捉摸的错误。
这个函数有两个参数,第一个参数pin是一个正整数,用来指定引脚的编号(0-16),第二个参数是用来指定引脚的IO模式,可用的参数有INPUT , OUTPUT , OUTPUT_OPEN_DRAIN , INPUT_ANALOG , INPUT_PULLUP , INPUT_PULLDOWN , INPUT_FLOATING , PWMPWM_OPEN_DRAIN
每个参数的具体意义请移步:https://book.2cto.com/201311/36087.html
5.timeval
在代码中已经告诉了我们整个结构体的来历和定义下的架构,这里不做详解,有兴趣的童鞋请移步https://blog.csdn.net/king16304/article/details/52273834
6.digitalWrite(uint8 pin, uint8 value)
这又是一个在wiringPi.h中已经定义好的函数,它的作用是对一个已近配置为输出模式(OUTPUT或者OUTPUT_OPEN_DRAIN)的 引脚 输出指定的电平信号,其中pin是一个正整数,用来指定一个已经初始化过的引脚,value可以是数字或者参数,数字表示下:1代表高电平,0代表低电平;参数表示下:LOW代表低电平,HIGH代表高电平。
7.delayMicroseconds (unsigned int howLong)
将线程暂停指定的微秒数(1000微妙=1毫秒=0.001s),因为Linux是多线程的,所以实际暂停的秒数可能比设置的更多一些
8.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。)
9.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个字节,可以用到几千亿年,这么长的时间完全不用担心溢出的问题。
10.根据返回的秒数计算出微秒数
start = tv1.tv_sec * 1000000 + tv1.tv_usec;
stop = tv2.tv_sec * 1000000 + tv2.tv_usec;
我们知道 timeval结构体中含有两个变量,tv_sec表示的是秒数,1秒=1000000微妙,第二个参数tv_usec表示的就是微秒数,所以通过这两个式子我们就求出了开始和结束时的微秒数,然后做差即可得到超声波传递所使用的时间
11.根据时间计算距离
(stop - start) / 1000000 * 34000 / 2
因为stop和start原本表示的微妙,所以做差之后处1000000换算回是多少秒。因为声音在物质中的传播受到物质材质的影响,这里我们暂且不考虑介质的种类,默认为声音是在空气中传播,所以取声音的速度为340m/s=34000cm/s,因为超声波测距的误差较小的范围200-300cm,所以我们这里计算速度时用cm表示。
既然我们已经读懂了代码,接下来我们就是硬件方面的链接:
我们先来了解一下各个硬件分别开来的属性。
1.树莓派:
树莓派的历史我们在此不做过多的讲解,其他硬件也暂且不讲,我们先来看一下树莓派上的引脚。
拿起树莓派,将USB接口向下,面向你那起来,你会发现树莓派右边有两列一共40个引脚,下边这部分告诉了我们这些引脚各自的功能。
+-----+-----+---------+------+---+---Pi ---+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | .3v | | | || | | | 5v | | |
| | | SDA. | ALT0 | | || | | | 5V | | |
| | | SCL. | ALT0 | | || | | | 0v | | |
| | | GPIO. | IN | | || | | ALT5 | TxD | | |
| | | 0v | | | || | | ALT5 | RxD | | |
| | | GPIO. | OUT | | || | | IN | GPIO. | | |
| | | GPIO. | IN | | || | | | 0v | | |
| | | GPIO. | IN | | || | | IN | GPIO. | | |
| | | .3v | | | || | | IN | GPIO. | | |
| | | MOSI | ALT0 | | || | | | 0v | | |
| | | MISO | ALT0 | | || | | IN | GPIO. | | |
| | | SCLK | ALT0 | | || | | OUT | CE0 | | |
| | | 0v | | | || | | OUT | CE1 | | |
| | | SDA. | IN | | || | | IN | SCL. | | |
| | | GPIO. | IN | | || | | | 0v | | |
| | | GPIO. | IN | | || | | IN | GPIO. | | |
| | | GPIO. | IN | | || | | | 0v | | |
| | | GPIO. | IN | | || | | IN | GPIO. | | |
| | | GPIO. | IN | | || | | IN | GPIO. | | |
| | | 0v | | | || | | IN | GPIO. | | |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+---Pi ---+---+------+---------+-----+-----+
我们重点来介绍这次试验用到的两种引脚:
①.电源引脚:分为3.3V / 5V / 0V三种,其中0V代表接地
②.GPIO输入输出接口:这是非常重要的一类引脚,上图中标明了GPIO的就是这类接口,树莓派GPIO接口只能输入输出数字信号(0&1等)
2.超声波模块
超声波模块的种类有很多,我们此处选择的模块型号为HC-SR04,本模块的优点为性能稳定,测度距离精确,模块高精度,盲区小。探测距离为2cm-450cm。
我们可以看到它一共有四个引脚:
Vcc:接5V电源(接1号引脚)
Trig:输出端口(接16号引脚)
Echo:输入端口(接18号端口)
Gnd:接地端(接6号端口)
3.杜邦线
杜邦线有三种类型,分别为公对母,母对母,公对公。我们这里需要的是四条母对母的杜邦线。
接下来我们就用杜邦线将超声波模块与树莓派连接,连接时一定要注意引脚之间的对应关系。连接成功后如下
连接成功后我们就开始测试程序了,先将程序编译成可执行的二进制文件
之后输入ls 查看,我们发现有编译成功后的disMeasure文件
之后我们输入sudo ./disMeasure 开始执行程序,程序运行效果如下。
到此,我们的超声波模块测距部分就算完美收工了。
以上就是超声波模块测距的c的代码和解析的部分了,希望能对大家的树莓派学习有帮助。
树莓派控制HC-SR04超声波模块测距(新手向+C语言向)的更多相关文章
- 关于HC04超声波模块测距的思考(51版)
之前写过一篇HC04的使用文章,当时是使用stm32来实现的,原文链接. 后来又多次使用51来驱动这个模块,有时候有测距需要,使用了几次,总是感觉我上次那个程序不是很好, 所以这次对它进行了改进.虽然 ...
- 树莓派超声波测距+蜂鸣器(c语言)
前边我们已经详细的讲解了树莓派控制超声波模块测距(http://www.cnblogs.com/yuemo/p/8888342.html)和超声波控制蜂鸣器模块发声(http://www.cnblog ...
- [TPYBoard - Micropython之会python就能做硬件 8] 学习使用超声波模块制作避障小车
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 一.实验器材 1.TPYboard V102板 一块 2.电机驱动模块L2 ...
- C语言单片机项目实战超声波雷达测距
本实验是基于MSP430利用HC-SR04超声波传感器进行测距,测距范围是3-65cm,讲得到的数据显示在LCD 1602液晶屏上. 模块工作原理如下 (1)采用 IO 触发测距,给至少 10us 的 ...
- 超声波模块HC-SR04简介以及编程
HC-SR04 一.主要参数1:使用电压:DC-5V2:静态电流:小于2mA3:电平输出:高5V4:电平输出:底0V5:感应角度:不大于15度6:探测距离:2cm-450cm7:高精度 可达0.2cm ...
- 【雕爷学编程】Arduino动手做(58)---SR04超声波传感器
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的.鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为 ...
- stm32与HC-SR04超声波传感器测距
首先,先来看一下这个模块的基本功能和原理. HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm:模块包括超声波发射器.接收器与控制电路.像智能小车的测距 ...
- stm32驱动超声波模块
下面是关于stm32驱动超声波模块的一段代码,有需要的朋友可以复制参考,希望对大家能够有所帮助和启发. #define HCSR04_PORT GPIOB #define HCSR04_CLK RCC ...
- 树莓派控制高电平蜂鸣器(c语言+新手向)
话不多说,先上代码: #include <wiringPi.h> #include <stdio.h> #include <sys/time.h> #define ...
随机推荐
- JavaScript(第十四天)【面向对象和原型】
学习要点: 1.学习条件 2.创建对象 3.原型 4.继承 ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建 ...
- 201621123060《JAVA程序设计》第十二周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车. 2.1 简述如何 ...
- 敏捷冲刺每日报告——Day3
1.情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起止时间 2017.10.27 00:00 -- 2017.10.28 00:00 讨论时间地点 2017.10.27晚9:30, ...
- 201621123057 《Java程序设计》第1周学习总结
1.本周学习总结 .java - - 源程序 .class - - 字节码文件 JVM - - 虚拟机 JRE - - 执行环境 JDK - - 开发工具包 其中,运行的是.class,而非.java ...
- python 操作Memcached
启动Memcached memcached -d -m 10 -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid 参数说明: -d ...
- 【深度学习】深入理解Batch Normalization批标准化
这几天面试经常被问到BN层的原理,虽然回答上来了,但还是感觉答得不是很好,今天仔细研究了一下Batch Normalization的原理,以下为参考网上几篇文章总结得出. Batch Normaliz ...
- linux下面的打包压缩命令
tar命令 tar [-cxtzjvfpPN] 文件与目录 ....linux下面压缩之前要把一堆文件打个包再压缩,即使只有一个文件也需要打个包.例子:tar czvf 1.tar.gz hello. ...
- lodash源码分析之获取数据类型
所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...
- 从PRISM开始学WPF(九)交互(完结)
0x07交互 Notification xaml: <Window x:Class="UsingPopupWindowAction.Views.MainWindow" xml ...
- 《深入实践Spring Boot》阅读笔记之一:基础应用开发
上上篇「1718总结与计划」中提到,18年要对部分项目拆分,进行服务化,并对代码进行重构.公司技术委员会也推荐使用spring boot,之前在各个技术网站中也了解过,它可以大大简化spring配置和 ...