最近学习Raspberry Pi,也买了一块2B的板子(这型号取得...)和一堆小器件慢慢摸索。
先从比较简单的超声波测距模块开始弄。
为了方便,把RPI的GPIO槽通过延长线接到专门的扩展槽,再插到面包板上,方便通过引线连接器件。
使用的超生模块型号是HC-SR04,有4个引脚:VCC——供电;Trig——触发控制端;Echo——输出反馈端;GND——接地端。
(2)模块会自动向前发送8个40kHz的脉冲;
(3)模块探测到回声后,会从Echo端输出高电平,持续的时间和发送声波后到接受到回声之间的时间差成正比例;
在hcsr04.h里定义一些必要的参数:
经测试,能正常工作。参考了树莓派论坛的资料,在此感谢。
先从比较简单的超声波测距模块开始弄。
为了方便,把RPI的GPIO槽通过延长线接到专门的扩展槽,再插到面包板上,方便通过引线连接器件。
使用的超生模块型号是HC-SR04,有4个引脚:VCC——供电;Trig——触发控制端;Echo——输出反馈端;GND——接地端。
工作流程为:
(1)给Trig端至少10us的高电平;(2)模块会自动向前发送8个40kHz的脉冲;
(3)模块探测到回声后,会从Echo端输出高电平,持续的时间和发送声波后到接受到回声之间的时间差成正比例;
(4)因此在程序里可以根据声波速度,计算出来回的距离,再除以2就得到单程距离。
在main.c里调用并显示测距结果:
#include <stdio.h>
#include <wiringPi.h>
#include "hcsr04.h"
int main(void)
{
......
double sec=0.0, rDist=0.0;
//Init GPIO,否则无法使用wiringPi库来操作GPIO
wiringPiSetup();
while(1)
{
//调用测距函数,成功返回0,通过参数返回测到的时间和距离
myErr = myfunc_GetDistance(&sec, &rDist);
if(!myErr)
{
sprintf(w_buf, "second=%f s,\tDistance=%f cm, myErr=%d.", sec, rDist, myErr);
}
else
{
sprintf(w_buf, "\t>>>HC-SR04 module report an error, error code is : %d.", myErr);
}
printf("%s\n", w_buf);
......
usleep(300000);
}
return(0)
}
在hcsr04.h里定义一些必要的参数:
#ifndef _HC_SR04_H_
#define _HC_SR04_H_
#define GPIO_HC_SR04_TRIG 0 //定义管脚Trig接到0#GPIO
#define GPIO_HC_SR04_ECHO 1 //定义管脚Echo接到1#GPIO
#define ERR_HC_SR04_TIME_OUT 0X01
#define ERR_HC_SR04_INVALID 0X02
#define ERR_SLEEP 0X04
#define MAX_WAIT_HC_SR04_COUNTER 65530
//定义测距函数原型
int myfunc_GetDistance(double *second, double *centimeter);
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <wiringPi.h>
#include "hcsr04.h"
int myfunc_GetDistance(double *second, double *centimeter)
{
double dist = 0;
double sec = 0;
unsigned int err = 0;
unsigned int waitCounter = 0;
struct timeval startTime,endTime;
char flagSleepFailed = 0;
char flagTimeOut = 0;
pinMode(GPIO_HC_SR04_TRIG,OUTPUT);
pinMode(GPIO_HC_SR04_ECHO,INPUT);
digitalWrite(GPIO_HC_SR04_TRIG,HIGH);
if(usleep(10) != 0)
{
flagSleepFailed = 1;
}
digitalWrite(GPIO_HC_SR04_TRIG,LOW);
gettimeofday(&startTime,0);
while((digitalRead(GPIO_HC_SR04_ECHO) == LOW) && (waitCounter < MAX_WAIT_HC_SR04_COUNTER)/**/)
{
waitCounter++;
}
if(waitCounter >= MAX_WAIT_HC_SR04_COUNTER)
{
flagTimeOut = 1;
}
waitCounter = 0;
while((digitalRead(GPIO_HC_SR04_ECHO) == HIGH) && (waitCounter < MAX_WAIT_HC_SR04_COUNTER))
{
waitCounter++;
}
gettimeofday(&endTime,0);
if(waitCounter >= MAX_WAIT_HC_SR04_COUNTER)
{
flagTimeOut = 1;
}
waitCounter = 0;
sec = endTime.tv_usec - startTime.tv_usec;
if(sec < 0)
{
sec = sec + 1000000;
}
sec = sec/1000000;
dist = sec*340*100/2;
if(dist < 2 || dist > 400)
{
err |= ERR_HC_SR04_INVALID;//HC-SR04 module report a invalid value
}
if(flagSleepFailed)
{
err |= ERR_SLEEP;
}
if(flagTimeOut )
{
err |= ERR_HC_SR04_TIME_OUT;
}
if(!err)
{
*second = sec;
*centimeter = dist;
}
else
{
*second = 0;
*centimeter = 0;
}
return err;
}
经测试,能正常工作。参考了树莓派论坛的资料,在此感谢。