初学者
10 分钟

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

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

UWB 4 Click with Flip&Click PIC32MZ

已发布 8月 19, 2024

点击板

UWB 4 Click

开发板

Flip&Click PIC32MZ

编译器

NECTO Studio

微控制器单元

PIC32MZ2048EFH100

将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

功能概述

开发板

Flip&Click PIC32MZ 是一款紧凑型开发板,设计为一套完整的解决方案,它将 Click 板™的灵活性带给您喜爱的微控制器,使其成为实现您想法的完美入门套件。它配备了一款板载 32 位 PIC32MZ 微控制器,Microchip 的 PIC32MZ2048EFH100,四个 mikroBUS™ 插槽用于 Click 板™连接,两个 USB 连接器,LED 指示灯,按钮,调试器/程序员连接器,以及两个与 Arduino-UNO 引脚兼容的头部。得益于创

新的制造技术,它允许您快速构建具有独特功能和特性的小工具。Flip&Click PIC32MZ 开发套件的每个部分都包含了使同一板块运行最高效的必要组件。此外,还可以选择 Flip&Click PIC32MZ 的编程方式,使用 chipKIT 引导程序(Arduino 风格的开发环境)或我们的 USB HID 引导程序,使用 mikroC、mikroBasic 和 mikroPascal for PIC32。该套件包括一个通过 USB 类型-C(USB-C)连接器的干净且调

节过的电源供应模块。所有 mikroBUS™ 本身支持的 通信方法都在这块板上,包括已经建立良好的 mikroBUS™ 插槽、用户可配置的按钮和 LED 指示灯。Flip&Click PIC32MZ 开发套件允许您在几分钟内创建新的应用程序。它由 Mikroe 软件工具原生支持,得益于大量不同的 Click 板™(超过一千块板),其数量每天都在增长,它涵盖了原型制作的许多方面。

Flip&Click PIC32MZ double image

微控制器概述 

MCU卡片 / MCU

default

建筑

PIC32

MCU 内存 (KB)

2048

硅供应商

Microchip

引脚数

100

RAM (字节)

524288

你完善了我!

配件

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
RE2
RST
ID COMM
RA0
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
RD9
INT
UART TX
RE3
TX
UART RX
RG9
RX
NC
NC
SCL
NC
NC
SDA
Power Supply
5V
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

UWB 4 Click Schematic schematic

一步一步来

项目组装

Flip&Click PIC32MZ front image hardware assembly

从选择您的开发板和Click板™开始。以Flip&Click PIC32MZ作为您的开发板开始。

Flip&Click PIC32MZ front image hardware assembly
GNSS2 Click front image hardware assembly
Prog-cut hardware assembly
GNSS2 Click complete accessories setup image hardware assembly
Flip&Click PIC32MZ MB1 Access - 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
Flip&Click PIC32MZ 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

额外支持

资源

喜欢这个项目吗?

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