How to configure Trigger for ADXL362 using sensor library

I am studying a little bit about the sensor library. Unfortunately, I haven't been able to find any good documentation about sensor library, what function calls are available for each sensor and etc... Is it available?

Anyways, my current problem is with ADXL362 accelerometer. I am trying to set a trigger (instead of polling data like in accel_polling project available at zephyr\samples\sensor\accel_polling)

I want to only read data when the movement threshold has been triggered. 

However, it is not fully clear how can this be achieved and could not find any useful information online about it.

My project repository:

github.com/.../thingy91_motion_trigger

I am currently testing on the Thingy 91 board and running the following code:

#include <stdio.h>
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>

K_SEM_DEFINE(sem, 0, 1);

static const enum sensor_channel channels[] = {
	SENSOR_CHAN_ACCEL_X,
	SENSOR_CHAN_ACCEL_Y,
	SENSOR_CHAN_ACCEL_Z,
};

#define DEFAULT_ADXL362_NODE DT_ALIAS(adxl362)
BUILD_ASSERT(DT_NODE_HAS_STATUS(DEFAULT_ADXL362_NODE, okay),
			 "ADXL362 not specified in DT");

// DEVICE TREE STRUCTURE
const struct device *adxl1362_sens = DEVICE_DT_GET(DEFAULT_ADXL362_NODE);


static void trigger_handler(const struct device *dev,
			    const struct sensor_trigger *trig)
{
	switch (trig->type) {
	case SENSOR_TRIG_DATA_READY:
		if (sensor_sample_fetch(dev) < 0) {
			printk("Sample fetch error\n");
			return;
		}
		k_sem_give(&sem);
		break;
	case SENSOR_TRIG_THRESHOLD:
		printk("Threshold trigger\n");
		break;
	default:
		printk("Unknown trigger\n");
	}
}

void main(void)
{

	struct sensor_value accel[3];


	if (!device_is_ready(adxl1362_sens))
	{
		printk("sensor: device %s not ready.\n", adxl1362_sens->name);
		return 0;
	}
	else
	{
		printk("sensor: device %s ready.\n", adxl1362_sens->name);
	}


	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER)) {
		struct sensor_trigger trig = { .chan = SENSOR_CHAN_ACCEL_X };

		trig.type = SENSOR_TRIG_THRESHOLD;
		if (sensor_trigger_set(adxl1362_sens, &trig, trigger_handler)) {
			printk("Trigger set error\n");
			return;
		}

		trig.type = SENSOR_TRIG_DATA_READY;
		if (sensor_trigger_set(adxl1362_sens, &trig, trigger_handler)) {
			printk("Trigger set error\n");
		}
	}

	while (true) {
		if (IS_ENABLED(CONFIG_ADXL362_TRIGGER)) {
			k_sem_take(&sem, K_FOREVER);
		} else {
			k_sleep(K_MSEC(1000));
			if (sensor_sample_fetch(adxl1362_sens) < 0) {
				printk("Sample fetch error\n");
				return;
			}
		}

		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_X, &accel[0]) < 0) {
			printk("Channel get error\n");
			return;
		}

		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_Y, &accel[1]) < 0) {
			printk("Channel get error\n");
			return;
		}

		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_Z, &accel[2]) < 0) {
			printk("Channel get error\n");
			return;
		}

		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
		       sensor_value_to_double(&accel[0]),
		       sensor_value_to_double(&accel[1]),
		       sensor_value_to_double(&accel[2]));
	}
}

my prj.conf is as following:

CONFIG_CBPRINTF_FP_SUPPORT=y


# Enable Edge Impulse dependencies
CONFIG_CPP=y
CONFIG_STD_CPP11=y
CONFIG_FP16=n


# SPI
CONFIG_SPI=y
CONFIG_SPI_NRFX=y
CONFIG_MAIN_STACK_SIZE=4096


# LOG
CONFIG_LOG=y

# ADXL362
CONFIG_SENSOR=y
CONFIG_ADXL362=y
CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD=y
CONFIG_ADXL362_INTERRUPT_MODE=1
CONFIG_ADXL362_ABS_REF_MODE=1
CONFIG_ADXL362_ACTIVITY_THRESHOLD=200


and my thingy91_nr9160_ns.overlay:

/ {
    aliases {
            adxl372 = &adxl372;
            adxl362 = &adxl362;
    };
};

After flasing the nRF9160 on the Thingy 91 with the source code shown above, I am getting the following error:

À*** Booting nRF Connect SDK v2.5.0 ***
sensor: device adxl362@0 ready.
[00:00:00.270,568] [1B][1;31m<err> ADXL362: Unsupported sensor trigger[1B][0m
Trigger set error

I would appreciate if someone could help me:

  1. By sharing sensor library documentation (especially what function calls are available for each sensor and how to use them correctly)
  2. Figure out what could be the issue with the code and why I am getting unsupported sensor trigger issue
  • UPDATE:

    After digging through the source code of the ADXL362 driver (zephyr\drivers\sensor\adxl362)

    I have discovered that SENSOR_TRIG_THRESHOLD is not supported.

    See the adxl362_trigger_set function (adxl362_trigger.c):

    int adxl362_trigger_set(const struct device *dev,
    			const struct sensor_trigger *trig,
    			sensor_trigger_handler_t handler)
    {
    	struct adxl362_data *drv_data = dev->data;
    	const struct adxl362_config *config = dev->config;
    	uint8_t int_mask, int_en, status_buf;
    
    	if (!config->interrupt.port) {
    		return -ENOTSUP;
    	}
    
    	switch (trig->type) {
    	case SENSOR_TRIG_MOTION:
    		k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
    		drv_data->act_handler = handler;
    		drv_data->act_trigger = trig;
    		k_mutex_unlock(&drv_data->trigger_mutex);
    		int_mask = ADXL362_INTMAP1_ACT;
    		/* Clear activity and inactivity interrupts */
    		adxl362_get_status(dev, &status_buf);
    		break;
    	case SENSOR_TRIG_STATIONARY:
    		k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
    		drv_data->inact_handler = handler;
    		drv_data->inact_trigger = trig;
    		k_mutex_unlock(&drv_data->trigger_mutex);
    		int_mask = ADXL362_INTMAP1_INACT;
    		/* Clear activity and inactivity interrupts */
    		adxl362_get_status(dev, &status_buf);
    		break;
    	case SENSOR_TRIG_DATA_READY:
    		k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
    		drv_data->drdy_handler = handler;
    		drv_data->drdy_trigger = trig;
    		k_mutex_unlock(&drv_data->trigger_mutex);
    		int_mask = ADXL362_INTMAP1_DATA_READY;
    		adxl362_clear_data_ready(dev);
    		break;
    	default:
    		LOG_ERR("Unsupported sensor trigger");
    		return -ENOTSUP;
    	}
    
    	if (handler) {
    		int_en = int_mask;
    	} else {
    		int_en = 0U;
    	}
    
    	return adxl362_reg_write_mask(dev, ADXL362_REG_INTMAP1, int_mask, int_en);
    }

    So I have modified my code slightly, removed the SENSOR_TRIG_THRESHOLD  and added only those trigger methods that are supported. See my updated main.c below:

    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/spi.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    
    K_SEM_DEFINE(sem, 0, 1);
    
    static const enum sensor_channel channels[] = {
    	SENSOR_CHAN_ACCEL_X,
    	SENSOR_CHAN_ACCEL_Y,
    	SENSOR_CHAN_ACCEL_Z,
    };
    
    #define DEFAULT_ADXL362_NODE DT_ALIAS(adxl362)
    BUILD_ASSERT(DT_NODE_HAS_STATUS(DEFAULT_ADXL362_NODE, okay),
    			 "ADXL362 not specified in DT");
    
    // DEVICE TREE STRUCTURE
    const struct device *adxl1362_sens = DEVICE_DT_GET(DEFAULT_ADXL362_NODE);
    
    static void trigger_handler(const struct device *dev,
    							const struct sensor_trigger *trig)
    {
    	switch (trig->type)
    	{
    	case SENSOR_TRIG_DATA_READY:
    	{
    		printk("SENSOR_TRIG_DATA_READY\n");
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error\n");
    			return;
    		}
    		k_sem_give(&sem);
    		break;
    	}
    	case SENSOR_TRIG_MOTION:
    	{
    		printk("SENSOR_TRIG_MOTION\n");
    		break;
    	}
    
    	case SENSOR_TRIG_STATIONARY:
    	{
    		printk("SENSOR_TRIG_STATIONARY\n");
    		break;
    	}
    
    	default:
    		printk("Unknown trigger\n");
    	}
    }
    
    void main(void)
    {
    
    	struct sensor_value accel[3];
    
    	if (!device_is_ready(adxl1362_sens))
    	{
    		printk("sensor: device %s not ready.\n", adxl1362_sens->name);
    		return 0;
    	}
    	else
    	{
    		printk("sensor: device %s ready.\n", adxl1362_sens->name);
    	}
    
    
    
    	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    	{
    		struct sensor_trigger trig = {.chan = SENSOR_CHAN_ACCEL_XYZ};
    
    		trig.type = SENSOR_TRIG_DATA_READY;
    		if (sensor_trigger_set(adxl1362_sens, &trig, trigger_handler))
    		{
    			printk("SENSOR_TRIG_DATA_READY set error\n");
    		}
    
    		trig.type = SENSOR_TRIG_MOTION;
    		if (sensor_trigger_set(adxl1362_sens, &trig, trigger_handler))
    		{
    			printk("SENSOR_TRIG_MOTION set error\n");
    		}
    
    		trig.type = SENSOR_TRIG_STATIONARY;
    		if (sensor_trigger_set(adxl1362_sens, &trig, trigger_handler))
    		{
    			printk("SENSOR_TRIG_STATIONARY set error\n");
    		}
    
    
    	}
    
    	while (true)
    	{
    		if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    		{
    			k_sem_take(&sem, K_FOREVER);
    		}
    
    		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_X, &accel[0]) < 0)
    		{
    			printk("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_Y, &accel[1]) < 0)
    		{
    			printk("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(adxl1362_sens, SENSOR_CHAN_ACCEL_Z, &accel[2]) < 0)
    		{
    			printk("Channel get error\n");
    			return;
    		}
    
    		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    			   sensor_value_to_double(&accel[0]),
    			   sensor_value_to_double(&accel[1]),
    			   sensor_value_to_double(&accel[2]));
    	}
    }

    Once I run the code, the following logs are being printed:

    ð*** Booting nRF Connect SDK v2.5.0 ***
    sensor: device adxl362@0 ready.
    SENSOR_TRIG_STATIONARY

    I have tried to move the Thingy91 board but nothing is triggered. I believe I am getting closed to figuring out how to properly set this up. I just need to figure out how to trigger SENSOR_TRIG_MOTION and SENSOR_TRIG_DATA_READY. Do I need any additional setup to get it to work?

    Perhaps I am not handling the events in trigger_handler correctly?

    static void trigger_handler(const struct device *dev,
    							const struct sensor_trigger *trig)
    {
    	switch (trig->type)
    	{
    	case SENSOR_TRIG_DATA_READY:
    	{
    		printk("SENSOR_TRIG_DATA_READY\n");
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error\n");
    			return;
    		}
    		k_sem_give(&sem);
    		break;
    	}
    	case SENSOR_TRIG_MOTION:
    	{
    		printk("SENSOR_TRIG_MOTION\n");
    		break;
    	}
    
    	case SENSOR_TRIG_STATIONARY:
    	{
    		printk("SENSOR_TRIG_STATIONARY\n");
    		break;
    	}
    
    	default:
    		printk("Unknown trigger\n");
    	}
    }

  • Thanks for reply. I had a look at the source code that you have suggested. I have learnt a couple of things:

    1. Only 2 triggers are created for the ADXL362 (motion and stationary). No trigger for data ready for some reason

    2. SENSOR_CHAN_ACCEL_XYZ is not supported for setting UPPER_THRESH and LOWER_THRESH

    After adjusting the source code a little bit. See my current full source code. 

    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/spi.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main);
    
    struct sensor_value data[3];
    
    /* Convert to s/m2 depending on the maximum measured range used for adxl362. */
    #if IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_2G)
    #define ADXL362_RANGE_MAX_M_S2 19.6133
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_4G)
    #define ADXL362_RANGE_MAX_M_S2 39.2266
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_RANGE_8G)
    #define ADXL362_RANGE_MAX_M_S2 78.4532
    #endif
    
    /* This is derived from the sensitivity values in the datasheet. */
    #define ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX 2000
    
    #if IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_12_5)
    #define ADXL362_TIMEOUT_MAX_S 5242.88
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_25)
    #define ADXL362_TIMEOUT_MAX_S 2621.44
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_50)
    #define ADXL362_TIMEOUT_MAX_S 1310.72
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_100)
    #define ADXL362_TIMEOUT_MAX_S 655.36
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_200)
    #define ADXL362_TIMEOUT_MAX_S 327.68
    #elif IS_ENABLED(CONFIG_ADXL362_ACCEL_ODR_400)
    #define ADXL362_TIMEOUT_MAX_S 163.84
    #endif
    
    #define ADXL362_TIMEOUT_RESOLUTION_MAX 65536
    
    #define DEFAULT_ADXL362_NODE DT_ALIAS(adxl362)
    BUILD_ASSERT(DT_NODE_HAS_STATUS(DEFAULT_ADXL362_NODE, okay),
    			 "ADXL362 not specified in DT");
    
    // DEVICE TREE STRUCTURE
    const struct device *adxl1362_sens = DEVICE_DT_GET(DEFAULT_ADXL362_NODE);
    
    static int ext_sensors_accelerometer_threshold_set(double threshold, bool upper);
    
    static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig)
    {
    	int err = 0;
    	switch (trig->type)
    	{
    
    	case SENSOR_TRIG_MOTION:
    	{
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error \n");
    			return;
    		}
    
    		err = sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, &data[0]);
    		if (err)
    		{
    			printk("sensor_channel_get, error: %d \n", err);
    			return;
    		}
    
    		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    			   sensor_value_to_double(&data[0]),
    			   sensor_value_to_double(&data[1]),
    			   sensor_value_to_double(&data[2]));
    
    		printk("Inactivity detected\n");
    		break;
    	}
    
    	case SENSOR_TRIG_STATIONARY:
    	{
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error \n");
    			return;
    		}
    
    		err = sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, &data[0]);
    		if (err)
    		{
    			printk("sensor_channel_get, error: %d \n", err);
    			return;
    		}
    
    		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    			   sensor_value_to_double(&data[0]),
    			   sensor_value_to_double(&data[1]),
    			   sensor_value_to_double(&data[2]));
    
    		printk("Activity detected\n");
    		break;
    	}
    
    	default:
    		printk("Unknown trigger %u \n",(trig->type));
    	}
    }
    
    void main(void)
    {
    
    	if (!device_is_ready(adxl1362_sens))
    	{
    		printk("sensor: device %s not ready.\n", adxl1362_sens->name);
    		return 0;
    	}
    
    	ext_sensors_accelerometer_threshold_set(3, true);
    	ext_sensors_accelerometer_threshold_set(0.5, false);
    
    	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    	{
    		printk("Configuring triggers\n");
    		struct sensor_trigger trig_motion = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_MOTION,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_motion, trigger_handler))
    		{
    			printk("SENSOR_TRIG_MOTION set error\n");
    		}
    
    		struct sensor_trigger trig_stationary = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_STATIONARY,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_stationary, trigger_handler))
    		{
    			printk("SENSOR_TRIG_STATIONARY set error\n");
    		}
    	}
    }
    
    static int ext_sensors_accelerometer_threshold_set(double threshold, bool upper)
    {
    	int err, input_value;
    	double range_max_m_s2 = ADXL362_RANGE_MAX_M_S2;
    
    	if ((threshold > range_max_m_s2) || (threshold <= 0.0))
    	{
    		LOG_ERR("Invalid %s threshold value: %f", upper ? "activity" : "inactivity", threshold);
    		return -ENOTSUP;
    	}
    
    	/* Convert threshold value into 11-bit decimal value relative
    	 * to the configured measuring range of the accelerometer.
    	 */
    	threshold = (threshold *
    				 (ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX / range_max_m_s2));
    
    	/* Add 0.5 to ensure proper conversion from double to int. */
    	threshold = threshold + 0.5;
    	input_value = (int)threshold;
    
    	if (input_value >= ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX)
    	{
    		input_value = ADXL362_THRESHOLD_RESOLUTION_DECIMAL_MAX - 1;
    	}
    	else if (input_value < 0)
    	{
    		input_value = 0;
    	}
    
    	const struct sensor_value data = {
    		.val1 = input_value};
    
    	enum sensor_attribute attr = upper ? SENSOR_ATTR_UPPER_THRESH : SENSOR_ATTR_LOWER_THRESH;
    
    	/* SENSOR_CHAN_ACCEL_XYZ is not supported by the driver in this case. */
    	err = sensor_attr_set(adxl1362_sens,
    						  SENSOR_CHAN_ACCEL_X,
    						  attr,
    						  &data);
    	if (err)
    	{
    		LOG_ERR("Failed to set accelerometer threshold value");
    		LOG_ERR("Device: %s, error: %d",
    				adxl1362_sens->name, err);
    
    		return err;
    	}
    	return 0;
    }

    And my proj.conf:

    CONFIG_CBPRINTF_FP_SUPPORT=y
    
    # SPI
    CONFIG_SPI=y
    CONFIG_SPI_NRFX=y
    CONFIG_MAIN_STACK_SIZE=4096
    
    # LOG
    CONFIG_LOG=y
    
    # ADXL362
    CONFIG_SENSOR=y
    CONFIG_ADXL362=y
    CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD=y
    CONFIG_ADXL362_INTERRUPT_MODE=1
    CONFIG_ADXL362_ABS_REF_MODE=1
    CONFIG_ADXL362_ACCEL_RANGE_2G=y
    CONFIG_ADXL362_ACCEL_ODR_400=y

    The serial terminal logs

    :

    As I move the device, multiple unknown triggers fire at once (maybe like 5 or something).  Also, some unknown triggers are triggered once when the device is kept still.

    I have looked through the code multiple times and cannot find any issues regarding the triggers. I believe they are set correctly:

    	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    	{
    		printk("Configuring triggers\n");
    		struct sensor_trigger trig_motion = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_MOTION,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_motion, trigger_handler))
    		{
    			printk("SENSOR_TRIG_MOTION set error\n");
    		}
    
    		struct sensor_trigger trig_stationary = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_STATIONARY,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_stationary, trigger_handler))
    		{
    			printk("SENSOR_TRIG_STATIONARY set error\n");
    		}
    	}

    static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig)
    {
    	int err = 0;
    	switch (trig->type)
    	{
    
    	case SENSOR_TRIG_MOTION:
    	{
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error \n");
    			return;
    		}
    
    		err = sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, &data[0]);
    		if (err)
    		{
    			printk("sensor_channel_get, error: %d \n", err);
    			return;
    		}
    
    		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    			   sensor_value_to_double(&data[0]),
    			   sensor_value_to_double(&data[1]),
    			   sensor_value_to_double(&data[2]));
    
    		printk("Inactivity detected\n");
    		break;
    	}
    
    	case SENSOR_TRIG_STATIONARY:
    	{
    		if (sensor_sample_fetch(dev) < 0)
    		{
    			printk("Sample fetch error \n");
    			return;
    		}
    
    		err = sensor_channel_get(dev, SENSOR_CHAN_ACCEL_XYZ, &data[0]);
    		if (err)
    		{
    			printk("sensor_channel_get, error: %d \n", err);
    			return;
    		}
    
    		printk("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    			   sensor_value_to_double(&data[0]),
    			   sensor_value_to_double(&data[1]),
    			   sensor_value_to_double(&data[2]));
    
    		printk("Activity detected\n");
    		break;
    	}
    
    	default:
    		printk("Unknown trigger %u \n",(trig->type));
    	}
    }

    I have also updated the code in the repository so you can have a look at the project files: https://github.com/krupis/thingy91_motion_trigger

    Perhaps you are able to detect any mistakes in my code and have a clue why I would be getting this unknown trigger even though I have defined my motion and stationary triggers

  • UPDATE

    I have figured out what was an issue regarding unknown triggers.

    The issue was I was setting the upper and lower threshold triggers before setting up trigger handlers

    The below is not correct:

    void main(void)
    {
    
    	if (!device_is_ready(adxl1362_sens))
    	{
    		printk("sensor: device %s not ready.\n", adxl1362_sens->name);
    		return 0;
    	}
    
    	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    	{
    		ext_sensors_accelerometer_threshold_set(10.0, true);
    		ext_sensors_accelerometer_threshold_set(1.5, false);
    	
    		printk("Configuring triggers\n");
    		struct sensor_trigger trig_motion = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_MOTION,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_motion, trigger_handler))
    		{
    			printk("SENSOR_TRIG_MOTION set error\n");
    		}
    
    		struct sensor_trigger trig_stationary = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_STATIONARY,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_stationary, trigger_handler))
    		{
    			printk("SENSOR_TRIG_STATIONARY set error\n");
    		}
    
    	}
    }

    This is correct:

    void main(void)
    {
    
    	if (!device_is_ready(adxl1362_sens))
    	{
    		printk("sensor: device %s not ready.\n", adxl1362_sens->name);
    		return 0;
    	}
    
    	if (IS_ENABLED(CONFIG_ADXL362_TRIGGER))
    	{
    		printk("Configuring triggers\n");
    		struct sensor_trigger trig_motion = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_MOTION,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_motion, trigger_handler))
    		{
    			printk("SENSOR_TRIG_MOTION set error\n");
    		}
    
    		struct sensor_trigger trig_stationary = {
    			.chan = SENSOR_CHAN_ACCEL_XYZ,
    			.type = SENSOR_TRIG_STATIONARY,
    		};
    		if (sensor_trigger_set(adxl1362_sens, &trig_stationary, trigger_handler))
    		{
    			printk("SENSOR_TRIG_STATIONARY set error\n");
    		}
    
    		ext_sensors_accelerometer_threshold_set(10.0, true);
    		ext_sensors_accelerometer_threshold_set(1.5, false);
    	}
    }

    So now I am able to trigger MOTION and STATIONARY events:

  • Hi,

    Your experiments and code examples were quite valuable for me.

    There still is a detail in the setup that I don't quite understand.
    You're monitoring for the beginning of a movement with the SENSOR_TRIG_MOTION trigger and then immediately register the end of the movement with the SENSOR_TRIG_STATIONARY trigger.

    Are these two events the only thing of interest for your implementation? I mean, in an example closer to the real world, sampling of continuous movement after the initial registering is also of interest. And sampling usually stops when the stationary trigger is met.

    I'm asking this because I'm trying to implement the described scenario (measuring vibrations, where samples are enclosed by the two said triggers) but two things bug me (I'm not very experienced in embedded programming, yet):

    1. The data in the Serial Terminal shows that the two triggers are registered immediately one after the other regardless for how long I'm shaking the Thingy (i.e. there is constant sequence of pairs of coordinates (movement+stationary) - stationary is registered even when I'm moving the device);
    2. I'm not sure how to interpret the continuous movement in the context of Zephyr/the sensor driver:
      1. is there a separate trigger to be used (I've seen someone using 
        SENSOR_TRIG_DATA_READY in another code sample ...)?
        b. or maybe some kind of loop has to be employed in the specific case?
        c. or another OS related mechanism should be used (an interrupt, or something)?

    Sorry if I hijacked your question but as you said - the documentation is quite scarce ...

    Best Regards,

    Ivan

Related