Skip to main content

Accelerometer Sample

Introduction

The "Accelerometer Sample" initializes the LIS2DH accelerometer on the Icarus boards and reads the acceleration values in a loop. This sample is compatible with the following boards:

info

[NCS v2.2.x] Download sample from Icarus - Accelerometer Sample (NCS v2.2.x)

info

[NCS v2.1.x] Download sample from Icarus - Accelerometer Sample (NCS v2.1.x)

info

[legacy] Download sample from Icarus - Accelerometer Sample (legacy)

Project configuration

The initialization of the application is done in the prj.conf file. By enabling certain options in this file, Zephyr will include the required libraries for the application. For this sample the following options are set:

CONFIG_I2C=y

CONFIG_SENSOR=y
CONFIG_LIS2DH=y
CONFIG_LIS2DH_ACCEL_RANGE_8G=y
CONFIG_LIS2DH_ODR_2=y

The option CONFIG_I2C enables the use of the I2C library. I2C needs to be enabled in order for the sensor library to read/write data to the accelerometer.

The option CONFIG_SENSOR enables the use of the sensor libraries used to access various different sensors. This option is a dependency of the CONFIG_LIS2DH option.

The option CONFIG_LIS2DH enables the use of the LIS2DH driver. The LIS2DH12, amongst others, is compatible with this driver. This driver allows further user-defined options to be set in the prj.conf file.

The option CONFIG_LIS2DH_ACCEL_RANGE_8G is one of the user-defined options available. It sets the measuring range of the accelerometer. This can be from +/- 2G up to +/- 16G. This sample uses 8G.

The option CONFIG_LIS2DH_ODR_2 is another user-defined option. It sets the sampling frequency of the accelerometer. This specific option corresponds to a sampling rate of 10Hz.

The full list of possible user-defined options can be found by searching "LIS2DH" at Zephyr's Kconfig Search.

Code explanation

This sample contains 2 source files: accelerometer.c and main.c. The functionality of the sample is mainly contained in accelerometer.c.

First a reference to the accelerometer needs to be obtained. The accelerometer is defined in the device tree of the board. The device tree is expressed as a set of files which are included in the nRF Connect SDK. In these files, the hardware of the Icarus boards is described in terms of hardware addresses and pin numbers.

In accelerometer.c, this reference is obtained in the init_accelerometer function:

const struct device *accel;

accel = DEVICE_DT_GET(ACCEL_NODE);

with the ACCEL_NODE defined as:

#define ACCEL_NODE       DT_ALIAS(accel0)

The accelerometer has an alias: accel0. This is the alias which is assigned to the hardware address of the accelerometer in the device tree of the board. Using DEVICE_DT_GET a pointer to the device with the alias accel0 is obtained from the device tree. This pointer is then set to the accel structure.

the reading of the data is done using the get_accelerometer_data function. This function uses the structure, which was set up, to read data:

sensor_sample_fetch(accel);

struct sensor_value value_x;
sensor_channel_get(accel, SENSOR_CHAN_ACCEL_X, &value_x);

struct sensor_value value_y;
sensor_channel_get(accel, SENSOR_CHAN_ACCEL_Y, &value_y);

struct sensor_value value_z;
sensor_channel_get(accel, SENSOR_CHAN_ACCEL_Z, &value_z);

In order to convert the value returned from the sensor to a double, the sensor library provides a helper method:

double x_accel = sensor_value_to_double(&value_x);

With these 2 functions set up, they can be called from main. First init_accelerometer is called to get the reference for the accelerometer. Then, in an infinite loop, 3 doubles are passed to get_accelerometer_data as pointers. These will contain the values from the accelerometer after the function call. The values are printed to the console, in m/s^2, and the loop continues:

double x_accel = 0;
double y_accel = 0;
double z_accel = 0;
get_accelerometer_data(&x_accel, &y_accel, &z_accel);

printk("Acceleration values:\n");
printk("-------------------------------------------------------------------------------\n");
printf("X: %lf (m/s^2), Y: %lf (m/s^2), Z: %lf (m/s^2)\n", x_accel, y_accel, z_accel);
printk("-------------------------------------------------------------------------------\n");