Hello,
I've been working on a project involving an IMU and bluetooth for a while, and had been using the IMU (LSM6DSO) on polling mode. Unfortunately, I found out that I will need to use trigger mode for this application, so I've been trying to figure out how to do that. I've made what feels like a hundred changes to my config and devicetree overlay files to try and get this working and have had no success so far. It seems like many of the trigger mode config options don't work, or say that they weren't able to set the value to y. I did find one combination that at least let me successfully build my code, and I will share both of those files here. I've been starting with the lsm6dso sample and trying to add code that sends an interrupt when the IMU records >2g acceleration and turns an LED on the nrf52 dk, but currently nothing occurs after the line 'Failed to set acceleration threshold' is printed in the terminal. Lastly, I have verified that my physical wiring and connections are as they should be, and uploaded the working code (using polling mode) to confirm. I would really appreciate any help or information that you can share regarding this. Thank you!
/* * Copyright (c) 2020 Yestin Sun * * SPDX-License-Identifier: Apache-2.0 */ #include <stdio.h> #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/sensor.h> #include <zephyr/drivers/gpio.h> static inline float out_ev(struct sensor_value *val) { return (val->val1 + (float)val->val2 / 1000000); } #define LED0_NODE DT_ALIAS(led0) static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); static void fetch_and_display(const struct device *dev) { struct sensor_value x, y, z; static int trig_cnt; trig_cnt++; /* lsm6dso accel */ sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ); sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &x); sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &y); sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &z); printf("accel x:%f ms/2 y:%f ms/2 z:%f ms/2\n", (double)out_ev(&x), (double)out_ev(&y), (double)out_ev(&z)); /* lsm6dso gyro */ sensor_sample_fetch_chan(dev, SENSOR_CHAN_GYRO_XYZ); sensor_channel_get(dev, SENSOR_CHAN_GYRO_X, &x); sensor_channel_get(dev, SENSOR_CHAN_GYRO_Y, &y); sensor_channel_get(dev, SENSOR_CHAN_GYRO_Z, &z); printf("gyro x:%f rad/s y:%f rad/s z:%f rad/s\n", (double)out_ev(&x), (double)out_ev(&y), (double)out_ev(&z)); printf("trig_cnt:%d\n\n", trig_cnt); } static int set_sampling_freq(const struct device *dev) { int ret = 0; struct sensor_value odr_attr; /* set accel/gyro sampling frequency to 12.5 Hz */ odr_attr.val1 = 12.5; odr_attr.val2 = 0; ret = sensor_attr_set(dev, SENSOR_CHAN_ACCEL_XYZ, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr); if (ret != 0) { printf("Cannot set sampling frequency for accelerometer.\n"); return ret; } ret = sensor_attr_set(dev, SENSOR_CHAN_GYRO_XYZ, SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr); if (ret != 0) { printf("Cannot set sampling frequency for gyro.\n"); return ret; } return 0; } #ifdef CONFIG_LSM6DSO_TRIGGER static void trigger_handler(const struct device *dev, const struct sensor_trigger *trig) { static bool led_on = false; printf("Triggered.\n"); // Toggle LED led_on = !led_on; gpio_pin_set_dt(&led, led_on); // Optional: also display sensor data fetch_and_display(dev); } static void test_trigger_mode(const struct device *dev) { struct sensor_trigger trig; struct sensor_value threshold; if (set_sampling_freq(dev) != 0) return; // Set 2g threshold (approx. 19.6 m/s²) threshold.val1 = 19; threshold.val2 = 600000; if (sensor_attr_set(dev, SENSOR_CHAN_ACCEL_XYZ, SENSOR_ATTR_SLOPE_TH, &threshold) != 0) { printf("Failed to set acceleration threshold\n"); return; } // Set trigger type to threshold trig.type = SENSOR_TRIG_THRESHOLD; trig.chan = SENSOR_CHAN_ACCEL_XYZ; if (sensor_trigger_set(dev, &trig, trigger_handler) != 0) { printf("Could not set threshold trigger\n"); return; } } #else static void test_polling_mode(const struct device *dev) { if (set_sampling_freq(dev) != 0) { return; } while (1) { fetch_and_display(dev); k_sleep(K_MSEC(1000)); } } #endif int main(void) { const struct device *const dev = DEVICE_DT_GET_ONE(st_lsm6dso); if (!device_is_ready(dev)) { printk("%s: device not ready.\n", dev->name); return 0; } #ifdef CONFIG_LSM6DSO_TRIGGER printf("Testing LSM6DSO sensor in trigger mode.\n\n"); if (!gpio_is_ready_dt(&led)) { printk("LED device not ready\n"); return 0; } if (gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE) != 0) { printk("Failed to configure LED\n"); return 0; } test_trigger_mode(dev); #else printf("Testing LSM6DSO sensor in polling mode.\n\n"); test_polling_mode(dev); #endif return 0; }
Config file: