How to: Accelerometer

Core module comes with three-axis ultra-low-power linear accelerometer connected via I2C bus. It is capable of motion detection and a free-fall based on interrupts.

Basically you have two options how to use the accelerometer - continuous measurement of acceleration or as an alarm, which triggers event handler if defined conditions occurs.

Recognizable Accelerometer Events

  • TWR_LIS2DH12_EVENT_ERROR

  • TWR_LIS2DH12_EVENT_UPDATE

  • TWR_LIS2DH12_EVENT_ALARM

Continuous Measurement

This can be achieved by setting the update interval in your code with function twr_lis2dh12_set_update_interval, which takes pointer to instantiated accelerometer and time before measurements in milliseconds as parameters.

You also have to instantiate a struct twr_lis2dh12_result_g_t to store the results of measurements. Those values can be retrieved by calling twr_lis2dh12_get_result_g function. In the simple example below, we measure exact values of acceleration in g every second and send them over USB.

#include <application.h>

twr_led_t led;

twr_lis2dh12_t a;
twr_lis2dh12_result_g_t a_result;

void lis2_event_handler(twr_lis2dh12_t *self, twr_lis2dh12_event_t event, void *event_param)
{
    (void) self;
    (void) event_param;

    if (event == TWR_LIS2DH12_EVENT_UPDATE) {
        twr_lis2dh12_get_result_g(&a, &a_result);
        twr_log_debug("X: %f\r\nY: %f\r\nZ: %f\r\n", a_result.x_axis, a_result.y_axis, a_result.z_axis);
    } else {
        twr_log_debug("error");
    }
}

void application_init(void)
{
    twr_log_init(TWR_LOG_LEVEL_DEBUG, TWR_LOG_TIMESTAMP_OFF);

    twr_lis2dh12_init(&a, TWR_I2C_I2C0, 0x19);
    twr_lis2dh12_set_event_handler(&a, lis2_event_handler, NULL);
    twr_lis2dh12_set_update_interval(&a, 1000);
}

Alarm

Alarm is a very interesting “feature”. This allows you to set up certain conditions when the “alarm” should be triggered (like “wake up, when module is moved in direction of X-axis && acceleration is higher than 1g”). The module uses interrupts to inform the microcontroller, which means that the microcontroller can sleep when it is not being moved and only be awaken when moved.

You can set conditions for the alarm in struct twr_lis2dh12_alarm_t.

When the accelerometer checks these settings it uses logical AND operation (so every set condition needs to occur for the alarm to be triggered).

In the example below, we set the alarm to be triggered when core module is moved in direction of X-axis with acceleration > 1g. When triggered, integrated red LED will switch on for one second.

After flashing, try to move your Core module very slowly. It will do nothing in any direction. Then try to move it quickly up and down - once again nothing happens, because this movement is in Z-axis. Now try to make a quick move in X-axis and the LED should light up.

 1#include <application.h>
 2
 3twr_led_t led;
 4
 5twr_lis2dh12_t a;
 6twr_lis2dh12_result_g_t a_result;
 7
 8// alarm settings
 9twr_lis2dh12_alarm_t alarm1;
10
11twr_scheduler_task_id_t disable_led_task;
12
13void disable_led(void* params)
14{
15    (void) params;
16    twr_led_set_mode(&led, TWR_LED_MODE_OFF);
17}
18
19void lis2_event_handler(twr_lis2dh12_t *self, twr_lis2dh12_event_t event, void *event_param)
20{
21    (void) self;
22    (void) event_param;
23
24    if (event == TWR_LIS2DH12_EVENT_ALARM) {
25        twr_led_set_mode(&led, TWR_LED_MODE_ON);
26        twr_scheduler_plan_from_now(disable_led_task, 1000);
27    }
28}
29
30void application_init(void)
31{
32    // here you can set conditions for the alarm to be triggered
33    alarm1.x_high = true;
34    alarm1.threshold = 1;
35
36    twr_led_init(&led, TWR_GPIO_LED, false, false);
37    twr_led_set_mode(&led, TWR_LED_MODE_OFF);
38
39    twr_lis2dh12_init(&a, TWR_I2C_I2C0, 0x19);
40    twr_lis2dh12_set_alarm(&a, &alarm1);
41    twr_lis2dh12_set_event_handler(&a, lis2_event_handler, NULL);
42
43    disable_led_task = twr_scheduler_register(disable_led, NULL, TWR_TICK_INFINITY);
44}