Raspberry Pi超声波测距样例

    最近学习Raspberry Pi,也买了一块2B的板子(这型号取得...)和一堆小器件慢慢摸索。
    先从比较简单的超声波测距模块开始弄。
    为了方便,把RPI的GPIO槽通过延长线接到专门的扩展槽,再插到面包板上,方便通过引线连接器件。
    使用的超生模块型号是HC-SR04,有4个引脚:VCC——供电;Trig——触发控制端;Echo——输出反馈端;GND——接地端。


工作流程为:

(1)给Trig端至少10us的高电平;
(2)模块会自动向前发送8个40kHz的脉冲;
(3)模块探测到回声后,会从Echo端输出高电平,持续的时间和发送声波后到接受到回声之间的时间差成正比例;

(4)因此在程序里可以根据声波速度,计算出来回的距离,再除以2就得到单程距离。

Raspberry Pi超声波测距样例_第1张图片

在main.c里调用并显示测距结果:

#include 
#include 
#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


在hcsr04.c里实现测距函数:

#include 
#include 
#include 
#include 
#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;
}

经测试,能正常工作。参考了树莓派论坛的资料,在此感谢。

你可能感兴趣的:(Raspberry,Pi)