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

how to send large payload(16k byte) using Bluetooth mesh

We are planing to use nrf52840 sdk in our project.we want to use mesh stack for that.

our product is sensor:

-deployed in oil field.

- send data 8 times a day.

-payload is 16K bytes.

-max hope will be 7.

currently using mobile app for provisioning.

we want to create mesh network on site for communication using which all sensor will send data.

we are exploring nrf52840 dk  with mesh stack (4.1) for throughput and latency.

Till now what i have tried is:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

take 2 nrf52840 DK board and flash one with light_switch_client and other with light_switch_server.i done  following changes in client and server side to send data and receive data

at server side:

static uint32_t status_send(generic_onoff_server_t * p_server,
                            const access_message_rx_t * p_message,
                            const generic_onoff_status_params_t * p_params)
{
   uint8_t data[500];
  memset(data,'K',498);
  data[499]=0;
    generic_onoff_status_msg_pkt_t msg_pkt;

    if (p_params->present_on_off > GENERIC_ONOFF_MAX ||
        p_params->target_on_off  > GENERIC_ONOFF_MAX ||
        p_params->remaining_time_ms > TRANSITION_TIME_STEP_10M_MAX)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    msg_pkt.present_on_off = p_params->present_on_off;
    if (p_params->remaining_time_ms > 0)
    {
        msg_pkt.target_on_off = p_params->target_on_off;
        msg_pkt.remaining_time = model_transition_time_encode(p_params->remaining_time_ms);
    }

    access_message_tx_t reply =
    {
        .opcode = ACCESS_OPCODE_SIG(GENERIC_ONOFF_OPCODE_STATUS),
        .p_buffer = (const uint8_t *)&data,// &msg_pkt,
        .length = strlen(data),//p_params->remaining_time_ms > 0 ? GENERIC_ONOFF_STATUS_MAXLEN : GENERIC_ONOFF_STATUS_MINLEN,
        .force_segmented = p_server->settings.force_segmented,
        .transmic_size = p_server->settings.transmic_size
    };

    if (p_message == NULL)
    {
        return access_model_publish(p_server->model_handle, &reply);
    }
    else
    {
        return access_model_reply(p_server->model_handle, p_message, &reply);
    }
}

at master side:

static void status_handle(access_model_handle_t handle, const access_message_rx_t * p_rx_msg, void * p_args)
{
    generic_onoff_client_t * p_client = (generic_onoff_client_t *) p_args;
    generic_onoff_status_params_t in_data = {0};

    if (p_rx_msg->length == GENERIC_ONOFF_STATUS_MINLEN || p_rx_msg->length == GENERIC_ONOFF_STATUS_MAXLEN)
    {
        generic_onoff_status_msg_pkt_t * p_msg_params_packed = (generic_onoff_status_msg_pkt_t *) p_rx_msg->p_data;

        if (p_rx_msg->length == GENERIC_ONOFF_STATUS_MINLEN)
        {
            in_data.present_on_off = p_msg_params_packed->present_on_off;
            in_data.target_on_off = p_msg_params_packed->present_on_off;
            in_data.remaining_time_ms = 0;
        }
        else
        {
            in_data.present_on_off = p_msg_params_packed->present_on_off;
            in_data.target_on_off = p_msg_params_packed->target_on_off;
            in_data.remaining_time_ms = model_transition_time_decode(p_msg_params_packed->remaining_time);
        }

        p_client->settings.p_callbacks->onoff_status_cb(p_client, &p_rx_msg->meta_data, &in_data);
    }
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, p_rx_msg->p_data);
            
}

using this i can send 300 bytes successfully but when i increase payload its failing so i debug and found that its due to ACCESS_MESSAGE_LENGTH_MAX during memory alloc .

1-How to send 16,384 bytes in mesh network?

2-Is message is segmented automatically and if not and i have to manually create packet  than what should be the procedure for waiting after one packet sent?

3-Is mesh is suitable for this and what will be throughput and latency?

4-Is there any ready example to send large payload in mesh network?

Parents
  • Hi,

    1. You will need to split up the data into smaller packets. Sending packets of smaller size and reassemble after it has been received on the other end.

    You can consider using Nordic Advertiser Extensions (Instaburst). It will increase your payload (498 bytes) but just note that Instaburst is a Nordic proprietary feature that does not adhere to the Bluetooth Mesh Specification. It will break compatibility with other Bluetooth Mesh implementations.

    You can read more about this in this post.

    2. Yes. any packet with size larger than 11 bytes (including header) will be split into segmented messages automatically. But the maximum possible segmented payload size is 380 so it will fail if you have a higher payload.

    3. Mesh is not optimal for sending/streaming a lot of data. In the Mesh documentation from our Infocenter:

    "Bluetooth Mesh primarily targets simple control and monitoring applications, like light control or sensor data gathering. The packet format is optimized for small control packets, issuing single commands or reports, and is not intended for data streaming or other high-bandwidth applications."

    The throughput in a Mesh network is highly dependent on several factors. How many nodes do you have in your network, are you sending reliable or unreliable messages, how many hops to you need to reach the receiver node etc. 

    For one hop we have seen 3.46kbps ( ~54 Bytes/s) with 20ms advertising, 100% scanning with 11 bytes payload,  Non-Acked, i.e. unreliable.

    4. Unfortunately, we don’t have an example for sending large payloads in a mesh network.

  • Hi,

    1. You can find the documentation for the Instaburst feature here, and APIs for Instaburst TX module and RX module.

    karan patel said:
    I want to integrate this feature in mesh sdk light_switch example is it possible?

    Yes, it should be possible.

    2. Instead of setting a flag in the NRF_MESH_EVT_TX_COMPLETE event and sending the data in main loop, try sending the data directly after getting the event? Doing it from main will cause interrupt priority issues as you mentioned. I recommend you to have a look at the interrupt priority documentation.

Reply Children
No Data
Related