This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE MESH Stack(2.0.1)Light Switch Demo Roundtrip Delay getting higher between client and server

Hii,

I am currently using two nRF52832 SDK boards to implement text message exchange with another nRF52832 SDK board via BLE Mesh SDK 2.0.1.

However, when I try to increase the frequency of sending the command the communication seem to choke. and i'm getting Roundtrip Delay higher between client and server.

Roundtrip calcualtion of 5byte send and receive  sheet is below

  

Round trip calcualtion of 11byte send and receive  sheet is below

How to reduce round trip delay time please suggest me ASAP.

Thanks,

Nikunj Patidar

 

Parents
  • Hello,

    I had to ask a colleague of mine to look at your question. He had some questions about how you measure the delays. He writes:

    ----------

    It doesn't look like he stamps the messages, so how does he know what message the server receives and answers to? It might have some implications on the measurements. Messages are not guaranteed to come in the right order in Mesh (although it is likely with only two nodes).The theoretical latency is ADV_INT/2 and default ADV_INT is 20ms. 

     

    We have a feature in the stack that implements flow control relatively simple:

    nrf_mesh_tx_token_t. Her is a code snippet that shows one way of using it:

    static nrf_mesh_tx_token_t m_my_token;
    
    static void mesh_evt_handler(const nrf_mesh_evt_t * p_evt)
    {
        if (p_evt->type == NRF_MESH_EVT_TX_COMPLETE &&
            p_evt->params.tx_complete.token == m_my_token)
        {
            /* Message has been sent on air. */
        }
    }
    
    void packet_send(void)
    {
        /* Using the access API directly. */
        access_message_tx_t message;
        memset(&message, 0, sizeof(message));
    
        /* TODO: Fill fields correctly */
        message.token = m_my_token;
    
        /* TODO: send */    
    }
    
    
    void init(void)
    {
        static nrf_mesh_evt_handler_t s_evt_handler = {
            .evt_cb = mesh_evt_handler
        };
    
        /* nrf_mesh_unique_token_get() was introduced in v2.1.1 to guarantee uniqueness of the value.
         * You _could_ just use a #defined number, but risk using the same number as something else in
         * the stack.
         */
        m_my_token = nrf_mesh_unique_token_get();
        nrf_mesh_evt_handler_add(&s_evt_handler);
    }
    

    This is used e.g. in Node Reset to make sure that we have sent a status message before actually deleting everything and reset the node. Right now, you must use the access.h or nrf_mesh.h API directly to control tokens.

    ----------

     

    So do you know that you are measuring the correct delays? Do you have any way of identifying the messages, or do you wait until you get the message back before you send a new one?

     

    Best regards,

    Edvin

Reply
  • Hello,

    I had to ask a colleague of mine to look at your question. He had some questions about how you measure the delays. He writes:

    ----------

    It doesn't look like he stamps the messages, so how does he know what message the server receives and answers to? It might have some implications on the measurements. Messages are not guaranteed to come in the right order in Mesh (although it is likely with only two nodes).The theoretical latency is ADV_INT/2 and default ADV_INT is 20ms. 

     

    We have a feature in the stack that implements flow control relatively simple:

    nrf_mesh_tx_token_t. Her is a code snippet that shows one way of using it:

    static nrf_mesh_tx_token_t m_my_token;
    
    static void mesh_evt_handler(const nrf_mesh_evt_t * p_evt)
    {
        if (p_evt->type == NRF_MESH_EVT_TX_COMPLETE &&
            p_evt->params.tx_complete.token == m_my_token)
        {
            /* Message has been sent on air. */
        }
    }
    
    void packet_send(void)
    {
        /* Using the access API directly. */
        access_message_tx_t message;
        memset(&message, 0, sizeof(message));
    
        /* TODO: Fill fields correctly */
        message.token = m_my_token;
    
        /* TODO: send */    
    }
    
    
    void init(void)
    {
        static nrf_mesh_evt_handler_t s_evt_handler = {
            .evt_cb = mesh_evt_handler
        };
    
        /* nrf_mesh_unique_token_get() was introduced in v2.1.1 to guarantee uniqueness of the value.
         * You _could_ just use a #defined number, but risk using the same number as something else in
         * the stack.
         */
        m_my_token = nrf_mesh_unique_token_get();
        nrf_mesh_evt_handler_add(&s_evt_handler);
    }
    

    This is used e.g. in Node Reset to make sure that we have sent a status message before actually deleting everything and reset the node. Right now, you must use the access.h or nrf_mesh.h API directly to control tokens.

    ----------

     

    So do you know that you are measuring the correct delays? Do you have any way of identifying the messages, or do you wait until you get the message back before you send a new one?

     

    Best regards,

    Edvin

Children
  • Hi Edvin,

    your answer does not match with my requirement. Answer for your required question below.

    Que:Do you have any way of identifying message?
    Ans: whatever client will send, server will echoback same message it received.
    Que: Do you know that you are measuring the correct delay?
    Ans: when client send message to server,timer started in client and it waits for echoback message from server. when echoback message received at client side.it will capture the timer.
    Que: do you wait until you get the message back before you send a new one?
    Ans: Yes
    Thank's
    Nikunj Patel
  • Hi Edvin,

    Please focus on my main Question is to reduce roundtrip delay of echo-back message from client to server to client again with the same message.

    Client Send Message:-

           

    uint8_t DATA_Tx[50]="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWX";
    uint32_t status = NRF_SUCCESS;
        status = send_command_client(&m_clients[button_number],&DATA_Tx[0],sizeof(DATA_Tx));
        if(!status)
        {
            Send_Cnt++;
            Start_timer_cnt=log_timestamp_get();
            
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "SendMsg to Server:%s    Msg_Send_Cntr:%d     Start_timer_cnt =%d \n",DATA_Tx, Send_Cnt,Start_timer_cnt);
        }

    Server Received Message After Echo-Back Message to client:-
    static void handle_send_command_cb(access_model_handle_t handle, const access_message_rx_t * p_message, void * p_args) 
    {
        
        uint16_t  i;
        uint8_t buffer[260];
        
        
        Stop_timer_cnt= log_timestamp_get();
        Rec_Cnt++;
        Actual_Time =((Stop_timer_cnt-Start_timer_cnt)/32768);
        
        memset(buffer, 0, sizeof(buffer));
        strncpy(buffer, command, length); 
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Received Data From Client: %s Rec_Cnt = %d rssi=%d Stop_timer_cnt=%d Actual_Time=%d\n", buffer,Rec_Cnt,p_message->meta_data.p_core_metadata->params.scanner.rssi,Stop_timer_cnt,Actual_Time);
    
    
        strncpy(response_msg.response, command, length);
        response_msg.length = length;               
    
    
        if (response_msg.length !=0)
        {  // need to send reply
            access_message_tx_t reply; 
            reply.opcode.opcode = Custom_message_OPCODE_RESPOND;
            reply.opcode.company_id = ACCESS_COMPANY_ID_NORDIC;
            reply.p_buffer = (const uint8_t *) &response_msg;
            reply.length = response_msg.length+2;  // just sending the length (16-bit) + response string.
            (void) access_model_publish(p_server->model_handle, &reply); //Publishing
        }    
        else
         {
            failureCount++;
         }
    }
    Client Received Echo Message :-

    static void handle_status_cb(access_model_handle_t handle, const access_message_rx_t * p_message, void * p_args)
    {
    
        uint16_t  i;
        uint8_t buffer[260];
    
       simple_on_off_client_t * p_client = p_args;
       NRF_MESH_ASSERT(p_client->status_cb != NULL);
       uint8_t *command = ((send_command_msg_t *) p_message->p_data)->command;
       uint16_t length =  ((send_command_msg_t *) p_message->p_data)->length;
       
        if (!is_valid_source(p_client, p_message))
        {
            return;
        }
    
    
        Stop_timer_cnt= log_timestamp_get();
        Recv_Cnt++;
        Actual_Time =((Stop_timer_cnt-Start_timer_cnt)/32768);
    
        receive_response_msg_t *p_response = (receive_response_msg_t *) p_message->p_data;
        memset(buffer, 0, sizeof(buffer));
        strncpy(buffer,  p_response->response, p_message->length-2);
       __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Received Data From Server: %s\t Rec_Cnt = %d rssi=%d Stop_timer_cnt=%d Actual_Time=%d\n", buffer,Recv_Cnt,p_message->meta_data.p_core_metadata->params.scanner.rssi,Stop_timer_cnt,Actual_Time);
    
    }

    Thank's

    Nikunj Patel

  • Hello,

    You write that you use two DKs, right?

    Is it possible to send the project that you are using to perform the tests?

     

    Best regards,

    Edvin

  • HI Edvin,

    Forgot Every Thing ..I have modify simple on_off Light Switch Example.

    Query : When Client Send 50 Byte to server, server get 50 byte message immediately  after sever send echo back message to client but client does not get message immediately, due to this server retries message.

    My question is why client does not receive echo back message immediately?

    Firmware.rar

    Thank's

    Nikunj Patel

  • Hi Nikunj,

    Have you been able to use this method to measure RTT by using timer? If yes, could you share an example or a link that is useful?

    Thanks,

    Pegah

Related