This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC2652R:运行另一个应用程序以读取传感器读数、同时运行 ZED 示例

Guru**** 2538950 points
Other Parts Discussed in Thread: Z-STACK

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1018833/cc2652r-running-another-application-for-sensor-reading-alongside-a-zed-example

器件型号:CC2652R
Thread 中讨论的其他器件:Z-stack

您好 TI!

我想利用 Z-Stack 来告诉我的 ZC 打开/关闭我的 ZED 上的光。 打开/关闭的条件来自对通过 I2C 连接到 ZED 的持续运行传感器的数据进行一些处理。

现在、我希望此传感器应用与其中一个 ZED 示例配合使用、例如 zed_sw、在这里、我的传感器任务会运行、直到状态变化得到确认并通知我的 zed_sw 向 ZC 发送开/关切换。 之后、传感器任务再次运行。 需要记住的是将我的传感器代码实施到 zed_sw 中或创建新任务。 这是可行的吗? 我应该如何推进?

提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、christng、

    您可以调整 i2ctmp TI 驱动程序示例或您开发的 I2C 代码并将其直接移植到 zed_samplesw.c 中、其中初始化在 zclSampleSw_Init 中进行处理、I2C 回调直接调用 zclGeneral_SendOnOff_CmdToggle 或创建一个应用程序事件(通常在 zcl_samplesw.h 中定义)、以便在 zcl_samplesw_loop 中直接处理 。  这也是使用传感器控制 器的绝佳机会、请参考 Sensor Controller Studio 示例和 SimpleLink Academy Labs。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您还可以参阅 sunmaysky.blogspot.com/.../basic-example-to-use-hdc1080-on-cc2650.html 中的示例代码

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复和建议。 我直到最近才收到通知、因此我一直在考虑为我的存在传感器读数引入一项新任务。 我这样做的原因是、它感觉在传感器应用上的工作较少、因为它独立工作。 此外,我感谢大家的耐心。 我正在伸展到一个巨大的未知领域、这里的一切都是如此。

    我在 zed_SampleApp 上尝试过这种方法、而不是在 CUI 被禁用的情况下尝试 zed_SW (因为我的传感器应用使用 display_UART 进行传感器打印)。

    到目前为止,我所做的是:

    1. 已构建优先级低于 zed_SampleApp 的新任务。
    2. 引入了一个共享全局变量、它是一个 bool 存在
    3. 引入了一个新的信号量信号量信号2、每当检测到存在变化时、该信号量信号就会从我的传感器应用程序发出。
    4. zed_sw process_loop 中的一个非等待 semaphore_pend (sem2)、当  sem2被发布时、该函数会将本地 bool newChange 更改为 true。

    我想进一步做些什么:

    1. process_loop 中的 updatePresence ()函数,根据 bool 的存在情况调用 zclGeneral_SendOnOff_CmdToggle,然后将本地 bool  newChange 更改为 false。

    我希望这是有道理的。

    因此、我认为、由于 TIRTOS 基于抢先式调度、因此共享变量的冲突不应成为问题、因为一个只读取、另一个只写入该变量。 只要 z-stack-task 和 zed_sw-task 没有关系、传感器任务就会进行处理和报告。 具有更高优先级的任务在需要时运行、不会发生冲突? zed_sw-task 每~1循环一次,因此将在合理的时间内调用 updatePresence ()。

    我现在需要在 zed_sw 上执行所有这些操作

    我的问题:

    1. 是否可以在没有 UART 功能的情况下使用 CUI? 我只需要按钮调试的处理程序。
    2. 如何在没有 CUI 的情况下管理 BDB 试运转?
    3. 您对我的方法有什么意见吗?

    提前感谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1.是的

    2.您可以使用 API  bdb_StartCommissioning

    3.我建议您创建一个周期性事件来进行传感器读取。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1.删除 Board_display_use_UART
    参考  zclSampleSw_processKey 的 CONFIG_BTN_LEFT
    3.周期计时器(请参阅 zclSampleSw_initializeClocks)的复杂度会降低

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的快速回复! 我将研究周期性事件。

    周末愉快

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好

    传感器读数行为现在似乎可以正常工作、但我的建议有问题。 我再次尝试使用默认示例。

    将两个 LP-CC2652R 与用于规划 ZED 的 bdb-commimming 配合使用时、会在以下之间切换其状态:

    已初始化->已发现->正在加入->已加入不安全->正在加入->已加入不安全->已初始化。

    这是在新导入的 zed_sw 和 zc_light 示例上完成的。 我还尝试重置为 FN 并重新连接两个 Launchpad、但仍会出现相同的行为。

    如何解决此问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尝试批量擦除您的芯片并下载应用程序以再次测试。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢!

    一切似乎都按预期工作、但我只有一个关于 SendOnOff_Cmd 的最后问题;ZC 似乎错过了从 ZED 偶尔发送的开/关命令、是否有任何方法来确认命令已获取? 某种握手或某种东西。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果所有 MAC/NWK 重试均已用完、则可以启用 APS ACK、如 Zigbee 基本项目开发 SLA 中所示、这种方法也会实现 APS 重试。  但对于父/子设备、 zstackmsg_CmdIDs_AF_DATA_CONFIRM_IND (请参阅 Z-Stack API 指南)状态应足够(检查是否匹配 transID)。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我同意 Ryan 的说法、即启用 APS 机架、但如果您的协调员经常未能收到命令、您的射频硬件可能存在问题、我还建议您使用嗅探器检查无线传输的确切情况。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我的函数发送开/关命令的方式似乎有问题。 使用 BTN-2 (用于切换灯)进行测试时、工作正常、能够在我自己的功能偶尔出现故障(大约10次中的2次)时进行切换。

    以下是仅用于发送开/关命令的函数。

    void zclSampleSw_actionToggleLight(void)
    {
        zstack_getZCLFrameCounterRsp_t rsp;

        Zstackapi_getZCLFrameCounterReq(appServiceTaskId, &rsp);
        zclSampleSw_UpdateStatusLine();

        if(prevPresence != presence)
        {
            if(presence)
            {
                zclGeneral_SendOnOff_CmdOn( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, rsp.zclFrameCounter );
            }else
            {
                zclGeneral_SendOnOff_CmdOff( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, rsp.zclFrameCounter );
            }
            prevPresence = presence;
            Display_printf(display, 0, 0, "%s", presence ? "Presence: TRUE\n" : "Presence: FALSE\n");
        }
    }

    此函数附加到 process_loop、如下所示:

    static void zclSampleSw_process_loop(void)
    {
        /* Forever loop */
        for(;;)
        {
            zstackmsg_genericReq_t *pMsg = NULL;
            bool msgProcessed = FALSE;

                /* Wait for response message */
            if(Semaphore_pend(appSemHandle, BIOS_WAIT_FOREVER ))
            {
                /* Retrieve the response message */
                if( (pMsg = (zstackmsg_genericReq_t*) OsalPort_msgReceive( appServiceTaskId )) != NULL)
                {
                    /* Process the message from the stack */
                    zclSampleSw_processZStackMsgs(pMsg);

                    // Free any separately allocated memory
                    msgProcessed = Zstackapi_freeIndMsg(pMsg);
                }

                if((msgProcessed == FALSE) && (pMsg != NULL))
                {
                    OsalPort_msgDeallocate((uint8_t*)pMsg);
                }

    #ifndef CUI_DISABLE
                zclsampleApp_ui_event_loop();
                zclSampleSw_UpdateStatusLine();
    #endif

                zclSampleSw_actionToggleLight();


    #if ZG_BUILD_ENDDEVICE_TYPE
                if ( appServiceTaskEvents & SAMPLEAPP_END_DEVICE_REJOIN_EVT )
                {
                  zstack_bdbZedAttemptRecoverNwkRsp_t zstack_bdbZedAttemptRecoverNwkRsp;

                  Zstackapi_bdbZedAttemptRecoverNwkReq(appServiceTaskId,&zstack_bdbZedAttemptRecoverNwkRsp);

                  appServiceTaskEvents &= ~SAMPLEAPP_END_DEVICE_REJOIN_EVT;
                }
    #endif
            }
        }
    }

    在环路内按下按钮和调用函数之间有何区别?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您 正在     对 zclSampleSw_process_loop 的每次迭代调用 zclSampleSw_actionToggleLight、其频率不可靠、不应依赖于该迭代。  相反、您应该创建一个示例应用事件(请参阅 zcl_samplesw.h) 、该事件由 外设(计时器、UART、GPIO 等)的更改/回调进行设置、然后在主处理循环内进行检查、执行和清除。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我将尝试按照大家的建议执行周期性计时器。

    1. 是否有原因将事件(在 zcl_samplesw.h 中)定义 为(0x0001、0x0002、0x0004、0x0008、0x0010)?
    2. 我应该如何启动周期性计时器? 在 zclSamplwSw_InitTM 中?
    3. 在 zclSampleSw_initializeClocks()中初始化的是一个"单次触发"计时器。 对于周期性计时器、如果将时钟周期计时器设置为1000、是否需要设置时钟持续时间?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    事件被定义为位标志、这就是您看到它们被定义为0x0001、0x0002、0x0004、0x0008、0x0010的原因。

    2.可以,可以在 zclSamplwSw_Init 中创建周期性计时器事件

    3.使用 UtilTimer_constructic 创建计时器事件时,可以将时钟持续时间设置为1000,这意味着事件回调将在1000ms 后触发,并将时钟周期设置为0。 在您的事件中、您可以调用 UtilTimer_setTimeout (1000)和 UtilTimer_start 来安排下一个周期性事件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经制作了周期性计时器、并在处理循环中检查、处理和清除了事件、但仍然获得与之前相同的行为。 BTN-2切换仍然正常、而开/关有时会失败。 ZED 设法加入网络后、计时器启动。

    我是否误解了您建议的方法?

    static void zclSampleSw_process_loop(void)
    {
        /* Forever loop */
        for(;;)
        {
            zstackmsg_genericReq_t *pMsg = NULL;
            bool msgProcessed = FALSE;

                /* Wait for response message */
            if(Semaphore_pend(appSemHandle, BIOS_WAIT_FOREVER ))
            {
                /* Retrieve the response message */
                if( (pMsg = (zstackmsg_genericReq_t*) OsalPort_msgReceive( appServiceTaskId )) != NULL)
                {
                    /* Process the message from the stack */
                    zclSampleSw_processZStackMsgs(pMsg);

                    // Free any separately allocated memory
                    msgProcessed = Zstackapi_freeIndMsg(pMsg);
                }

                if((msgProcessed == FALSE) && (pMsg != NULL))
                {
                    OsalPort_msgDeallocate((uint8_t*)pMsg);
                }

    #ifndef CUI_DISABLE
                zclsampleApp_ui_event_loop();
                zclSampleSw_UpdateStatusLine();
    #endif
                if ( appServiceTaskEvents & SAMPLEAPP_SENSOR_UPDATE_EVT )
                {
                    if(prevPresence != presence)
                    {
                        zstack_getZCLFrameCounterRsp_t rsp;

                        Zstackapi_getZCLFrameCounterReq(appServiceTaskId, &rsp);

                        if(presence == true)
                        {
                            zclGeneral_SendOnOff_CmdOn( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, rsp.zclFrameCounter );
                        }
                        if(presence == false)
                        {
                            zclGeneral_SendOnOff_CmdOff( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, rsp.zclFrameCounter );
                        }
                        prevPresence = presence;
                        Display_printf(display, 0, 0, "%s", presence ? "Presence: TRUE\n" : "Presence: FALSE\n");
                    }

                    appServiceTaskEvents &= ~SAMPLEAPP_SENSOR_UPDATE_EVT;

                    UtilTimer_setTimeout( sensorClkHandle, SAMPLEAPP_SENSOR_UPDATE_DELAY );
                    UtilTimer_start(&sensorClkStruct);
                    Display_printf(display, 0, 0, "Periodic timer event!");
                }

    #if ZG_BUILD_ENDDEVICE_TYPE
                if ( appServiceTaskEvents & SAMPLEAPP_END_DEVICE_REJOIN_EVT )
                {
                    zstack_bdbZedAttemptRecoverNwkRsp_t zstack_bdbZedAttemptRecoverNwkRsp;

                    Zstackapi_bdbZedAttemptRecoverNwkReq(appServiceTaskId,&zstack_bdbZedAttemptRecoverNwkRsp);

                    appServiceTaskEvents &= ~SAMPLEAPP_END_DEVICE_REJOIN_EVT;
                }

    ................................................................

    Thanks for your help

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否进行监听器记录并附加它、以便我们检查无线传输过程中发生的情况?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../zed_5F00_sw_5F00_christng_5F00_trimmed.zip

    e2e.ti.com/.../zed_5F00_sw_5F00_christng.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我从我的 Smart RF 监听器代理中注意到、当开/关命令不成功时、Incoming Packets 字段不会递增、但会在成功执行后更新。 那么、我认为它必须是我的实施中的一个错误吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可以添加 CCS 断点、检查  zclGeneral_SendOnOff_CmdOn 的返回值、还有 zstackmsg_CmdIDs_AF_DATA_CONFIRM_IND (之前讨论过) 以监控 数据包发送错误。   您的计时器回调中包含什么内容以及 SampleApp_sensor_update_delay 的值是什么?

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在监听器日志中看不到任何开/关命令。 是否确定触发了周期性事件并调用了 zclGeneral_SendOnOff_CmdOn/zclGeneral_SendOnOff_CmdOff?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    YiKai 和 Ryan、您好!

    是的、我确定我的周期性事件会被触发、因为我包含了每个 SampleApp_sensor_update_delay (1000ms)都会发生的控制台打印。 我还看到、通过触发存在传感器、ZC_Light 会被打开和关闭。 调试确认我调用了 zclGeneral_SendOnOff_CmdOn/zclGeneral_SendOnOff_CmdOff。

    我的计时器回调:

    static void zclSampleSw_processLightTimeoutCallback(UArg a0)
    {
        (void)a0;

        appServiceTaskEvents |= SAMPLEAPP_SENSOR_UPDATE_EVT;

        Semaphore_post(appSemHandle);
    }

    使用 AF_DATA_CONFIRM_IND:

    成功发送数据包:

    状态:0x00

    端点:8

    失败的数据包发送:

    状态:0x01

    端点:8

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我发现了错误/错误/功能是什么。

    通过在发送命令时以特定方式将我的手放在 ZED 板/天线上、可以成功发送命令。 我成功地复制了这一"解决方案"、大约100%的时间未能发送。  

    通过反复发送命令直至成功(请参阅下面的代码)、我观察到当我缓慢地将手放在电路板周围时、命令如何一直出现故障、从而成功发送命令?

    if (pInd->req.status != 0)
                  {
                      Zstackapi_getZCLFrameCounterReq(appServiceTaskId, &sensor_rsp);

                      if (presence)
                      {
                          zclGeneral_SendOnOff_CmdOn( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, sensor_rsp.zclFrameCounter );
                      }else
                      {
                          zclGeneral_SendOnOff_CmdOff( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, FALSE, sensor_rsp.zclFrameCounter );
                      }
                      Display_printf(display, 0, 0, "Resent command for transId %d\n", pInd->req.transID);
                      Task_sleep(1000);
                  }

    对此我没有解释