Accelerometer values don't refresh
Answer
4/9/18 12:23 PM

Dear members of community,

I would like to print the values of the accelerometer and the light sensor with the following code:

/************************************************************
*   AccelerationSensor.c
************************************************************/

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

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

#include "XdkSensorHandle.h"

/* own header files */


// Function that read and print the sensor data of the BMI160 to the console of the XDK-Workbench
static void readLightAccelerometer(xTimerHandle xTimer)
{
    (void) xTimer;

    Retcode_T returnValueLight = RETCODE_FAILURE;
    Retcode_T returnValueAcc = RETCODE_FAILURE;
    Accelerometer_XyzData_T bmi160 = {INT32_C(0), INT32_C(0), INT32_C(0)};
    memset(&bmi160, 0, sizeof(CalibratedAccel_XyzMps2Data_T));
	/* Read light sensor and accelerometer data */

	uint32_t max44009 = UINT32_C(0);

	returnValueLight = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,&max44009);
	returnValueAcc = Accelerometer_readXyzGValue(xdkAccelerometers_BMI160_Handle,&bmi160);

    if (RETCODE_OK != returnValueLight) {
            printf("Light sensor data could not be obtained ");
        }
    else if (RETCODE_OK != returnValueAcc) {
    		printf("Accelerator data could not be obtained ");
    	}
    else {
        printf("%.4d;%.4f;%.4f;%.4f\n\r",
        		(unsigned int) max44009, (float) bmi160.xAxisData, (float) bmi160.yAxisData, (float) bmi160.zAxisData);
    }
}

// Function that initializes the Lightsensor with the MAX44009 handler and with additional presettings
static void initLightSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    Retcode_T returnBrightnessValue = RETCODE_FAILURE;
    Retcode_T returnIntegrationTimeValue = RETCODE_FAILURE;

    /* initialize light sensor */

    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);

    if ( RETCODE_OK != returnValue){
        printf("MAX44009 Light Sensor initialization failed\n\r");
    }

    returnBrightnessValue = LightSensor_setBrightness(xdkLightSensor_MAX44009_Handle,LIGHTSENSOR_NORMAL_BRIGHTNESS);
    if (RETCODE_OK != returnBrightnessValue) {
        printf("Configuring brightness failed \n\r");
    }
    returnIntegrationTimeValue = LightSensor_setIntegrationTime(xdkLightSensor_MAX44009_Handle,LIGHTSENSOR_200MS);
    if (RETCODE_OK != returnIntegrationTimeValue) {
        printf("Configuring integration time failed \n\r");
    }
}

// Function that initializes the Accelerometer with the BMI160 handler and with additional presettings
static void initAccelerometer(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    Retcode_T returnBandwidthValue = RETCODE_FAILURE;
    Retcode_T returnRangeValue = RETCODE_FAILURE;

    /* initialize accelerometer */

    returnValue = Accelerometer_init(xdkAccelerometers_BMI160_Handle);

    if ( RETCODE_OK != returnValue) {
        printf("BMI160 Accelerometer initialization failed\n\r");
    }

    returnBandwidthValue = Accelerometer_setBandwidth(xdkAccelerometers_BMI160_Handle,ACCELEROMETER_BMI160_BANDWIDTH_200HZ);

    if (RETCODE_OK != returnBandwidthValue) {
        printf("Configuring bandwidth failed \n\r");
    }
    returnRangeValue = Accelerometer_setRange(xdkAccelerometers_BMI160_Handle,ACCELEROMETER_BMI160_RANGE_4G);

    if (RETCODE_OK != returnRangeValue) {
        printf("Configuring range failed \n\r");
    }
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);

    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t fourMilisecondDelay = UINT32_C(4);
    uint32_t timerAutoReloadOn = UINT32_C(1);

    //xTimerHandle lightSensorHandle = NULL;
    xTimerHandle lightaccelerometerHandle = NULL;

	initLightSensor();
    initAccelerometer();

    /* Creation and start of the timer task */
    
    lightaccelerometerHandle = xTimerCreate((const char *) "readLight&Acclerometer", fourMilisecondDelay,timerAutoReloadOn, NULL, readLightAccelerometer);

    xTimerStart(lightaccelerometerHandle,timerBlockTime);
}

It actually prints the values of both sensors, but while the values of the light sensor are being refreshed as expected, the accelerometer-values remain allways the same.

The console prints are for example:

INFO | XDK DEVICE 1: 241920;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 241920;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 241920;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 3600;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 3600;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 3600;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000
INFO | XDK DEVICE 1: 243360;-42.0000;0.0000;2023.0000

Also the values of the accelerometer seem to be really strange to stand for gravity values.

Any idea what I did wrong?

 

0 (0 Votes)
RE: Accelerometer values don't refresh
Answer
4/9/18 3:17 PM as a reply to Aleksandr Gorovoj.
Hello Aleksandr,

there seems to be an issue with the BMI160 when the bandwidth is set to 200Hz. The accelerometer's internal API will then produce the same result every time.

Setting the bandwidth to anything lower than 200Hz (for example 100Hz) will make the code work as expected. Alternatively, the BMA280 can be used as well.

I will forward this issue to the responsible developer.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
0 (0 Votes)
RE: Accelerometer values don't refresh
Answer
4/10/18 10:59 AM as a reply to Alexander Sawtschuk.

Dear Alexander,

 

thanks for the hint. I've changed the code to read the BMA280 @ 500Hz and it works.

/************************************************************
*   AccelerationSensor.c
************************************************************/

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

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

#include "XdkSensorHandle.h"

/* own header files */



// Function that read and print the sensor data of the BMA280 to the console of the XDK-Workbench
static void readLightAccelerometer(xTimerHandle xTimer)
{
    (void) xTimer;

    Retcode_T returnValueLight = RETCODE_FAILURE;
    Retcode_T returnValueAcc = RETCODE_FAILURE;
    Accelerometer_XyzData_T bma280 = {INT32_C(0), INT32_C(0), INT32_C(0)};
    memset(&bma280, 0, sizeof(CalibratedAccel_XyzMps2Data_T));
	/* Read light sensor and accelerometer data */

	uint32_t max44009 = UINT32_C(0);

	returnValueAcc = Accelerometer_readXyzGValue(xdkAccelerometers_BMA280_Handle,&bma280);
	returnValueLight = LightSensor_readLuxData(xdkLightSensor_MAX44009_Handle,&max44009);


    if (RETCODE_OK != returnValueLight) {
            printf("Light sensor data could not be obtained ");
        }
    else if (RETCODE_OK != returnValueAcc) {
    		printf("Accelerator data could not be obtained ");
    	}
    else if (RETCODE_OK == returnValueLight && RETCODE_OK == returnValueAcc) {
        printf("%.4d;%.4f;%.4f;%.4f\n\r",
        		(unsigned int) max44009, (float) bma280.xAxisData, (float) bma280.yAxisData, (float) bma280.zAxisData);
    }
}

// Function that initializes the Lightsensor with the MAX44009 handler and with additional presettings
static void initLightSensor(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    Retcode_T returnBrightnessValue = RETCODE_FAILURE;
    Retcode_T returnIntegrationTimeValue = RETCODE_FAILURE;

    /* initialize light sensor */

    returnValue = LightSensor_init(xdkLightSensor_MAX44009_Handle);

    if ( RETCODE_OK != returnValue){
        printf("MAX44009 Light Sensor initialization failed\n\r");
    }

    returnBrightnessValue = LightSensor_setBrightness(xdkLightSensor_MAX44009_Handle,LIGHTSENSOR_NORMAL_BRIGHTNESS);
    if (RETCODE_OK != returnBrightnessValue) {
        printf("Configuring brightness failed \n\r");
    }
    returnIntegrationTimeValue = LightSensor_setIntegrationTime(xdkLightSensor_MAX44009_Handle,LIGHTSENSOR_200MS);
    if (RETCODE_OK != returnIntegrationTimeValue) {
        printf("Configuring integration time failed \n\r");
    }
}

// Function that initializes the Accelerometer with the BMI160 handler and with additional presettings
static void initAccelerometer(void)
{
    Retcode_T returnValue = RETCODE_FAILURE;
    Retcode_T returnBandwidthValue = RETCODE_FAILURE;
    Retcode_T returnRangeValue = RETCODE_FAILURE;

    /* initialize accelerometer */

    returnValue = Accelerometer_init(xdkAccelerometers_BMA280_Handle);

    if ( RETCODE_OK != returnValue) {
        printf("BMA280 Accelerometer initialization failed\n\r");
    }

    returnBandwidthValue = Accelerometer_setBandwidth(xdkAccelerometers_BMA280_Handle,ACCELEROMETER_BMA280_BANDWIDTH_500HZ);

    if (RETCODE_OK != returnBandwidthValue) {
        printf("Configuring bandwidth failed \n\r");
    }
    returnRangeValue = Accelerometer_setRange(xdkAccelerometers_BMA280_Handle,ACCELEROMETER_BMA280_RANGE_8G);

    if (RETCODE_OK != returnRangeValue) {
        printf("Configuring range failed \n\r");
    }
}

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)
{
    if (CmdProcessorHandle == NULL)
    {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);

    uint32_t timerBlockTime = UINT32_MAX;
    uint32_t oneMilisecondDelay = UINT32_C(1);
    uint32_t timerAutoReloadOn = UINT32_C(1);

    //xTimerHandle lightSensorHandle = NULL;
    xTimerHandle lightaccelerometerHandle = NULL;

	initLightSensor();
    initAccelerometer();

    /* Creation and start of the timer task */
    /*lightSensorHandle = xTimerCreate((const char *) "readLightSensor", oneMilisecondDelay,timerAutoReloadOn, NULL, readLightSensor); */
    lightaccelerometerHandle = xTimerCreate((const char *) "readLight&Acclerometer", oneMilisecondDelay, timerAutoReloadOn, NULL, readLightAccelerometer);

    //xTimerStart(lightSensorHandle,timerBlockTime);
    xTimerStart(lightaccelerometerHandle,timerBlockTime);
}

One thing is that I am reading the GValues (as no m/s²-Values are possible in BCDS_Accelerometer.h), but this GValues are some kind of strange. As for example:

                    (lux   ; xAxis ; yAxis ; zAxis  )
INFO | XDK DEVICE 1: 345600;14.0000;2.0000;1011.0000

Are the values of the axes in mili g not standard g so I have to devide them by 1000 and multiplicate by 9.81 to get m/s²?

 

Other Question:

I've set the BMA280 Bandwidth to 500Hz and provided to xTimerCreate a one milisecond delay and one milisecond of autoreload. But the XDK prints only rount about 400 values each second instead of 1000. What could cause that?

0 (0 Votes)
RE: Accelerometer values don't refresh
Answer
4/10/18 4:24 PM as a reply to Aleksandr Gorovoj.
Hello Aleksandr,

the z-axis shows a value of 1011 because it is converted to milli G. As you proposed, you would have to divide by 1000 and multiply by 9.81 to convert it to m/s^s.

As for why you only get 400 results per second, despite attempting to produce results every millisecond. Output via USB is very time-consuming, as such, it takes more than one tick to read the data and to print it. In some cases, it even takes three ticks.

An absolute frequency of 500Hz is not possible, if your print every single set of data immediately.

My colleague discussed this in detail in this thread here , in case you are interested.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
+1 (1 Vote)
RE: Accelerometer values don't refresh
Answer
4/11/18 7:26 AM as a reply to Alexander Sawtschuk.

Hey Alexander,

thank you again for the fast reply. So as I understood you, there is only one way to get the most out of the sensor's sampling rate by buffering the values and send the data as "bigger packages"? ,

There is no need to try to optimize my code in other ways?

Greets

0 (0 Votes)
RE: Accelerometer values don't refresh
Answer
4/11/18 3:40 PM as a reply to Aleksandr Gorovoj.
Hello Aleksandr,

by sending bigger packages you will likely achieve a higher rate, but since USB will still be quite the bottleneck, optimizing the frequency will be difficult.

If you plan to send messages via WiFi, you will have even more options in regards to how messages are sent. This is because the simplelink chip processes and sends messages asynchronously from the XDK's MCU.

So, if you stay with USB, I recommend to optimize sending as much as possible (i.e. minimze the number of bytes you send, and how often you send them). Of course, I can give advice in that regard as well. Otherwise, if you plan to use WiFi or BLE, I would recommend to implement the communication using one of those modules, before optimizing the transmission.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Alex
0 (0 Votes)