中级
20 分钟

使用 Tarvos-III(2609011081000)和 ATmega328 实现 868MHz SRD 频段的远距离无线通信

面向可扩展物联网的远距离、低功耗 868MHz 无线解决方案

ISM 7 Click with Arduino UNO Rev3

已发布 5月 12, 2025

点击板

ISM 7 Click

开发板

Arduino UNO Rev3

编译器

NECTO Studio

微控制器单元

ATmega328

支持 Flooding Mesh 的 868MHz 长距离无线通信,通信范围可达 300 米

A

A

硬件概览

它是如何工作的?

ISM 7 Click 基于 Würth Elektronik 推出的 Tarvos-III 无线模块(型号 2609011081000),专为 868MHz SRD 频段内的无线通信应用而设计。该模块集成了高性能的 sub-GHz 收发器 Texas Instruments CC1310,具备一个 32 位 ARM Cortex-M3 处理器、128kB 的闪存和 20kB 的 RAM,能够同时处理通信任务并运行用户自定义的应用程序代码。其支持的频率范围覆盖 863MHz 到 870MHz,在视距条件下可实现最长 300 米的稳定通信距离。凭借 -8dBm 的发射功率和高达 -104dBm 的接收灵敏度,ISM 7 Click 即便在干扰严重或复杂的环境中也能保持可靠的无线连接。该 Click 板非常适用于各种长距离、低功耗的物联网通信应用,如智能计量、工业监测、楼宇自动化、农业感测系统和物流追踪等。Tarvos-III 模块设计注重能效管理,特别适合用于电池供电的低功耗系统中。模块集成的软件栈支持先进的网络功能,包括 Flooding Mesh 技术,在大范围传感器网络中实现强

健的多跳通信能力。其地址配置系统高度灵活,最多可支持 65,535 个设备并划分为多达 255 个独立网络,为大规模 IoT 部署提供强大扩展性。ISM 7 Click 通过 UART 接口与主控 MCU 通信,使用标准的 RX 和 TX 引脚及 RTS 硬件流控引脚进行数据传输,默认通信速率为 115200bps。板上包含两个配置拨码开关,分别用于控制模块的启动模式和工作模式。BOOT 拨码开关用于选择启动方式,拨至位置 0 时,模块将运行预加载的应用固件,拨至位置 1 时,模块进入 UART 启动模式,用于执行固件升级。MODE 拨码开关用于设定模块的启动工作模式,拨至位置 0 将模块设置为命令模式,允许用户通过 UART 使用类 AT 命令进行配置与控制;拨至位置 1 时,模块进入透明传输模式,在该模式下所有接收到的 UART 数据将直接通过无线发送。除了通信和控制引脚,ISM 7 Click 还包含一个复位引脚(RST)和一个 RESET 按钮,用于轻松实现模块的软硬件重启,还配有一个 

WUP 唤醒引脚,可从关断模式中唤醒模块。板上配有两颗状态 LED 指示灯,绿色 TX 灯表示数据发送状态,红色 RX 灯表示数据接收状态,方便开发与调试过程中的实时状态反馈。Tarvos-III(2609011081000)模块默认配备板载天线,支持标准无线应用。考虑到模块封装的一致性,ISM 7 Click 板也兼容另一版本的 Tarvos-III 模块(型号 2609011181000),该版本支持外接天线。为此,板上还预留了一个未焊接的外部天线连接器,可用于集成如 ISM 868/915MHz 主动 PCB 天线等外部天线。除此之外,该板还包含标准的 JTAG 接口焊盘,方便进行设计验证与电路板调试。ISM 7 Click 仅支持 3.3V 逻辑电压工作环境,若与其他逻辑电压等级的 MCU 配合使用,需进行适当的电平转换。该 Click 板配备了易于使用的软件库和示例代码,可作为开发参考,帮助用户快速构建和扩展其无线通信系统。

ISM 7 Click hardware overview image

功能概述

开发板

Arduino UNO 是围绕 ATmega328P 芯片构建的多功能微控制器板。它为各种项目提供了广泛的连接选项,具有 14 个数字输入/输出引脚,其中六个支持 PWM 输出,以及六个模拟输入。其核心组件包括一个 16MHz 的陶瓷谐振器、一个 USB 连接器、一个电

源插孔、一个 ICSP 头和一个复位按钮,提供了为板 子供电和编程所需的一切。UNO 可以通过 USB 连接到计算机,也可以通过 AC-to-DC 适配器或电池供电。作为第一个 USB Arduino 板,它成为 Arduino 平台的基准,"Uno" 符号化其作为系列首款产品的地

位。这个名称选择,意为意大利语中的 "一",是为了 纪念 Arduino Software(IDE)1.0 的推出。最初与 Arduino Software(IDE)版本1.0 同时推出,Uno 自此成为后续 Arduino 发布的基础模型,体现了该平台的演进。

Arduino UNO Rev3 double side image

微控制器概述 

MCU卡片 / MCU

default

建筑

AVR

MCU 内存 (KB)

32

硅供应商

Microchip

引脚数

32

RAM (字节)

2048

你完善了我!

配件

Click Shield for Arduino UNO 具有两个专有的 mikroBUS™ 插座,使所有 Click board™ 设备能够轻松与 Arduino UNO 板进行接口连接。Arduino UNO 是一款基于 ATmega328P 的微控制器开发板,为用户提供了一种经济实惠且灵活的方式来测试新概念并构建基于 ATmega328P 微控制器的原型系统,结合了性能、功耗和功能的多种配置选择。Arduino UNO 具有 14 个数字输入/输出引脚(其中 6 个可用作 PWM 输出)、6 个模拟输入、16 MHz 陶瓷谐振器(CSTCE16M0V53-R0)、USB 接口、电源插座、ICSP 头和复位按钮。大多数 ATmega328P 微控制器的引脚都连接到开发板左右两侧的 IO 引脚,然后再连接到两个 mikroBUS™ 插座。这款 Click Shield 还配备了多个开关,可执行各种功能,例如选择 mikroBUS™ 插座上模拟信号的逻辑电平,以及选择 mikroBUS™ 插座本身的逻辑电压电平。此外,用户还可以通过现有的双向电平转换电压转换器使用任何 Click board™,无论 Click board™ 运行在 3.3V 还是 5V 逻辑电压电平。一旦将 Arduino UNO 板与 Click Shield for Arduino UNO 连接,用户即可访问数百种 Click board™,并兼容 3.3V 或 5V 逻辑电压电平的设备。

Click Shield for Arduino UNO accessories 1 image

使用的MCU引脚

mikroBUS™映射器

NC
NC
AN
Reset
PD2
RST
ID COMM
PB2
CS
NC
NC
SCK
NC
NC
MISO
NC
NC
MOSI
Power Supply
3.3V
3.3V
Ground
GND
GND
Module Wake-Up
PD6
PWM
UART RTS
PC3
INT
UART TX
PD0
TX
UART RX
PD1
RX
NC
NC
SCL
NC
NC
SDA
NC
NC
5V
Ground
GND
GND
1

“仔细看看!”

Click board™ 原理图

ISM 7 Click Schematic schematic

一步一步来

项目组装

Click Shield for Arduino UNO front image hardware assembly

从选择您的开发板和Click板™开始。以Arduino UNO Rev3作为您的开发板开始。

Click Shield for Arduino UNO front image hardware assembly
Arduino UNO Rev3 front image hardware assembly
Charger 27 Click front image hardware assembly
Prog-cut hardware assembly
Charger 27 Click complete accessories setup image hardware assembly
Board mapper by product8 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
Arduino UNO 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”替换为要显示的参数。

软件支持

库描述

ISM 7 Click 演示应用程序使用 NECTO Studio开发,确保与 mikroSDK 的开源库和工具兼容。该演示设计为即插即用,可与所有具有 mikroBUS™ 插座的 开发板、入门板和 mikromedia 板完全兼容,用于快速实现和测试。

示例描述
本示例演示如何使用 ISM 7 Click 板,通过两个 Click 板之间的通信展示其无线传输能力。

关键功能:

  • ism7_cfg_setup - 初始化 Click 配置结构为默认初始值。

  • ism7_init - 初始化该 Click 板所需的所有引脚和外设。

  • ism7_send_cmd - 从 Click 上下文对象中发送所需命令包。

  • ism7_read_event - 从环形缓冲区中读取事件数据包并存储到 Click 上下文对象中。

  • ism7_get_user_setting - 从指定用户设置索引读取数据,并将其存储到事件数据包对象中。

应用初始化
初始化驱动程序,重置 Click 板,读取设备信息,并发送初始消息以启动与另一块 Click 板的通信。

应用任务
持续读取并解析所有接收到的事件数据包,并通过 USB UART 显示。系统将回显所有来自已连接设备的接收数据,实现基本的双向通信演示。

开源

代码示例

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

/*!
 * @file main.c
 * @brief ISM 7 Click Example.
 *
 * # Description
 * This example demonstrates the use of ISM 7 Click board by showing
 * the communication between two Click boards.
 *
 * The demo application is composed of two sections :
 *
 * ## Application Init
 * Initializes the driver, resets the Click board, reads the device info, and sends
 * a message to initiate the communication with other Click board.
 *
 * ## Application Task
 * Reads and parses all the received event packets and displays them the USB UART.
 * All incoming data messages received from the connected device will be echoed back.
 *
 * ## Additional Function
 * - static err_t ism7_parse_cnf ( ism7_t *ctx )
 * - static err_t ism7_parse_ind ( ism7_t *ctx )
 * - static err_t ism7_parse_event ( ism7_t *ctx )
 *
 * @author Stefan Filipovic
 *
 */

#include "board.h"
#include "log.h"
#include "ism7.h"

// Text message to send to initiate communication
#define DEMO_TEXT_MESSAGE   "MIKROE - ISM 7 Click board"

static ism7_t ism7;
static log_t logger;

/**
 * @brief ISM 7 parse cnf function.
 * @details This function parses all received confirmation packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #ism7_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t ism7_parse_cnf ( ism7_t *ctx );

/**
 * @brief ISM 7 parse ind function.
 * @details This function parses all received indication packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #ism7_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t ism7_parse_ind ( ism7_t *ctx );

/**
 * @brief ISM 7 parse event function.
 * @details This function parses all received packets and displays them on the USB UART.
 * @param[in] ctx : Click context object.
 * See #ism7_t object definition for detailed explanation.
 * @return @li @c 0 - Packet parsed successfully,
 *         @li @c 1 - Error.
 * See #err_t definition for detailed explanation.
 * @note None.
 */
static err_t ism7_parse_event ( ism7_t *ctx );

void application_init ( void ) 
{
    log_cfg_t log_cfg;  /**< Logger config object. */
    ism7_cfg_t ism7_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.
    ism7_cfg_setup( &ism7_cfg );
    ISM7_MAP_MIKROBUS( ism7_cfg, MIKROBUS_1 );
    if ( UART_ERROR == ism7_init( &ism7, &ism7_cfg ) ) 
    {
        log_error( &logger, " Communication init." );
        for ( ; ; );
    }
    
    log_printf( &logger, ">> Reset device.\r\n" );
    if ( ISM7_ERROR == ism7_reset_device ( &ism7 ) )
    {
        log_error( &logger, " Reset device." );
        for ( ; ; );
    }
    
    log_printf( &logger, ">> Get device info.\r\n" );
    if ( ISM7_OK == ism7_get_user_setting ( &ism7, ISM7_SET_IDX_FACTORY_SETTINGS ) ) 
    {
        log_printf( &logger, " < Serial number: 0x%.2X%.2X%.2X%.2X\r\n", 
                    ( uint16_t ) ism7.evt_pkt.payload[ 4 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 3 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 2 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 1 ] );
        log_printf( &logger, "   Hardware version: %u.%u.%u\r\n", 
                    ( uint16_t ) ism7.evt_pkt.payload[ 5 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 6 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 7 ] );
        log_printf( &logger, "   Frequency correction factor: %u\r\n",  
                    ( uint16_t ) ism7.evt_pkt.payload[ 8 ] );
    }

    log_printf( &logger, ">> Get FW version.\r\n" );
    if ( ISM7_OK == ism7_get_user_setting ( &ism7, ISM7_SET_IDX_FIRMWARE_VERSION ) ) 
    {
        log_printf( &logger, " < FW version: %u.%u.%u\r\n\n", 
                    ( uint16_t ) ism7.evt_pkt.payload[ 3 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 2 ], 
                    ( uint16_t ) ism7.evt_pkt.payload[ 1 ] );
    }

    log_printf( &logger, ">> Send message to initiate communication.\r\n" );
    ism7.cmd_pkt.cmd = ISM7_CMD_REQ_DATA;
    ism7.cmd_pkt.payload_len = strlen ( DEMO_TEXT_MESSAGE );
    strcpy ( ism7.cmd_pkt.payload, DEMO_TEXT_MESSAGE );
    if ( ISM7_OK == ism7_send_cmd ( &ism7 ) )
    {
        if ( ISM7_OK == ism7_wait_for_event ( &ism7, ISM7_CMD_CNF_DATA, ISM7_WAIT_TIME_1S ) ) 
        {
            ism7_parse_event ( &ism7 );
        }
    }

    log_info( &logger, " Application Task " );
}

void application_task ( void ) 
{
    if ( ISM7_OK == ism7_read_event ( &ism7 ) ) 
    {
        ism7_parse_event ( &ism7 );
    }
}

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 err_t ism7_parse_cnf ( ism7_t *ctx )
{
    err_t error_flag = ISM7_OK;
    uint16_t byte_cnt = 0;

    if ( ISM7_CMD_TYPE_CNF == ( ctx->evt_pkt.cmd & ISM7_CMD_TYPE_MASK ) )
    {
        // Parse confirmation packet
        switch ( ctx->evt_pkt.cmd )
        {
            case ISM7_CMD_CNF_GET:
            {
                log_printf( &logger, " < GET_CNF -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case ISM7_CNF_GET_STATUS_OK:
                    {
                        log_printf( &logger, "Request successfully received and processed" );
                        break;
                    }
                    case ISM7_CNF_GET_STATUS_FAILED:
                    {
                        log_printf( &logger, "Request not successful" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown status: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                if ( ctx->evt_pkt.payload_len > 1 )
                {
                    log_printf( &logger, "\r\n   Setting: " );
                    for ( byte_cnt = 1; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                    {
                        log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                    }
                }
                break;
            }
            case ISM7_CMD_CNF_DATA:
            {
                log_printf( &logger, " < DATA_CNF -> " );
                switch ( ctx->evt_pkt.payload[ 0 ] )
                {
                    case ISM7_CNF_DATA_STATUS_ACK:
                    {
                        log_printf( &logger, "ACK received or not requested" );
                        break;
                    }
                    case ISM7_CNF_DATA_STATUS_NACK:
                    {
                        log_printf( &logger, "No ACK received within a time-out " );
                        break;
                    }
                    case ISM7_CNF_DATA_STATUS_INVALID_CH:
                    {
                        log_printf( &logger, "Invalid channel selected" );
                        break;
                    }
                    case ISM7_CNF_DATA_STATUS_RADIO_CH_BUSY:
                    {
                        log_printf( &logger, "Radio channel busy (LBT)" );
                        break;
                    }
                    case ISM7_CNF_DATA_STATUS_MODULE_BUSY:
                    {
                        log_printf( &logger, "Module is currently busy" );
                        break;
                    }
                    case ISM7_CNF_DATA_STATUS_INVALID:
                    {
                        log_printf( &logger, "Invalid (payload too long)" );
                        break;
                    }
                    default:
                    {
                        log_printf( &logger, "Unknown status: 0x%.2X", ( uint16_t ) ctx->evt_pkt.payload[ 0 ] );
                        break;
                    }
                }
                Delay_ms ( 1000 );
                break;
            }
            default:
            {
                log_printf( &logger, " < CMD_CNF 0x%.2X -> ", ( uint16_t ) ctx->evt_pkt.cmd );
                for ( byte_cnt = 0; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                break;
            }
        }
        log_printf( &logger, "\r\n\n" );
    }
    else
    {
        // Wrong packet type
        error_flag |= ISM7_ERROR;
    }
    return error_flag;
}

static err_t ism7_parse_ind ( ism7_t *ctx )
{
    err_t error_flag = ISM7_OK;
    uint16_t byte_cnt = 0;

    if ( ISM7_CMD_TYPE_IND == ( ctx->evt_pkt.cmd & ISM7_CMD_TYPE_MASK ) )
    {
        // Parse indication packet
        switch ( ctx->evt_pkt.cmd )
        {
            case ISM7_CMD_IND_DATAEX:
            {
                log_printf( &logger, " < DATAEX_IND -> " );
                log_printf( &logger, "Field strength: %d\r\n", 
                            ( int16_t ) ( ( int8_t ) ctx->evt_pkt.payload[ ctx->evt_pkt.payload_len - 1 ] ) );
                log_printf( &logger, "   Data (HEX): " );
                for ( byte_cnt = 0; byte_cnt < ( ctx->evt_pkt.payload_len - 1 ); byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                Delay_ms ( 10 );
                ctx->evt_pkt.payload[ ctx->evt_pkt.payload_len - 1 ] = 0;
                log_printf( &logger, "\r\n   Data (STR): %s", &ctx->evt_pkt.payload[ 0 ] );
                
                log_printf( &logger, "\r\n\n>> Echo back the received message." );
                ctx->cmd_pkt.cmd = ISM7_CMD_REQ_DATA;
                ctx->cmd_pkt.payload_len = ctx->evt_pkt.payload_len - 1;
                memcpy ( &ctx->cmd_pkt.payload[ 0 ], &ctx->evt_pkt.payload[ 0 ], ctx->evt_pkt.payload_len - 1 );
                error_flag |= ism7_send_cmd ( ctx );
                break;
            }
            default:
            {
                log_printf( &logger, " < CMD_IND 0x%.2X -> ", ( uint16_t ) ctx->evt_pkt.cmd );
                for ( byte_cnt = 0; byte_cnt < ctx->evt_pkt.payload_len; byte_cnt++ )
                {
                    log_printf( &logger, "0x%.2X ", ( uint16_t ) ctx->evt_pkt.payload[ byte_cnt ] );
                }
                break;
            }
        }
        log_printf( &logger, "\r\n\n" );
    }
    else
    {
        // Wrong packet type
        error_flag |= ISM7_ERROR;
    }
    return error_flag;
}

static err_t ism7_parse_event ( ism7_t *ctx )
{
    err_t error_flag = ISM7_OK;

    if ( ISM7_CMD_TYPE_CNF == ( ctx->evt_pkt.cmd & ISM7_CMD_TYPE_MASK ) )
    {
        error_flag |= ism7_parse_cnf ( ctx );
    }
    else if ( ISM7_CMD_TYPE_IND == ( ctx->evt_pkt.cmd & ISM7_CMD_TYPE_MASK ) )
    {
        error_flag |= ism7_parse_ind ( ctx );
    }
    else
    {
        // Error packet should not be a command request
        error_flag |= ISM7_ERROR;
    }
    return error_flag;
}

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

额外支持

资源

喜欢这个项目吗?

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