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.

CC1352P: how to send data from collector to a specific sensor in a 15.4 network FH Low Latency Broadcast mode

Part Number: CC1352P

Tool/software:

Hi,

I am trying to port our code from 15.4 FH mode to FH Low Latency Broadcast (FH-LLB) mode. So far I was able to get network joining, sending data from sensor to collector to work, but hit a snag when trying to send data from collector to a specific sensor node.

According to the documentation available here, collector sends data to sensor through broadcast, each sensor node receives a copy of the message and discards messages without matching address. Programming wise, how do we go about this?

I assume we can use the same function in `collector.c` as we do in other network modes

// collector.c
static bool sendMsg(Smsgs_cmdIds_t type, uint16_t dstShortAddr, bool rxOnIdle,
                    uint16_t len,
                    uint8_t *pData,
                    uint8_t *frameIdPtr);

So far none of the messages sent via this function is received by sensor nodes. 

There is also a function to broadcast messages:

static void sendBroadcastMsg(Smsgs_cmdIds_t type, uint16_t len,
                    uint8_t *pData)

This seems to be the function used by example collector project to send data to sensor nodes in FH-LLB mode. Destination address is manually assembled into payload, sensor nodes then perform a manual check if destination address matches its own. 

    /*
     Collector generate a broadcast command message for FH mode
     */
    if(Collector_events & COLLECTOR_BROADCAST_TIMEOUT_EVT)
    {
        /* Clear the event */
        Util_clearEvent(&Collector_events, COLLECTOR_BROADCAST_TIMEOUT_EVT);
        if(FH_BROADCAST_INTERVAL > 0 && (!CERTIFICATION_TEST_MODE))
        {
#ifdef FH_LOW_LATENCY_BROADCAST
            if(broadcastQueue < 1)
            {
                uint8_t buffer[SMSGS_BROADCAST_CMD_LENGTH];
                uint8_t *pBuf = buffer;

                /* Build the message */
                if(sendCamCmd)
                {
                    *pBuf++ = (uint8_t)Smgs_cmdIds_broadcastCtrlMsg;
                    *pBuf++ = Util_loUint16(destDevAddr);
                    *pBuf++ = Util_hiUint16(destDevAddr);
                    *pBuf = 0x1;
                    sendCamCmd -= 1;
                }
                else
                {
                    *pBuf++ = (uint8_t)Smgs_cmdIds_broadcastCtrlMsg;
                    *pBuf++ = 0xF;
                    *pBuf++ = 0xF;
                    *pBuf = 0xF;
                }
                broadcastQueue += 1;
                sendBroadcastMsg(Smgs_cmdIds_broadcastCtrlMsg, SMSGS_BROADCAST_CMD_LENGTH,
                                 buffer);
            }
            /* set clock for next broadcast command */
            Csf_setBroadcastClock(FH_BROADCAST_INTERVAL / 2);
#else  // FH_LOW_LATENCY_BROADCAST
            generateBroadcastCmd();
            /* set clock for next broadcast command */
            Csf_setBroadcastClock(FH_BROADCAST_INTERVAL);
#endif // FH_LOW_LATENCY_BROADCAST
        }
    }

My question is, can the address check done by MAC layer? Or is there a different way to do it? 

Thanks,

ZL

  • Hi Zhiyong,

    the communication from collector to sensor is implemented using broadcast transmissions only.

    The broadcast message is sent periodically (broadcast interval) by the collector. The event responsible is the COLLECTOR_BROADCAST_TIMEOUT_EVT and the event handling that you shared above.

    The default message format is as below and you can change it in smgs.h (remember to change it on collector and sensor).

    All sensors receive all broadcast messages and use them as heartbeat to check if they are still connected to the collector.

    All sensors check after receiving the broadcast message if the Destination Device Address is the same as their own device address. If so, they process the command.

    The sensor processes the broadcast message in sensor.c -> processBroadcastCtrlMsg() below.

    To address now a specific sensor you need to attach it's device address to the broadcast message. This will trigger the Command event when the sensor receives it.

    An example on how this is done is implemented on the collector. When pressing button 1 of the collector it will append the device address of the first sensor in the network and you will see the Green LED of the sensor toggle when it receives the command. With button 2 of the collector you can address one by one all the sensors in the network and observe the same LED toggle. (Checkout collector.c -> COLLECTOR_BROADCAST_CAMCMD_EVT)



    Each of the commands is acknowledged by the sensors and the collectors green LED toggles when it receives the acknowledgement.

    Kind regards,
    Theo

  • Hi Mr. Lange,

    Thanks for your quick reply and confirming that the only way to send data from collector to sensor is through broadcast.

    Two following up questions:

    1) What to change in smsgs.h if we want to send customized messages? I assume there are at least two as in the following blocks, the broad cmd length and typedef.

    /*! Broadcast Command message length (over-the-air-length) */
    #ifdef FH_LOW_LATENCY_BROADCAST
    #define SMSGS_BROADCAST_CMD_LENGTH  4   // Change this to whatever fits?
    #else  // FH_LOW_LATENCY_BROADCAST
    #define SMSGS_BROADCAST_CMD_LENGTH  3
    #endif // FH_LOW_LATENCY_BROADCAST
    
     Broadcast Cmd Request message: sent from controller to the sensor.
     */
    typedef struct _Smsgs_broadcastcmdmsg_t
    {
        /*! Command ID - 1 byte */
        Smsgs_cmdIds_t cmdId;
    #ifdef FH_LOW_LATENCY_BROADCAST
        uint16_t destdevAddr; // destination device address
        uint8_t camCmd;       // camera command for the destination device
    #else  // FH_LOW_LATENCY_BROADCAST
        uint16_t broadcastMsgId;
    #endif
    }Smsgs_broadcastcmdmsg_t;

    2) The max broadcast interval: the range recommended in Syscfg is 0 to UINT32_MAX. Is there any practical limit on how often broadcast should be? 20ms RX on every 1 seconds still leads about 100 ~ 200uA power consumption. But if we can push broadcast interval to 5 or 10 seconds, then this part of power consumption becomes a lot more acceptable.

    Best,

    ZL

  • Hi Zhiyong,

    1. Currently camCmd = 0x01 is used to trigger the camera command on the sensor side. You could reuse this, for instance with a different value 0x02 to trigger your command.

    sensor.c

     

                    /* process camera commands */
                    if(camCmd == 0x1) //--> This is the camCmd
                    {
                        /* send the acknowledgment message */
                        uint8_t buffer[SMSGS_TOGGLE_LED_RESPONSE_MSG_LEN];
                        uint8_t *pBuf = buffer;
    
                        *pBuf = (uint8_t)Smsgs_cmdIds_toggleLedRsp;
    
                        Sensor_sendMsg(Smsgs_cmdIds_toggleLedRsp,
                                        &pDataInd->srcAddr, true,
                                        SMSGS_TOGGLE_LED_RESPONSE_MSG_LEN,
                                        buffer);
    
                        Util_setEvent(&Sensor_events, SENSOR_BROADCAST_CAMCMD_EVT);
                    }
                }

    collector.c

                    /* Build the message */
                    if(sendCamCmd)
                    {
                        *pBuf++ = (uint8_t)Smgs_cmdIds_broadcastCtrlMsg;
                        *pBuf++ = Util_loUint16(destDevAddr);
                        *pBuf++ = Util_hiUint16(destDevAddr);
                        *pBuf = 0x1; // -> this is the camCmd
                        sendCamCmd -= 1;
                    }

    If you needed an additional payload besides the command, you should increase (smsgs.h) SMSGS_BROADCAST_CMD_LENGTH and add an additional member to  the struct Smsgs_broadcastcmdmsg_t. And then you populate *pBuf from the previous code snippet.

    2. 5 to 10 seconds broads interval should be fine. Remember you should also change  LOW_LATENCY_BROADCAST_CONFIGURATION_TIMEOUT (sensor.c) to double the broadcast interval as explained in  the user manual . I'll check on what is the practical limit.

  • Hi Mr. Aguiar,

    Thanks for your reply.

    Regarding broadcast interval, there seems to be a limit somewhere between 30 and 60seconds. 30s seems to work just fine, but 60s seems not. 30s should be good enough for my purpose.

    I also asked questions in separated threads about to how to set broadcast interval. Please see if you can help answer as well.

    Best,

    ZL