XDK

Developer Portal

XDK - The Sensor X-perience

Programmable sensor device and IoT prototyping platform with an open SDK for any use case.

Enable all Sensors in one

Note: The code snippets in this article are intended for XDK-Workbench versions 3.4.0 and higher.

The XDK provides one Sensor API to manage all XDK sensor functionalities on the device at once. The interfaces can be used to initialize and read the measured sensor data and it also allows minor specific sensor configuration. Applications can use the sensor API in order to measure the surrounding world with all XDK sensors at once.

  1. Implementation
  2. Initializing and Configuring the Sensors
  3. Enabling the Sensors
  4. Reading Data from the Sensors
  5. Full Code Example

Implementation

This chapter demonstrates the usage of the XDK's sensors in reading and showing their collected data. The current chapter will describe how to initialize all sensors in general by using the XDK_Sensor.h interface with only a short number of configurations. If more specific configurations are required, please visit the advanced sensor chapter for each sensor.

Initializing and Configuring the Sensors

The interface XDK_Sensor.h utilizes a new kind of initialization, by using a configuration struct of the type Sensor_Setup_T, which includes the following configuration elements:

Structure element Description
CmdProcessorHandle The main command processor handle
Enable The sensors to be enabled (See 'Sensor_Enable_T' struct below)
Config Sensor configurations (See 'Sensor_Configuration_T' struct below)

Additionally, the XDK_Sensor.h utilizes the new configuration struct of the type Sensor_Enable_T, which includes the following configuration elements:

Structure element Description
bool Accel A boolean representing if the accelerometer is to be enabled or not
bool Mag A boolean representing if the magnetometer is to be enabled or not
bool Gyro A boolean representing if the gyroscope is to be enabled or not
bool Humidity A boolean representing if the humidity sensor is to be enabled or not
bool Temp A boolean representing if the temperature sensor is to be enabled or not
bool Pressure A boolean representing if the pressure sensor is to be enabled or not
bool Light A boolean representing if the light sensor is to be enabled or not
bool Noise A boolean representing if the noise sensor is to be enabled or not

The interface XDK_Sensor.h utilizes additionally a configuration struct of the type Sensor_Configuration_T, which includes the following configuration elements:

Structure element Description
Accel The accelerometer sensor configurations
Mag The magnetometer sensor configurations
Gyro The gyro sensor configurations
Light The light sensor configurations
Temp The temperature sensor configurations

An example about how to configure and initialize the Sensor Utility functionality is shown in the following code below.

Please note that the example code for the XDK_Sensor.h interface is following the conventions of the new XdkApplicationtemplate example from the XDK-Workbench 3.4.0.

#include "XDK_Sensor.h"
// other interfaces here

#define APP_TEMPERATURE_OFFSET_CORRECTION   (-3459)

static Sensor_Setup_T SensorSetup =
        {
                .CmdProcessorHandle = NULL,
                .Enable =
                        {
                                .Accel = true,
                                .Mag = true,
                                .Gyro = true,
                                .Humidity = true,
                                .Temp = true,
                                .Pressure = true,
                                .Light = true,
                                .Noise = true,
                        },
                .Config =
                        {
                                .Accel =
                                        {
                                                .Type = SENSOR_ACCEL_BMA280,
                                                .IsRawData = false,
                                                .IsInteruptEnabled = false,

                                        },
                                .Gyro =
                                        {
                                                .Type = SENSOR_GYRO_BMG160,
                                                .IsRawData = false,
                                        },
                                .Mag =
                                        {
                                                .IsRawData = false,
                                        },
                                .Light =
                                        {
                                                .IsInteruptEnabled = false,

                                        },
                                .Temp =
                                        {
                                                .OffsetCorrection = APP_TEMPERATURE_OFFSET_CORRECTION,
                                        },
                        },
        };/**< Sensor setup parameters */

The example code shows first the inclusion of the interface XDK_Sensor.h. Afterwards, a struct called SensorSetup of the type Sensor_Setup_T is declared and filled with the parameters described in the previously listed table.

Also, due to the influence of the XDK's board heat, an additional temperature offset in millidegree #define APP_TEMPERATURE_OFFSET_CORRECTION (-3459) is recommended to compensate the incorrect temperature. This offset is passed into the configuration element for the temperature sensor.

static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);


    Sensor_Setup(&SensorSetup);
    //other implementation
}

Enabling the Sensors

Now all setup configurations are made, it is time to enable the sensors. For that, the function Sensor_Enable() needs to be called in the context of the function AppControllerEnable() as shown in the code below.

static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);

    Sensor_Enable();
}

Reading Data from the Sensors

Now that all configuration and enabling is done, the measuring functionality needs to be implemented. For that, the function Sensor_GetData() can be used to retrieve the data from all configured sensors.

The code below demonstrates how this is implemented in the function AppControllerFire().

static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);

    Sensor_Value_T sensorValue;

    memset(&sensorValue, 0x00, sizeof(sensorValue));

    Sensor_GetData(&sensorValue);

}

First, a variable sensorValue of the type Sensor_Value_T is declared and will be used to contains all the measured sensor values. Then every element of the variable sensorValue is filled with zeros by using the function memset(). Afterwards the sensor data is retrieved by passing the variable sensorValue into the function Sensor_GetData().

Note: In XDK-Workbench version 3.5.0 and higher, it is not possible to sample all sensors at once since the sampling of the acoustic sensor will throw an error that its data could not be sampled and therefore display an error. As such, it is only possible to use the acoustic sensor alone will disabling all other sensors and vice versa.

Full Code Example

/* module includes ********************************************************** */

/* own header files */
#include "XdkAppInfo.h"

#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "XDK_Sensor.h"
#include "BCDS_Assert.h"
#include "BCDS_CmdProcessor.h"
#include "FreeRTOS.h"
#include "timers.h"

/* constant definitions ***************************************************** */
#define APP_TEMPERATURE_OFFSET_CORRECTION   (-3459)

/* local variables ********************************************************** */

static CmdProcessor_T *AppCmdProcessor;/**< Handle to store the main Command processor handle to be reused by ServalPAL thread */

static xTimerHandle sensorHandle = NULL;


static Sensor_Setup_T SensorSetup =
        {
                .CmdProcessorHandle = NULL,
                .Enable =
                        {
                                .Accel = true,
                                .Mag = true,
                                .Gyro = true,
                                .Humidity = true,
                                .Temp = true,
                                .Pressure = true,
                                .Light = true,
                                .Noise = false,
                        },
                .Config =
                        {
                                .Accel =
                                        {
                                                .Type = SENSOR_ACCEL_BMA280,
                                                .IsRawData = false,
                                                .IsInteruptEnabled = false,

                                        },
                                .Gyro =
                                        {
                                                .Type = SENSOR_GYRO_BMG160,
                                                .IsRawData = false,
                                        },
                                .Mag =
                                        {
                                                .IsRawData = false,
                                        },
                                .Light =
                                        {
                                                .IsInteruptEnabled = false,

                                        },
                                .Temp =
                                        {
                                                .OffsetCorrection = APP_TEMPERATURE_OFFSET_CORRECTION,
                                        },
                        },
        };/**< Sensor setup parameters */



static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);

    Retcode_T retcode = RETCODE_OK;
    Sensor_Value_T sensorValue;

    memset(&sensorValue, 0x00, sizeof(sensorValue));

        retcode = Sensor_GetData(&sensorValue);
        if (RETCODE_OK == retcode)
        {

                printf("Accelerometer Converted data :\n\rx =%ld mg\n\ry =%ld mg\n\rz =%ld mg\r\n",
                        (long int) sensorValue.Accel.X,
                        (long int) sensorValue.Accel.Y,
                        (long int) sensorValue.Accel.Z);

                printf("Accelerometer Raw data :\n\rx =%ld \n\ry =%ld\n\rz =%ld\r\n",
                        (long int) sensorValue.Accel.X,
                        (long int) sensorValue.Accel.Y,
                        (long int) sensorValue.Accel.Z);

                printf("BME280 Environmental Conversion Data for Humidity:\n\rh =%ld %%rh\r\n",
                        (long int) sensorValue.RH);

                printf("BME280 Environmental Conversion Data for Pressure :\n\rp =%ld Pa\r\n",
                        (long int) sensorValue.Pressure);

                printf("BME280 Environmental Conversion Data for temperature :\n\rt =%ld mDeg\r\n",
                        (long int) sensorValue.Temp);

                printf("Magnetometer Converted data :\n\rx =%ld microTesla\n\ry =%ld microTesla\n\rz =%ld microTesla\n\rr =%ld\r\n",
                        (long int) sensorValue.Mag.X,
                        (long int) sensorValue.Mag.Y,
                        (long int) sensorValue.Mag.Z,
                        (long int) sensorValue.Mag.R);

                printf("Magnetometer Raw data :\n\rx =%ld\n\ry =%ld\n\rz =%ld \n\rr =%ld\r\n",
                        (long int) sensorValue.Mag.X,
                        (long int) sensorValue.Mag.Y,
                        (long int) sensorValue.Mag.Z,
                        (long int) sensorValue.Mag.R);

                printf("Gyro Converted Data :\n\rx =%ld mDeg\n\ry =%ld mDeg\n\rz =%ld mDeg\r\n",
                        (long int) sensorValue.Gyro.X,
                        (long int) sensorValue.Gyro.Y,
                        (long int) sensorValue.Gyro.Z);

                printf("Gyro Raw Data :\n\rx =%ld \n\ry =%ld \n\rz =%ld \r\n",
                        (long int) sensorValue.Gyro.X,
                        (long int) sensorValue.Gyro.Y,
                        (long int) sensorValue.Gyro.Z);

                printf("Light sensor data obtained in millilux :%d \n\r", (unsigned int) sensorValue.Light);

                printf("Noise Sensor RMS Voltage :\r\nVrms = %f \r\n", sensorValue.Noise);
            }

        if (RETCODE_OK != retcode)
        {
            Retcode_RaiseError(retcode);
        }
}

static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);

    Retcode_T retcode = Sensor_Enable();


    if (RETCODE_OK == retcode)
    {

        uint32_t timerBlockTime = UINT32_MAX;
        xTimerStart(sensorHandle, timerBlockTime);

    }
}


static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);

    uint32_t oneSecondDelay = UINT32_C(1000);
    uint32_t timerAutoReloadOn = UINT32_C(1);

    Retcode_T retcode = Sensor_Setup(&SensorSetup);

    if (RETCODE_OK == retcode)
    {
        sensorHandle = xTimerCreate((const char *)"AppController", oneSecondDelay, timerAutoReloadOn, NULL, AppControllerFire);
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));
    }
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

/* global functions ***********************************************************/

/** Refer interface header for description*/
void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T*) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}