前言
记录pinMode(pin,mode)函数,有时候搞不清。。
pinMode函数用于配置引脚为输入或者输出模式,它是一个无返回值的函数,一般放在setup()函数体重,先设置再使用。
pinMode函数由两个参数–pin 和 mode,pin参数表示要配置的引脚代号,以Arduino Uno为例,它的取值范围是013,也可以把模拟引脚(A0A5)作为数字引脚使用,此时编号为14脚到19脚。mode参数表示设置的模式——INPUT输入模式或者OUTPUT输出模式,其中INPUT用于读取信号,OUTPUT用于输出控制信号。
配置数字引脚3位输出模式的语句如下所示:
pinMode(3,OUTPUT);
准备材料
- 超声波模块
- 树莓派3b
- 杜邦线母对母
- 树莓派电源线
超声波模块介绍
参数
测距原理
工作原理:
1.超声波模块和单片机进行连接。
2.触发信号,给Trig引脚发送一个大于10us的高电平。
3.发送高电平后,模块会循环发送8个40KHZ的脉冲,与此同时Echo引脚会由低电平变成高电平,这时候就需要开启定时器开始计算Echo引脚的高电平时间,
4.模块接收到返回的超声波时,Echo电平会由高电平变成低电平,此时应该关闭定时器,这个时候的算出来的定时器的时间就是Echo持续的高电平,也就是超声波从发射到传回来的总时间。
5.(除去温度的影响)根据声速为340m/s,来计算(高电平时间 * 340m/s) / 2。 计算的时候注意自己使用定时器获得的时间的单位。记得换算。
接线:
Vcc:超声波模块电源脚,接5V电源
Trig:接收来自树莓派的控制信号,接 GPIO 口
Echo:发送测距结果给树莓派,接 GPIO 口
(值得注意的是:Echo 返回的是 5v信号,而树莓派的 GPIO 接收超过 3.3v 的信号可能会被烧毁,因此可以加一个分压电路)
Gnd:接地,接 0v
注意:
(1)超声波模块的VCC电源要接5V的,如果接3.3V,模块的测距数值会不正确,在同一个数值范围波动;
(2)此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作;
(3)测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果;
struct timeval结构体
#include <sys/time.h>//头文件
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
其中,tv_sec为Epoch到创建struct timeval时的秒数,tv_usec为微秒数
gettimeofday()函数
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors.
NOTE: This form of timezone information is obsolete.
Use the functions and variables declared in <time.h> instead. */
extern int gettimeofday (struct timeval *__restrict __tv,
__timezone_ptr_t __tz) __THROW __nonnull ((1));
gettimeofday() 功能是得到当前时间和时区,分别写到 tv 和 tz 中,如果tz 为 NULL 则不向 tz 写入。
demo示例
#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>
#include <stdlib.h>
#define Trig 4
#define Echo 5
void initFunc(){
pinMode(Trig,OUTPUT); //初始化超声波
pinMode(Echo,INPUT);
}
float ultraFunc(){
float dis;
long start;
long end;
struct timeval tv1;
struct timeval tv2;
digitalWrite(Trig,LOW);
delayMicroseconds(2);
digitalWrite(Trig,HIGH);
delayMicroseconds(10);
digitalWrite(Trig,LOW);
while(digitalRead(Echo) != HIGH); // HIGH(1),检测到高电平时跳出循环
gettimeofday(&tv1, NULL); // 获取时间(此为高电平开始时间)
while(digitalRead(Echo) != LOW); // LOW(0),检测到低电平跳出循环
gettimeofday(&tv2, NULL); // 获取时间(此为低电平开始时间,即为高电平结束时间)
start = tv1.tv_sec * 1000000 + tv1.tv_usec; // 单位(微秒)
end = tv2.tv_sec * 1000000 + tv2.tv_usec; // 单位(微秒)
dis = (float)(end - start) / 1000000 * 34000 / 2; // 距离计算(高电平时间 * 音速 / 2)
return dis;
}
int main(){
float dis;
if(wiringPiSetup()==-1){
printf("setup wiringPi failed\n");
exit(-1);
}
initFunc();
while(1){
dis = ultraFunc();
printf("距离:%0.3fcm\n",dis);
delay(1000);
}
return 0;
}
工作图:
运行结果: