Page 1 of 1

ESP BLE MESH using deep sleep

Posted: Fri Jul 23, 2021 4:40 am
by kskd1804
Hi,

I am currently working on building a BLE mesh for transmitting data from multiple nodes with Sensor Server model (publishes the data on group address) to a single node with Sensor Client model (subscribes to the group address). Everything seems to be working fine. But now I changed the code so that nodes with Sensor Server model go to deep sleep after publishing the data on the group address and wake up whenever a GPIO goes high.
I am doing this by calling esp_deep_sleep_start function after esp_ble_mesh_model_publish function. There are no errors at the Server end but for some reason, the Sensor Client model is not able to receive the data.

This the function which is called

Code: Select all

void custom_ble_mesh_send_sensor_readings(int8_t state) {
	// Set the new Motion State
	net_buf_simple_reset(&sensor_data_0);
	net_buf_simple_add_u8(&sensor_data_0, state);
	ESP_LOGI(TAG, "Sensor Reading: %d", state);
	
	// Prep the data to be sent
	uint8_t *status = NULL;
    uint16_t buf_size = 0;
    uint16_t length = 0;    
    esp_err_t err;
    int i;
	
	/**
     * Sensor Data state from Mesh Model Spec
     * |--------Field--------|-Size (octets)-|------------------------Notes-------------------------|
     * |----Property ID 1----|-------2-------|--ID of the 1st device property of the sensor---------|
     * |-----Raw Value 1-----|----variable---|--Raw Value field defined by the 1st device property--|
     * |----Property ID 2----|-------2-------|--ID of the 2nd device property of the sensor---------|
     * |-----Raw Value 2-----|----variable---|--Raw Value field defined by the 2nd device property--|
     * | ...... |
     * |----Property ID n----|-------2-------|--ID of the nth device property of the sensor---------|
     * |-----Raw Value n-----|----variable---|--Raw Value field defined by the nth device property--|
     */
    for (i = 0; i < ARRAY_SIZE(sensor_states); i++) {
        esp_ble_mesh_sensor_state_t *state = &sensor_states[i];
        if (state->sensor_data.length == ESP_BLE_MESH_SENSOR_DATA_ZERO_LEN) {
            buf_size += ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID_LEN;
        } else {
            /* Use "state->sensor_data.length + 1" because the length of sensor data is zero-based. */
            if (state->sensor_data.format == ESP_BLE_MESH_SENSOR_DATA_FORMAT_A) {
                buf_size += ESP_BLE_MESH_SENSOR_DATA_FORMAT_A_MPID_LEN + state->sensor_data.length + 1;
            } else {
                buf_size += ESP_BLE_MESH_SENSOR_DATA_FORMAT_B_MPID_LEN + state->sensor_data.length + 1;
            }
        }
    }

    status = calloc(1, buf_size);
    if (!status) {
        ESP_LOGE(TAG, "No memory for sensor status!");
        return;
    }
	
	for (i = 0; i < ARRAY_SIZE(sensor_states); i++) {
		length += example_ble_mesh_get_sensor_data(&sensor_states[i], status + length);
	}
	
	ESP_LOG_BUFFER_HEX("Sensor Data", status, length);	
    err = esp_ble_mesh_model_publish(sensor_server.model, ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS, length, status, ROLE_NODE);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to publish Sensor Status, err %d", err);
    }
    free(status);
    esp_deep_sleep_start();
}
The basic idea here is to save as much power as possible because, the nodes running Sensor Server models will be running on a battery. This is the flow that I am planning to achieve.

GPIO goes HIGH -> Wake up from deep sleep -> Publish the sensor data on the group address -> Go back to sleep.

I was wondering someone could help me fix this. Thanks!

Re: ESP BLE MESH using deep sleep

Posted: Fri Jul 23, 2021 10:36 am
by kskd1804
Ok, after digging deeper, I think I understand why the messages are not getting transmitted. Correct me if I am wrong. The esp_ble_mesh_model_publish function seems to be pushing the data to be handled by a Queue, which in turn will handle the transmission of data. It seems, the esp_deep_sleep_start function is getting called even before the Queue can take up the task. I think the issue can be solved I can receive a callback once the message is published on the Sensor Server callback function. I see ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT event in the API documentation, but I am not sure if this will work as the event belongs to esp_ble_mesh_model_cb_param_t and not esp_ble_mesh_sensor_server_cb_param_t. I will try it out anyway, but if someone could shed some light in this, I would be great. Thanks!

Re: ESP BLE MESH using deep sleep

Posted: Mon Jul 26, 2021 4:15 am
by kskd1804
Ok I finally solved the issue. As I thought the callback ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT event was triggered whenever I publish a message. I am calling esp_deep_sleep_start() within this callback event and everything worked like a charm.