×

用于Arduino的BGT60雷达传感器

消耗积分:0 | 格式:zip | 大小:0.02 MB | 2022-10-26

分享资料个

描述

在本教程结束时,您将能够检测运动及其方向,并根据检测到的运动触发中断。

BGT60LTR11AIP 防护罩

我们的防护罩使用 60GHz 雷达技术来检测 7m 范围内的运动及其方向。它提供仅 20x6.25mm 的小尺寸和低功耗,为许多应用创造了创新、直观的传感功能。小型运动传感器集成天线并在内部处理原始雷达信号,无需任何外部微控制器即可操作设备。

pYYBAGNX-4qAMWG-AADDij3Ub4o746.png
雷达 BGT60 引脚分配
 

仅使用四个引脚就可以非常轻松地与防护罩连接:

  • 接地
  • 输入电压 (1.5V - 5V)
  • P out (= 运动方向)
  • T out (= 运动检测)

带有 GND 和 Vin(1.5V 至 5V)的电源可以连接到微控制器引脚 Vcc 和 GND。相位检测输出 (P out) 引脚表示方向,而目标检测输出 (T out) 引脚表示雷达传感器检测到的运动。BGT60 可以轻松插入 Arduino MKR1000 板的接头(Vcc、GND、T out - A1 和 P out - A2)

 

用于 Arduino 的英飞凌 60GHz 库

我们为 60GHz 雷达屏蔽开发的库称为“radar-bgt60”。使用 Arduino IDE,通过 Sketch -> Include library -> Library Manager 安装 Radar 库。雷达库包括八个基本 API 函数,我们稍后会在各种示例中使用它们。

  • Bgt60() - Arduino Bgt60 对象的构造函数
  • ~Bgt60() - Arduino Bgt60 对象的析构函数
  • init() - 初始化 Bgt60 类对象
  • deinit() - 取消初始化 Bgt60 类对象
  • getMotion() - 读出目标检测引脚
  • getDirection() - 读出相位检测引脚
  • enableInterrupt() - 启用硬件中断
  • disableInterrupt() - 禁用硬件中断

在我们的Arduino API 描述中找到更多详细信息

要将草图上传到您的板上,您必须先选择所需的平台。在此示例中,我们使用 Arduino MKR1000 板。转到工具 -> 董事会 -> 董事会经理。在那里你搜索你的“Arduino MKR1000”,你会找到需要安装的包“Arduino SAMD Boards”。

poYBAGNX-5CAb4z7AABrXgGLvb8234.png
 

为了现在上传草图,您还必须选择正确的 COM 端口。有一个非常简单的方法可以做到这一点。拔下连接的 Arduino,然后检查Tool -> Port下可用的 COM-Ports 现在连接您的 Arduino 并再次检查端口。现在你应该看到一个新的,以前没有的。这是正确的,请选择它。

运动

在第一个简单示例中,我们想使用 getMotion() 函数来识别传感器环境中的运动。从文件 -> 示例 -> 雷达-bgt60 -> 运动检测中获取代码。

/*!
 * \name        motionDetection
 * \author      Infineon Technologies AG
 * \copyright   2021 Infineon Technologies AG
 * \brief       This example detects the motion of an object
 * \details     This example demonstrates how to detect a moving object while the
 *              BGT60LTR11AIP shield is connected to Arduino compatible
 *              boards using polling method.
 *
 *              Connection details:
 *              --------------------------------------------------
 *              Pin on shield   Connected to pin on Arduino
 *              --------------------------------------------------
 *              TD                  depends on Arduino board
 *              PD                  depends on Arduino board
 *              GND                 GND
 *              Vin                 VCC (3.3V or 5V - depends on Arduino board)
 *              --------------------------------------------------
 *
 *              Decoding on-board LED output of BGT60LTR11AIP shield:
 * 
 *              - Red LED indicates the output of direction of motion once target is detected (PD)
 *              ---------------------------------------------
 *              LED    State    Output explanation
 *              ---------------------------------------------
 *              Red     ON       Departing target
 *                      OFF      Approaching target
 *              ---------------------------------------------
 *
 *              - Green LED indicates the output of target in motion detection (TD)
 *              ---------------------------------------------
 *              LED    State    Output explanation
 *              ---------------------------------------------
 *              Green    ON       Moving target detected
 *                       OFF      No target detected
 *              ---------------------------------------------
 *
 * SPDX-License-Identifier: MIT
 */

#include 
/* Include library main header */
#include 
/* Include Arduino platform header */
#include 

/*
* In case no supported platform is defined, the
* PD and TD pin will be set to the values below.
*/
#ifndef TD
#define TD  15
#endif

#ifndef PD
#define PD  16
#endif

/* Create radar object with following arguments:
 *  TD : Target Detect Pin
 *  PD : Phase Detect Pin */
Bgt60Ino radarShield(TD, PD);

/* Begin setup function - takes care of initializations and executes only once post reset */
void setup()
{
    /* Set the baud rate for sending messages to the serial monitor */
    Serial.begin(9600);
    // Configures the GPIO pins to input mode
    Error_t init_status = radarShield.init();
    /* Check if the initialization was successful */
    if (OK != init_status) {
        Serial.println("Init failed.");
    }
    else {
        Serial.println("Init successful.");
    }
}

/* Begin loop function - this part of code is executed continuously until external termination */
void loop()
{
    /* Initialize the variable to NO_MOTION to be able to record new events */
    Bgt60::Motion_t motion = Bgt60::NO_MOTION;

   /* The getMotion() API does two things:
        1. Returns the success or failure to detect moving object as a message of type Error_t.
           Any value other than OK indicates failure
        2. Sets recent event in "motion" variable. Events can be: NO_MOTION or MOTION */
    Error_t err = radarShield.getMotion(motion);

    /* Check if API execution is successful */
    if(err == OK)
    {
        /* Cases based on value set in motion variable */
        switch (motion)
        {
            /* Variable "motion" is set to MOTION when moving target is detected */
            case Bgt60::MOTION:
                Serial.println("Target in motion detected!");
                break;
            /*  Variable "motion" is set to NO_MOTION when moving target is not present */
            case Bgt60::NO_MOTION:
                Serial.println("No target in motion detected.");
                break;
        }
    }
    /*  API execution returned error */
    else {
        Serial.println("Error occurred!");
    }

    /* Reducing the frequency of the measurements */
    delay(500);
}

没有注释,代码只有 50 行。在我们逐步讨论之后,我们将上传示例。

#include 
#include 
#include 

首先,我们包含了来自 Arduino 的主库和用于 BGT60 雷达传感器的库。

#ifndef TD
#define TD  15
#endif

#ifndef PD
#define PD  16
#endif

Bgt60Ino radarShield(TD, PD);

if 条件检查是否定义了 TD 和 PD。它们代表我们的引脚相位检测和硬件的目标检测。在我们的例子中,它们已经设置好了,因为我们之前定义了支持的平台 Arduino MKR1000。如果我们选择另一个微控制器(不是来自 Arduino),这一步是指定未知引脚的必要步骤。行“Bgt60Ino radarShield(TD, PD);” 使用教练用两个针创建一个雷达对象。

void setup()
{
    Serial.begin(9600);
    // Configures the GPIO pins to input mode
    Error_t init_status = radarShield.init();
    if (OK != init_status) {
        Serial.println("Init failed.");
    }
    else {
        Serial.println("Init successful.");
    }
}

在函数“setup”中是我们程序的初始化。当我们上传草图时它只执行一次。“Serial.begin()”函数设置波特率,它定义了向监视器发送消息的传输速度。现在我们使用库的 API 函数之一“intit()”来初始化之前的 Bgt60 类对象“radarShield”。因此,引脚将设置为输入模式。如果初始化成功,函数返回“OK”。为了以用户身份查看初始化是否有效,我们打印 init 函数的结果。

void loop()
{
    Bgt60::Motion_t motion = Bgt60::NO_MOTION;

    Error_t err = radarShield.getMotion(motion);

“loop()”函数是代码的一部分,它一遍又一遍地重复。首先,我们拒绝变量“运动”以保存检测到的运动。有两种可能的状态。一开始我们将其设置为“Bgt60::NO_MOTION”。

在下一行中,我们在“radarShield”对象上使用函数“getMotion()”。该函数的传递参数是运动变量。当传感器检测到运动时,该函数将变量设置为“Bgt60::MOTION” . 如果整个函数成功,“OK”将保存在“Error_t”变量中。

if(err == OK)
    {
        switch (motion)
        {
            case Bgt60::MOTION:
                Serial.println("Target in motion detected!");
                break;
            case Bgt60::NO_MOTION:
                Serial.println("No target in motion detected.");
                break;
        }
    }
    else {
        Serial.println("Error occurred!");
    }
    delay(500);
}

在最后一部分,我们检查函数是否成功。在这种情况下,如果变量“motion”是“Bgt60::MOTION”或“Bgt60::NO_MOTION”,我们将启动 switch case 条件并打印解决方案。最后我们开始一个延迟,它代表两个循环段落之间的暂停。

pYYBAGNX-5KATxMyAAA2UShhZ2U458.png
工具栏
 

现在我们了解了整个代码并准备上传它。如果到目前为止还没有完成,您可以编译按钮 1 上的代码。使用 2 将草图上传到板上。要查看我们打印的内容以及传感器是否检测到运动,您必须在 3 上打开显示器。

当周围的一切完全静止时,您可以在监视器上读取“未检测到运动中的目标”。但是,如果您在距离传感器 5 米的范围内有运动,您的输出就是“检测到运动中的目标!”。

方向

在成功检测到运动之后,我们还想知道这个运动的方向。因此,库、对象创建和设置功能完全相同。

Bgt60::Direction_t direction = Bgt60::NO_DIR;

Error_t err = radarShield.getDirection(direction);

循环中的代码也和之前类似,但现在我们为方向做。首先我们需要一个变量来存储方向。其次,我们使用 API 函数“getDirection()”。

if (err == OK)
{
    switch (direction)
    {
        case Bgt60::APPROACHING:
            Serial.println("Target is approaching!");
            break;
        case Bgt60::DEPARTING:
            Serial.println("Target is departing!");
            break;
        case Bgt60::NO_DIR:
            Serial.println("Direction cannot be determined since no motion was detected!");
            break;
    }
}
else{
Serial.println("Error occurred!");
}

方向变量有三种可能的状态。我们有两个不同的方向:接近和离开。也有可能,我们根本没有运动,因此没有方向。如果 API 函数有效,它会为错误变量返回“O​​K”。只有当它成功时,我们才会开始一个 switch-case 条件,我们在离开、接近和无方向之间做出决定。每次延迟后都会打印当前状态。

poYBAGNX-5WAKQuSAACR9Lzzthw603.png
可能的监视器输出方向检测
 

可能的监视器输出在上图中。要创建它,您首先将手移向传感器,然后再移开。

打断

作为最后一个例子,让我们展示如何使用中断功能。当您启用中断时,处理器会停止其当前活动并保存其状态。相反,它同时执行一个称为中断服务程序 (ISR) 的功能。在我们的示例中,当检测到的运动或方向的状态发生变化时会触发中断。因此,代码中的库和对象创建仍然与上两个示例中的相同。

init_status = radarShield.enableInterrupt(cBackFunct);

if (OK != init_status)
    Serial.println("Interrupt init failed.");
else
    Serial.println("Interrupt init successful.");
}

在 setup 函数中,我们像以前一样设置波特率并初始化我们的对象。此外,我们现在激活中断。函数“enableInterrupt()”打开硬件中断。“cBackFunct”函数从中断开始。此外,我们得到一个状态变量,我们可以使用它检查启用中断的 API 函数是否有效。

/* Definition and initialization of the interrupt active flag */
volatile static bool intActive = false;

/* User defined callback function */
void cBackFunct(void)
{
    if ( ! intActive ) {

        /* Set the interrupt active flag to avoid parallel execution of this function multiple times. */
        intActive = true;

        /* Create variables to store the state of the motion as well as the direction */
        Bgt60::Motion_t motion = Bgt60::NO_MOTION;
        Bgt60::Direction_t direction = Bgt60::NO_DIR;

        /* Now check what happend, first check if a motion was detected or is
not detected anymore */
        Error_t err = radarShield.getMotion(motion);

        /* Check if API execution is successful */
        if(OK == err)
        {
            /* In case motion is detected */
            if(Bgt60::MOTION == motion){
                Serial.println("Target in motion was detected!");

                /* Check the direction of the detected motion */
                err = radarShield.getDirection(direction);
                if(OK == err)
                {
                    /* In case the target is approaching */
                    if(Bgt60::APPROACHING == direction){
                        Serial.println("The target is approaching!");
                    }
                    /* In case the target is departing */
                    else{
                        Serial.println("The target is departing!");
                    }
                }
            /* API execution returned error */
            else{
                Serial.println("Error has occurred during the determination of the direction!");
            }
        }
        /* No motion is detected */
        else{
            Serial.println("No target in motion detected!");
        }
    }
    /* API execution returned errord */
    else {
        Serial.println("Error has occurred during the determination of the direction!");
    }

    Serial.println("\n--------------------------------------\n");

    /* Release the interrupt active flag to allow a new call of this callback function. */
    intActive = false;
    }
}

“cBackFunct”代表中断服务程序(ISR)。我们将它写在 setup 函数之前的单独函数中。还。我们有一个局部变量,它是中断的活动标志。因此,它在 ISR 开始时设置为活动,在函数结束时设置为非活动。为避免多次并行执行此函数,“cBackFunct”检查活动标志之前是否处于非活动状态。该函数中的其他所有内容都类似于方向检测。我们首先使用已知函数来检查运动,然后分离运动的两个方向。我们打印相应的运动状态和方向。之后,我们打印一个视觉边框以保持概览。

void loop()
{
    // Here you can do something else in parallel while waiting for an interrupt.
    delay(1000);
}

在我们的循环函数中,我们现在只有延迟。我们可以在那里放置任何代码,这些代码应该在没有发生运动或方向变化的情况下执行。为了更容易理解中断的工作方式,您也可以在循环中打印一些内容。

poYBAGNX-5iARMpqAABwjzGHWPw709.jpg
 

监视器输出在每个边界后发生变化。这是因为我们只有在发生变化时才开始中断。打印输出之间的时间不再像以前那样有规律,现在取决于中断。

如果我们不再需要中断,例如一段时间后,我们可以使用函数“disableInterrupt()”禁用它。之后只有我们在循环中的代码会被执行。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !