STM32WB BLE MESH Sensor Model

Revision as of 14:16, 27 October 2021 by Registered User (→‎Technical Description)

1. Technical Description

This page describes the functioning of the BLE Mesh Sensor Client/Server Project and how to handle it.

A quick description of the BLE Mesh Sensor Model is available in the ST BLE-Mesh Application Note[1].

This project demonstrates STM32WB application capabilities using BLE-Mesh solution and with a sensor module and using specific Sensor Client commands. The goal of the project is to send sensor data from the Sensor Server to the Sensor Client on Sensor Client request.

Project Overview

To realize this project, we use two Discovery Kits including temperature and time of flight sensors.

One board implements a BLE Mesh Sensor Server Node, and the second board a Sensor Client Node. A short push on Sensor Client User Button 1 (B1) send a Get Temperature request to the Sensor Server, a long push sends a Get Distance request. The Server answers to the Client and the required data are displayed on Client logs.

BLE Mesh Sensor Project Description

2. Demonstration Setup

2.1. Device Requirement

Required material to setup the demonstration is the following:

  • 2 Discovery Kit : As temperature sensing boards
  • 1 Smartphone with Android or iOS

Click on Component Hyperlink to see resellers.

2.2. Software

Sensor Model Application can be found on latest STM32CubeWB release [NOTE: this example will be included in next package: v1.13.0]:

Project BLE Mesh Sensor - STM32WB5MM-DK

2.3. Code Modification

Server/Client setup:
Modify the mesh_cfg_usr.h file in order to chose between the Client or Server configuration:

  • Server:
/* Enable Sensor Model Server or Sensor Model Client */
//#define ENABLE_SENSOR_MODEL_SERVER                                        (1)

#define ENABLE_SENSOR_MODEL_CLIENT                                           (1)
  • Client:
/* Enable Sensor Model Server or Sensor Model Client */
//#define ENABLE_SENSOR_MODEL_SERVER                                        (1)

#define ENABLE_SENSOR_MODEL_CLIENT                                           (1)

After each modification, rebuild the project and flash the corresponding board.

3. Sensor Model Code Description

Sensor Client-Server code architecture, from the action on user button to the sensor data display, can be summarized as follow:

Code Architecture

Code sections specific to the Sensor Server/Client Demonstration is identified by the tag: MESH_MODEL_SENSOR_APP_CODE.
To identify all code part related to Sensor Client-Server example, launch a research on this keyword.

3.1. Node Setup

For both Nodes, here Sensor Client and Sensor Server nodes.
In mesh_cfg_usr.h file, setup your node:

  • Number of Element, you can define up to 5 elements per nodes:
/* Max elements: 5 */
#define APPLICATION_NUMBER_OF_ELEMENTS                                         1
  • Number of Models per elements, you can define up to 11 models per elements:
/* Max total Models per element = (SIG + Vendor) = 11 */
/* Max SIG Models per element */
#define USER_SIG_MODELS_MAX_COUNT                                              10
/* Max Vendor Models per element */
#define USER_VENDOR_MODELS_MAX_COUNT                                           1
  • Enable Models required for your demonstration, here Sensor Model Server:
/* Enable Sensor Model Server or Sensor Model Client */
#define ENABLE_SENSOR_MODEL_SERVER                                           (1)
//#define ENABLE_SENSOR_MODEL_CLIENT                                           (1)
  • Or Sensor Model Client:
/* Enable Sensor Model Server or Sensor Model Client */
//#define ENABLE_SENSOR_MODEL_SERVER                                           (1)
#define ENABLE_SENSOR_MODEL_CLIENT                                           (1)

This Number defines in which element the model is enable and works as a bitmap:

  • Bit 0 corresponds to element 1
  • Bit 1 corresponds to element 2
  • Bit 2 corresponds to element 3

For example (5) means the model is enabled on element 1 and element 3

3.2. Sensor Definition

In order to make the Sensor command to work with your sensors, some modifications must be done in sensor_cfg_usr.h file.

  • Define the maximum number of data series your sensors support:
#define SENSOR_MAX_SERIES_COUNT                                                2
  • Define the sum of sensors count on all the elements of your node:
#define TOTAL_SENSORS_COUNT                                                2
  • Define and Initialize your sensors settings:
#define SENSOR2_ELEMENT_IDX                    	 0
#define SENSOR2_PROPERTY_ID                    	TIME_OF_FLIGHT_PID
#define SENSOR2_POSITIVE_TOLERANCE              SENSOR_POSITIVE_TOLERANCE_UNSPECIFIED
#define SENSOR2_NEGATIVE_TOLERANCE            SENSOR_NEGATIVE_TOLERANCE_UNSPECIFIED
[]
#define SENSOR_SERVER_INIT_PARAMS \
{\
  TOTAL_SENSORS_COUNT,\
  {\
    SENSOR1_INIT_PARAMS,\
    SENSOR2_INIT_PARAMS,\
  }\
}

3.3. Sensor Initialization (Server side)

Add the functions to initialize your different sensors in Appli_Sensor_Init, appli_sensor.c.

In the example, we initialize the Time of Flight Sensor (VL53L0X) and the Temperature Sensor (STTS22H):

 /* Sensor Initialization */
  TRACE_M(TF_SENSOR, "VL53L0X init\r\n");
  VL53L0X_PROXIMITY_Init();
  TRACE_M(TF_SENSOR, "STTS22H init\r\n");
  STTS22H_Init_Sensor();


Then, launch the data measurement:

  /* Start measure of the distance */
  VL53L0X_Start_Measure();
  /* Start measure of the temperature */
  STTS22H_Start_Measure();

3.4. SENSOR_GET Request (Client Side)

On button push, call Appli_SensorsClient_API to send SENSOR_GET command to the publish address (defined by the smartphone application), this is done in appli_mesh.c file.
Appli_SensorsClient_API takes as parameter the element index, here 0, the command opcode and the property ID of the sensor targeted.

  /* PRESENT_AMBIENT_TEMPERATURE_PID */
  pPropertyId[0]= 0x4F;           // Property ID byte 0 : Property ID for the sensor
  pPropertyId[1]= 0x00;           // Property ID byte 1 : Property ID for the sensor

  /* Sensor Client Send SENSOR_GET request with PRESENT_AMBIENT_TEMPERATURE_PID */
  Appli_SensorsClient_API(0, SENSOR_GET, pPropertyId);

3.5. Sensor Data reading (Server Side)

Appli_Sensor_ReadValue (appli_sensor.c) is a callback called by Sensor_Status in response of a Sensor Get request.
This gets the value measured by the sensor identified by the property ID received and copy it into a response buffer.
In the example, we initialize the Time of Flight Sensor (VL53L0X) and the Temperature Sensor (STTS22H):

switch(SensorServerInitParams.sensorInitParams[sensorOffset].propertyId)
  {
  case PRESENT_AMBIENT_TEMPERATURE_PID:
    {
      STTS22H_getTemperatureValue(&temp_val);
      pValueParams->data[0] = (MOBLEUINT8)round(temp_val*2);
     []
    }
    break;
case TIME_OF_FLIGHT_PID:
    {
      prox_value = VL53L0X_PROXIMITY_GetDistance();
      []
      pValueParams->data[0] = distance;
    }
    break;
   []

3.6. Sensor Data Answer(Server Side)

Once the data collected from sensor, the Sensor_Status() function calls the BLE Mesh lib function BLEMesh_ModelSendMessage() to send the data buffer through the BLE Mesh network, up to the Client Node.

3.7. Sensor Data Reception (Client Side)

The Client node must decode the data buffer regarding the sensor data marshalling format.
This is done in Appli_Sensor_Status function, in appli_sensor_client.c.
The following code part decode the marshalled sensor data received regarding the Sensor Model specification, to retrieve the Sensor PID and the data length:

 if((pStatus[0] & 0x01) == 0x01){
    sensorStatusFormat=0x01;
    receivedLenght=(MOBLEUINT32)(((pStatus[0] & 0xFE)>>1) + 1);
    receivedPID=(MOBLEUINT16)((pStatus[2] << 8)|(pStatus[1]));
  }

  else{
    sensorStatusFormat=0x00;
    receivedLenght=(MOBLEUINT32)(((pStatus[0] & 0x1E)>>1)+1);
    receivedPID=(MOBLEUINT16)(((pStatus[0] & 0xE0) >> 5)|(pStatus[1] << 3));
  }
Sensor Data Marshalling Formats

Once the Sensor PID is retrieved, manage the sensor data depending on the sensor type.

  switch(receivedPID){
  case PRESENT_AMBIENT_TEMPERATURE_PID:
    TRACE_M(TF_SERIAL_CTRL,"Temperature = %d degrees \n\r", (pStatus[2]/2));
    break;

  case TIME_OF_FLIGHT_PID:  
    TRACE_M(TF_SERIAL_CTRL,"Distance = %d cm \n\r", ((pStatus[4]<<8)|(pStatus[3])));
    break;

    /* Add Sensor PID here */
  default:
    break;
  }

4. Demonstration Handle

1. Flash your boards with the different node projects.
Ensure your boards are un-provisioned by pressing RESET (1) and B1 (2) buttons simultaneously, release RESET and keep B1 pressed until the LED1 (3) is blinking:

Unprovisioning process


2. Launch the Smartphone application and add the different nodes to the network:
Sensor Server Node:
- Provision and Configure:

Sensor Server node provisioning


- Rename the node:

Node renaming


Sensor Client Node:
- Provision and Configure:

Sensor Client node provisioning


- Select the Client Subscription and Publication Addresses:

Subscription/Publication addresses setup


- Rename the node:

Node renaming


3. Launch the Smartphone application and add the different nodes to the network:
- Pressing user button 1 of the Client board send a SENSOR_GET request to the Sensor Server
- The Sensor Server receive the request and Reply with the required sensor data
- The Client decode the data and displays it on his terminal

Demonstration Summary