初学者
10 分钟

使用Sera NX040 (453-00174C)和STM32L073RZ在室内环境中精确监控和定位贵重资产

超宽带(UWB)和蓝牙LE,实现小于±10cm的卓越测距精度

UWB 4 Click with Nucleo-64 with STM32L073RZ MCU

已发布 8月 19, 2024

点击板

UWB 4 Click

开发板

Nucleo-64 with STM32L073RZ MCU

编译器

NECTO Studio

微控制器单元

STM32L073RZ

将UWB(超宽带)用于精确测距,与Bluetooth LE(低功耗蓝牙)相结合,实现无线通信和数据传输,以便在精确的室内定位和基于位置的应用中使用

A

A

硬件概览

它是如何工作的?

UWB 4 Click 基于 Ezurio 的 Sera NX040(453-00174C),这是一款配备外部天线连接器的先进 UWB/BLE 模块。该模块采用顶级芯片:NXP 的 SR040 超宽带(UWB)芯片组和 Nordic Semiconductor 的 nRF52833 Bluetooth LE 芯片,提供在精确定位和无线通信方面的卓越性能。此外,该模块已预先校准以符合法规要求,并针对各种温度和 UWB 天线实现进行了优化,提供卓越的测距性能,使此 Click board™ 成为精确室内定位和基于位置的应用(如资产跟踪、导航和工业自动化)的理想选择。正如所提到的,Sera NX040 的核心是 NXP SR040 超宽带收发器,该收发器支持 IEEE 802.15.4/4z 高精度测距(HPR)UWB 操作。它包括一个完全嵌入的 FiRa 兼容 MAC 和 PHY,允许在发起者和响应者模式下无缝进行双向测距(TWR)会话,以及在到达时间差(TDoA)系统中的 Blink 模式操作。SR040 实现了小于 ±10cm 的卓越测距精度,典型接收灵敏度为 -92dBm。此外,模块还集成了 Nordic Semiconductor 的 nRF52833 芯片组,这是

一款完全认证的 Bluetooth SoC,支持 Bluetooth LE 5.4,可有效进行 UWB 测距会话的配置、设置和控制。nRF52833 提供最高 +8dBm 的发射功率和典型的 -96dBm 接收灵敏度。Sera NX040 通过标准 RX 和 TX 引脚通过 UART 接口与主机 MCU 通信。默认波特率为 115200bps,该设置确保了高效可靠的数据传输。除了 UART,此板还配备了用于 USB 2.0 FS(全速,12Mbps)的 USB Type-C 连接器,使其能够直接连接到 Sera NX040 模块的 USB 端口,实现灵活的集成。当使用 USB 接口时,整个系统由 MCP1826 LDO 稳压器提供的 3.3V 电源供电,该稳压器将 USB 的 5V 转换为 3.3V。为了开发和调试,模块提供了一个 SWDIO 接头,可访问 nRF52833 的 SWD(JTAG)接口,使其与 Nordic SDK 兼容。此接口对于利用高级功能和进行深入测试的开发人员至关重要。通过 Nordic SDK 提供全面的 USB 驱动程序支持,增强了模块在各种开发环境中的通用性。除了接口引脚外,此 Click board™ 还具有复位引脚(RST)和复位按钮用于模块重置。它还包括一个用

户引脚(BTN)和按钮(UBTN)用于交互式控制程序流。RGB LED 作为用户可配置的红色 LED 指示灯,提供各种状态的视觉反馈,如 UART 消息、启动过程或调试器命令。此外,该板还包括一个 NFC 天线连接器用于 NFC 应用和测试点用于调试和监控。TP1 和 TP2 作为 Sera NX040 的第二 UART 引脚,而 TP3、TP4 和 TP5 分别提供对 SR040 RST、SWCLK 和 SWDIO 引脚的访问。这些功能使测试和开发变得更加容易,使该板在广泛的应用中具有高度的通用性。在 UWB 4 Click 的底部,有 LP 切割痕迹。通过切割这些痕迹,可以通过断开 PWR LED 和 ClickID 电路来实现低功耗,从而节省额外的电力消耗。此 Click board™ 可以通过 VCC SEL 跳线选择使用 3.3V 或 5V 逻辑电压水平。由于 Sera NX040 模块在 3.3V 下工作,使用逻辑电平转换器 TXS0104 以实现正确操作和精确的信号电平转换。因此,3.3V 和 5V 兼容的 MCU 都可以正确使用通信线路。此外,这款 Click board™ 配备了包含易用功能的库和示例代码,可作为进一步开发的参考。

UWB 4 Click hardware overview image

功能概述

开发板

Nucleo-64搭载STM32L073RZ MCU提供了一个经济实惠且灵活的平台,供开发人员探索新的想法并原型化其设计。该板利用了STM32微控制器的多功能性,使用户能够为其项目选择性能和功耗之间的最佳平衡。它采用LQFP64封装的STM32微控制器,并包括一些必要的组件,例如用户LED,可以同时作为ARDUINO®信号使用,以及用户和复位按钮,以及用于精准定时操作的32.768kHz晶体振荡器。设计时考虑了扩展性和灵活性,Nucleo-64板具有ARDUINO® 

Uno V3扩展连接器和ST morpho扩展引脚标头,为全面项目集成提供了对STM32 I/O的完全访问权限。电源选项具有适应性,支持ST-LINK USB VBUS或外部电源,确保在各种开发环境中的适应性。该板还配备了一个内置的ST-LINK调试器/编程器,具有USB重新枚举功能,简化了编程和调试过程。此外,该板还设计了外部SMPS,以实现有效的Vcore逻辑供电,支持USB设备全速或USB SNK/UFP全速,以及内置的加密功能,增强了项目的功耗效率和安全性。通过专用

连接器提供了额外的连接性,用于外部SMPS实验、ST-LINK的USB连接器和MIPI®调试连接器,扩展了硬件接口和实验的可能性。开发人员将通过STM32Cube MCU软件包中全面的免费软件库和示例得到广泛的支持。这与与各种集成开发环境(IDE)的兼容性相结合,包括IAR Embedded Workbench®、MDK-ARM和STM32CubeIDE,确保了平稳高效的开发体验,使用户能够充分发挥Nucleo-64板在其项目中的功能。

Nucleo 64 with STM32L073RZ MCU double side image

微控制器概述 

MCU卡片 / MCU

default

建筑

ARM Cortex-M0

MCU 内存 (KB)

192

硅供应商

STMicroelectronics

引脚数

64

RAM (字节)

20480

你完善了我!

配件

Click Shield for Nucleo-64 配备了两个专有的 mikroBUS™ 插座,使得所有的 Click board™ 设备都可以轻松地与 STM32 Nucleo-64 开发板连接。这样,Mikroe 允许其用户从不断增长的 Click boards™ 范围中添加任何功能,如 WiFi、GSM、GPS、蓝牙、ZigBee、环境传感器、LED、语音识别、电机控制、运动传感器等。您可以使用超过 1537 个 Click boards™,这些 Click boards™ 可以堆叠和集成。STM32 Nucleo-64 开发板基于 64 引脚封装的微控制器,采用 32 位 MCU,配备 ARM Cortex M4 处理器,运行速度为 84MHz,具有 512Kb Flash 和 96KB SRAM,分为两个区域,顶部区域代表 ST-Link/V2 调试器和编程器,而底部区域是一个实际的开发板。通过 USB 连接方便地控制和供电这些板子,以便直接对 Nucleo-64 开发板进行编程和高效调试,其中还需要额外的 USB 线连接到板子上的 USB 迷你接口。大多数 STM32 微控制器引脚都连接到了板子左右边缘的 IO 引脚上,然后连接到两个现有的 mikroBUS™ 插座上。该 Click Shield 还有几个开关,用于选择 mikroBUS™ 插座上模拟信号的逻辑电平和 mikroBUS™ 插座本身的逻辑电压电平。此外,用户还可以通过现有的双向电平转换器,使用任何 Click board™,无论 Click board™ 是否在 3.3V 或 5V 逻辑电压电平下运行。一旦将 STM32 Nucleo-64 开发板与我们的 Click Shield for Nucleo-64 连接,您就可以访问数百个工作于 3.3V 或 5V 逻辑电压电平的 Click boards™。

Click Shield for Nucleo-64 accessories 1 image

EUB5850A3S-10MH4L NanoUWB天线在5850-8250 MHz频率范围内工作,覆盖UWB通道5、6、7、8和9,提供强大的覆盖范围。凭借3-dBi的增益,该天线为超宽带应用确保了最佳性能。其快速简便的安装方式,加上在潮湿环境以及冷热循环中牢固粘附的背胶,使其成为各种环境下的可靠选择。该天线符合RoHS标准,具有多功能性,可安装在各种非导电表面、不同厚度的表面,甚至在自由空间中,为平面和开放式安装提供了灵活性。

UWB 4 Click accessories 1 image

001-0022 FlexPIFA天线专为2.4 GHz BLE应用设计,提供2400-2480 MHz的频率范围,具有+2.0 dBi的峰值增益和优于-1.5 dBi的平均增益。该天线具有线性极化和小于2.0:1的VSWR,确保了高效的信号传输,并具有50 Ω的阻抗。安装快速简便,并符合RoHS标准,其背胶在潮湿和温度波动等严苛条件下仍能牢固粘附。FlexPIFA天线可以安装在各种非导电表面、金属附近,甚至靠近人体,非常适合可穿戴设备和紧凑型设备。

UWB 4 Click accessories 2 image

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
Reset
PC12
RST
ID COMM
PB12
CS
NC
NC
SCK
NC
NC
MISO
NC
NC
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
NC
NC
PWM
User Interaction Signal
PC14
INT
UART TX
PA2
TX
UART RX
PA3
RX
NC
NC
SCL
NC
NC
SDA
Power Supply
5V
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

UWB 4 Click Schematic schematic

一步一步来

项目组装

Click Shield for Nucleo-64 accessories 1 image hardware assembly

从选择您的开发板和Click板™开始。以Nucleo-64 with STM32L073RZ MCU作为您的开发板开始。

Click Shield for Nucleo-64 accessories 1 image hardware assembly
Nucleo 64 with STM32F401RE MCU front image hardware assembly
LTE IoT 5 Click front image hardware assembly
Prog-cut hardware assembly
LTE IoT 5 Click complete accessories setup image hardware assembly
Nucleo-64 with STM32XXX MCU Access MB 1 Mini B Conn - upright/background hardware assembly
Necto image step 2 hardware assembly
Necto image step 3 hardware assembly
Necto image step 4 hardware assembly
Necto image step 5 hardware assembly
Necto image step 6 hardware assembly
Clicker 4 for STM32F4 HA MCU Step hardware assembly
Necto No Display image step 8 hardware assembly
Necto image step 9 hardware assembly
Necto image step 10 hardware assembly
Debug Image Necto Step hardware assembly

实时跟踪您的结果

应用程序输出

1. 应用程序输出 - 在调试模式下,“应用程序输出”窗口支持实时数据监控,直接提供执行结果的可视化。请按照提供的教程正确配置环境,以确保数据正确显示。

2. UART 终端 - 使用UART Terminal通过USB to UART converter监视数据传输,实现Click board™与开发系统之间的直接通信。请根据项目需求配置波特率和其他串行设置,以确保正常运行。有关分步设置说明,请参考提供的教程

3. Plot 输出 - Plot功能提供了一种强大的方式来可视化实时传感器数据,使趋势分析、调试和多个数据点的对比变得更加直观。要正确设置,请按照提供的教程,其中包含使用Plot功能显示Click board™读数的分步示例。在代码中使用Plot功能时,请使用以下函数:plot(insert_graph_name, variable_name);。这是一个通用格式,用户需要将“insert_graph_name”替换为实际图表名称,并将“variable_name”替换为要显示的参数。

软件支持

库描述

该库包含 UWB 4 Click 驱动程序的 API。

关键功能:

  • uwb4_cmd_run - 此函数将指定命令发送到Click模块。

  • uwb4_cmd_set - 此函数为Click模块的指定命令设置一个值。

  • uwb4_reset_device - 此函数通过切换复位引脚的逻辑状态来重置设备。

开源

代码示例

完整的应用程序代码和一个现成的项目可以通过NECTO Studio包管理器直接安装到NECTO Studio 应用程序代码也可以在MIKROE的GitHub账户中找到。

/*!
 * @file main.c
 * @brief UWB 4 Click Example.
 *
 * # Description
 * This example demonstrates the use of UWB 4 click board by showing
 * the UWB ranging between two click boards configured as initiator and responder.
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the driver and logger.
 *
 * ## Application Task
 * Application task is split in few stages:
 *  - UWB4_POWER_UP:
 * Powers up the device and reads system information.
 *  - UWB4_CONFIG_EXAMPLE:
 * Configures device for UWB ranging.
 *  - UWB4_EXAMPLE:
 * Reads and parses the UWB ranging information.
 *
 * ## Additional Function
 * - static void uwb4_clear_app_buf ( void )
 * - static void uwb4_log_app_buf ( void )
 * - static err_t uwb4_process ( uwb4_t *ctx )
 * - static err_t uwb4_read_response ( uwb4_t *ctx, uint8_t *rsp )
 * - static err_t uwb4_power_up ( uwb4_t *ctx )
 * - static err_t uwb4_config_example ( uwb4_t *ctx )
 * - static err_t uwb4_example ( uwb4_t *ctx )
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "uwb4.h"
#include "generic_pointer.h"

// Comment out the line below to switch the example mode to responder
#define EXAMPLE_INITIATOR

// Default config for initiator and responder examples
#ifdef EXAMPLE_INITIATOR
    #define UWB_SESSION_ID          "1234"
    #define UWB_ROLE                "0"
    #define UWB_LOCAL_ADDRESS       "1111"
    #define UWB_REMOTE_ADDRESS      "2222"
    #define UWB_RANGING_INTERVAL    "500"
#else
    #define UWB_SESSION_ID          "1234"
    #define UWB_ROLE                "1"
    #define UWB_LOCAL_ADDRESS       "2222"
    #define UWB_REMOTE_ADDRESS      "1111"
    #define UWB_RANGING_INTERVAL    "500"
#endif

static uwb4_t uwb4;
static log_t logger;

// Application buffer size
#define APP_BUFFER_SIZE             256
#define PROCESS_BUFFER_SIZE         256

static uint8_t app_buf[ APP_BUFFER_SIZE ] = { 0 };
static int32_t app_buf_len = 0;

/**
 * @brief Example states.
 * @details Predefined enum values for application example state.
 */
typedef enum
{
    UWB4_POWER_UP = 1,
    UWB4_CONFIG_EXAMPLE,
    UWB4_EXAMPLE

} uwb4_app_state_t;

static uwb4_app_state_t app_state = UWB4_POWER_UP;

/**
 * @brief UWB 4 clearing application buffer.
 * @details This function clears memory of application buffer and reset its length.
 * @note None.
 */
static void uwb4_clear_app_buf ( void );

/**
 * @brief UWB 4 log application buffer.
 * @details This function logs data from application buffer to USB UART.
 * @note None.
 */
static void uwb4_log_app_buf ( void );

/**
 * @brief UWB 4 data reading function.
 * @details This function reads data from device and concatenates data to application buffer. 
 * @param[in] ctx : Click context object.
 * See #uwb4_t object definition for detailed explanation.
 * @return @li @c  0 - Read some data.
 *         @li @c -1 - Nothing is read.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t uwb4_process ( uwb4_t *ctx );

/**
 * @brief UWB 4 read response function.
 * @details This function waits for a response message, reads and displays it on the USB UART.
 * @param[in] ctx : Click context object.
 * See #uwb4_t object definition for detailed explanation.
 * @param[in] rsp  Expected response.
 * @return @li @c  0 - OK response.
 *         @li @c -2 - Timeout error.
 *         @li @c -3 - Command error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t uwb4_read_response ( uwb4_t *ctx, uint8_t *rsp );

/**
 * @brief UWB 4 power up function.
 * @details This function powers up the device and reads system information.
 * @param[in] ctx : Click context object.
 * See #uwb4_t object definition for detailed explanation.
 * @return @li @c    0 - OK.
 *         @li @c != 0 - Read response error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t uwb4_power_up ( uwb4_t *ctx );

/**
 * @brief UWB 4 config example function.
 * @details This function configures device for UWB ranging.
 * @param[in] ctx : Click context object.
 * See #uwb4_t object definition for detailed explanation.
 * @return @li @c    0 - OK.
 *         @li @c != 0 - Read response error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t uwb4_config_example ( uwb4_t *ctx );

/**
 * @brief UWB 4 example function.
 * @details This function reads and parses the UWB ranging information.
 * @param[in] ctx : Click context object.
 * See #uwb4_t object definition for detailed explanation.
 * @return @li @c    0 - OK.
 *         @li @c != 0 - Read response error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t uwb4_example ( uwb4_t *ctx );

void application_init ( void ) 
{
    log_cfg_t log_cfg;  /**< Logger config object. */
    uwb4_cfg_t uwb4_cfg;  /**< Click config object. */

    /** 
     * Logger initialization.
     * Default baud rate: 115200
     * Default log level: LOG_LEVEL_DEBUG
     * @note If USB_UART_RX and USB_UART_TX 
     * are defined as HAL_PIN_NC, you will 
     * need to define them manually for log to work. 
     * See @b LOG_MAP_USB_UART macro definition for detailed explanation.
     */
    LOG_MAP_USB_UART( log_cfg );
    log_init( &logger, &log_cfg );
    log_info( &logger, " Application Init " );

    // Click initialization.
    uwb4_cfg_setup( &uwb4_cfg );
    UWB4_MAP_MIKROBUS( uwb4_cfg, MIKROBUS_1 );
    if ( UART_ERROR == uwb4_init( &uwb4, &uwb4_cfg ) ) 
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    log_info( &logger, " Application Task " );

    app_state = UWB4_POWER_UP;
    log_printf( &logger, ">>> APP STATE - POWER UP <<<\r\n\n" );
}

void application_task ( void ) 
{
    switch ( app_state )
    {
        case UWB4_POWER_UP:
        {
            if ( UWB4_OK == uwb4_power_up( &uwb4 ) )
            {
                app_state = UWB4_CONFIG_EXAMPLE;
                log_printf( &logger, ">>> APP STATE - CONFIG EXAMPLE <<<\r\n\n" );
            }
            break;
        }
        case UWB4_CONFIG_EXAMPLE:
        {
            if ( UWB4_OK == uwb4_config_example( &uwb4 ) )
            {
                app_state = UWB4_EXAMPLE;
                log_printf( &logger, ">>> APP STATE - EXAMPLE <<<\r\n\n" );
            }
            break;
        }
        case UWB4_EXAMPLE:
        {
            uwb4_example( &uwb4 );
            break;
        }
        default:
        {
            log_error( &logger, " APP STATE." );
            break;
        }
    }
}

int main ( void ) 
{
    /* Do not remove this line or clock might not be set correctly. */
    #ifdef PREINIT_SUPPORTED
    preinit();
    #endif
    
    application_init( );
    
    for ( ; ; ) 
    {
        application_task( );
    }

    return 0;
}

static void uwb4_clear_app_buf ( void ) 
{
    memset( app_buf, 0, app_buf_len );
    app_buf_len = 0;
}

static void uwb4_log_app_buf ( void )
{
    for ( int32_t buf_cnt = 0; buf_cnt < app_buf_len; buf_cnt++ )
    {
        log_printf( &logger, "%c", app_buf[ buf_cnt ] );
    }
}

static err_t uwb4_process ( uwb4_t *ctx ) 
{
    uint8_t rx_buf[ PROCESS_BUFFER_SIZE ] = { 0 };
    int32_t overflow_bytes = 0;
    int32_t rx_cnt = 0;
    int32_t rx_size = uwb4_generic_read( ctx, rx_buf, PROCESS_BUFFER_SIZE );
    if ( ( rx_size > 0 ) && ( rx_size <= APP_BUFFER_SIZE ) ) 
    {
        if ( ( app_buf_len + rx_size ) > APP_BUFFER_SIZE ) 
        {
            overflow_bytes = ( app_buf_len + rx_size ) - APP_BUFFER_SIZE;
            app_buf_len = APP_BUFFER_SIZE - rx_size;
            memmove ( app_buf, &app_buf[ overflow_bytes ], app_buf_len );
            memset ( &app_buf[ app_buf_len ], 0, overflow_bytes );
        }
        for ( rx_cnt = 0; rx_cnt < rx_size; rx_cnt++ ) 
        {
            if ( rx_buf[ rx_cnt ] ) 
            {
                app_buf[ app_buf_len++ ] = rx_buf[ rx_cnt ];
            }
        }
        return UWB4_OK;
    }
    return UWB4_ERROR;
}

static err_t uwb4_read_response ( uwb4_t *ctx, uint8_t *rsp ) 
{
    #define READ_RESPONSE_TIMEOUT_MS    30000
    uint32_t timeout_cnt = 0;
    uwb4_clear_app_buf ( );
    uwb4_process( ctx );
    while ( ( 0 == strstr( app_buf, rsp ) ) &&
            ( 0 == strstr( app_buf, UWB4_RSP_ERROR ) ) )
    {
        uwb4_process( ctx );
        if ( timeout_cnt++ > READ_RESPONSE_TIMEOUT_MS )
        {
            uwb4_clear_app_buf( );
            log_error( &logger, " Timeout!" );
            return UWB4_ERROR_TIMEOUT;
        }
        Delay_ms( 1 );
    }
    Delay_ms ( 200 );
    uwb4_process( ctx );
    if ( strstr( app_buf, rsp ) )
    {
        uwb4_log_app_buf( );
        log_printf( &logger, "--------------------------------\r\n" );
        return UWB4_OK;
    }
    log_error( &logger, " CMD!" );
    return UWB4_ERROR_CMD;
}

static err_t uwb4_power_up ( uwb4_t *ctx )
{
    err_t error_flag = UWB4_OK;
    
    log_printf( &logger, ">>> Reset device.\r\n" );
    uwb4_reset_device( &uwb4 );
    while ( UWB4_OK == uwb4_process( ctx ) )
    {
        uwb4_log_app_buf( );
        uwb4_clear_app_buf ( );
    }
    log_printf( &logger, "--------------------------------\r\n" );

    log_printf( &logger, ">>> Check communication.\r\n" );
    uwb4_cmd_run( &uwb4, UWB4_CMD_AT );
    error_flag |= uwb4_read_response( &uwb4, UWB4_RSP_OK );

    log_printf( &logger, ">>> Enable echo.\r\n" );
    uwb4_cmd_run( &uwb4, UWB4_CMD_ENABLE_ECHO );
    error_flag |= uwb4_read_response( &uwb4, UWB4_RSP_OK );
    
    log_printf( &logger, ">>> Get module name.\r\n" );
    uwb4_cmd_run( ctx, UWB4_CMD_GET_MODULE_NAME );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );

    log_printf( &logger, ">>> Get device firmware version.\r\n" );
    uwb4_cmd_run( ctx, UWB4_CMD_GET_FIRMWARE_VERSION );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );

    log_printf( &logger, ">>> Get device serial number.\r\n" );
    uwb4_cmd_run( ctx, UWB4_CMD_GET_UNIQUE_ID );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );

    return error_flag;
}

static err_t uwb4_config_example ( uwb4_t *ctx )
{
    err_t error_flag = UWB4_OK;
    uint8_t param_buf[ 100 ] = { 0 };
#ifdef EXAMPLE_INITIATOR
    log_printf( &logger, ">>> Create a new initiator UWB session.\r\n" );
#else
    log_printf( &logger, ">>> Create a new responder UWB session.\r\n" );
#endif
    strcpy( param_buf, UWB_SESSION_ID );
    strcat( param_buf, "," );
    strcat( param_buf, UWB_ROLE );
    uwb4_cmd_set( ctx, UWB4_CMD_CREATE_SESSION, param_buf );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );
    log_printf( &logger, ">>> Set local and remote addresses.\r\n" );
    strcpy( param_buf, UWB_SESSION_ID );
    strcat( param_buf, "," );
    strcat( param_buf, UWB_LOCAL_ADDRESS );
    strcat( param_buf, "," );
    strcat( param_buf, UWB_REMOTE_ADDRESS );
    uwb4_cmd_set( ctx, UWB4_CMD_SET_ADDRESS, param_buf );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );
    log_printf( &logger, ">>> Set ranging interval.\r\n" );
    strcpy( param_buf, UWB_SESSION_ID );
    strcat( param_buf, "," );
    strcat( param_buf, UWB_RANGING_INTERVAL );
    uwb4_cmd_set( ctx, UWB4_CMD_SET_RANGING_INTERVAL, param_buf );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );
    log_printf( &logger, ">>> Start the UWB session.\r\n" );
    uwb4_cmd_set( ctx, UWB4_CMD_START_SESSION, UWB_SESSION_ID );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_OK );
    return error_flag;
}

static err_t uwb4_example ( uwb4_t *ctx )
{
    err_t error_flag = UWB4_OK;
    uint8_t session_id[ 10 ] = { 0 };
    uint8_t remote_addr[ 10 ] = { 0 };
    uint8_t distance[ 10 ] = { 0 };

    log_printf( &logger, ">>> Reading distance to the remote device.\r\n" );
    error_flag |= uwb4_read_response( ctx, UWB4_RSP_RANGE );
    
    uint8_t * __generic_ptr start_ptr = strstr( app_buf, UWB4_RSP_RANGE );
    uint8_t * __generic_ptr end_ptr = NULL;
    if ( start_ptr )
    {
        start_ptr = start_ptr + strlen ( UWB4_RSP_RANGE );
        end_ptr = strstr ( start_ptr, " " );
        memcpy ( session_id, start_ptr, end_ptr - start_ptr );
        
        start_ptr = end_ptr + 1;
        end_ptr = strstr ( start_ptr, " " );
        memcpy ( remote_addr, start_ptr, end_ptr - start_ptr );

        start_ptr = end_ptr + 1;
        end_ptr = strstr ( start_ptr, "\r\n" );
        memcpy ( distance, start_ptr, end_ptr - start_ptr );

        log_printf( &logger, ">>> Parse received message.\r\n" );
        if ( strstr ( distance, "65535" ) )
        {
            log_printf ( &logger, " No remote device found.\r\n" );
        }
        else
        {
            log_printf ( &logger, " Session ID: %s\r\n", session_id );
            log_printf ( &logger, " Remote address: %s\r\n", remote_addr );
            log_printf ( &logger, " Distance: %s cm\r\n", distance );
        }
        log_printf( &logger, "--------------------------------\r\n" );
    }
    return error_flag;
}

// ------------------------------------------------------------------------ END

额外支持

资源

喜欢这个项目吗?

'购买此套件' 按钮会直接带您进入购物车,您可以在购物车中轻松添加或移除产品。