Hello! To summarize my issue, I have a 6 DOF accelerometer/gyroscope [LSM6DS3TR-C]. I am accessing the sensor using SPI and the Zephyr Sensor API, and my readings are somewhat unstable and slightly incorrect - e.g, when not moving, the sensor's gyroscope measures +/- 0.1 - 0.9 rad/s.
My environment:
- NRF Connect SDK in VSCode - Version 2.1.1
- Zephyr v3.1.99
I'll attach the relevant code, apologies for the length.
Below is my function for creating the SPI device.
/* Function for initializing SPI device */ static const struct device *get_spi_device(void) { const struct device *dev = DEVICE_DT_GET(DT_INST(0, st_lsm6dsl)); if (dev == NULL) { /* No such node, or the node does not have status "okay". */ printk("\nError: no device found.\n"); return NULL; } if (!device_is_ready(dev)) { printk("\nError: Device \"%s\" is not ready; " "check the driver initialization logs for errors.\n", dev->name); return NULL; } printk("Found device \"%s\", getting sensor data\n", dev->name); return dev; }
I access the sensor data using the Sensor API enums.
void main(void) { //... const struct device *spi_dev = get_spi_device(); if (spi_dev == NULL) { return; } static struct sensor_value accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z; while(1){ /* Returns values m/s^2 */ sensor_sample_fetch_chan(spi_dev, SENSOR_CHAN_ACCEL_XYZ); sensor_channel_get(spi_dev, SENSOR_CHAN_ACCEL_X, &accel_x); sensor_channel_get(spi_dev, SENSOR_CHAN_ACCEL_Y, &accel_y); sensor_channel_get(spi_dev, SENSOR_CHAN_ACCEL_Z, &accel_z); // returns gyro data in rad/s sensor_sample_fetch_chan(spi_dev, SENSOR_CHAN_GYRO_XYZ); sensor_channel_get(spi_dev, SENSOR_CHAN_GYRO_X, &gyro_x); sensor_channel_get(spi_dev, SENSOR_CHAN_GYRO_Y, &gyro_y); sensor_channel_get(spi_dev, SENSOR_CHAN_GYRO_Z, &gyro_z); printk("%d.%d,", (accel_x.val1), abs(accel_x.val2)); printk("%d.%d,", (accel_y.val1), abs(accel_y.val2)); printk("%d.%d,", (accel_z.val1), abs(accel_z.val2)); printk("%d.%d,", (gyro_x.val1), abs(gyro_x.val2)); printk("%d.%d,", (gyro_y.val1), abs(gyro_y.val2)); printk("%d.%d\n", (gyro_z.val1), abs(gyro_z.val2)); k_msleep(500); } }
Here is my prj.conf:
# assert will cause soft resets, so set to N for now CONFIG_ASSERT=n #run on restart CONFIG_BOARD_ENABLE_DCDC=n # # Enable RTT to replace UART CONFIG_RTT_CONSOLE=y CONFIG_STDOUT_CONSOLE=y CONFIG_UART_CONSOLE=n CONFIG_USE_SEGGER_RTT=y CONFIG_SHELL_BACKEND_RTT=y # ACCEL/GYRO PRJ.CONF CONFIG_I2C=y CONFIG_SPI=y CONFIG_SENSOR=y # Allow math.h CONFIG_NEWLIB_LIBC=y # Floating point support CONFIG_CBPRINTF_FP_SUPPORT=y # Sensor specific configurations CONFIG_LSM6DSL=y CONFIG_LSM6DSL_TRIGGER_NONE=y CONFIG_LSM6DSL_ACCEL_ODR=8 CONFIG_LSM6DSL_ACCEL_FS=16 CONFIG_LSM6DSL_GYRO_FS=1000 CONFIG_LSM6DSL_GYRO_ODR=8 CONFIG_LSM6DSL_ENABLE_TEMP=y # Config NFC pins as GPIO based on pins used for SPI CONFIG_NFCT_PINS_AS_GPIOS=y
And finally, my overlay file.
&pinctrl { spi1_default: spi1_default { group1 { psels = <NRF_PSEL(SPIM_SCK, 0, 12)>, <NRF_PSEL(SPIM_MOSI, 0, 13)>, <NRF_PSEL(SPIM_MISO, 0, 14)>; }; }; spi1_sleep: spi1_sleep { group1 { psels = <NRF_PSEL(SPIM_SCK, 0, 12)>, <NRF_PSEL(SPIM_MOSI, 0, 13)>, <NRF_PSEL(SPIM_MISO, 0, 14)>; low-power-enable; }; }; }; &spi1 { compatible = "nordic,nrf-spi"; status = "okay"; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; cs-gpios = < &gpio0 11 GPIO_ACTIVE_LOW >; lsm6dsl@0 { status="okay"; compatible = "st,lsm6dsl"; reg = < 0 >; spi-max-frequency = <1000000>; }; }; &spi0 { status="disabled"; }; &i2c0 { status="disabled"; };
My primary concern is the gyroscope values being non-zero and very jittery when I print out the values. I am aware I'm using the library for the LSM6DSL, but I've compared datasheets with the LSM6DS3TR-C and all the registers and conversions are the exact same. Note that my readings are 'almost' correct, in the sense that I can still read G as ~9.81-10 [m/s^2].
I tested this exact same sensor (Adafruit LSM6DS3TR-C Breakout) in an Arduino environment and using the Adafruit library for both LSM6DSL and LSM6DS3TR-C. Both outputted stable zero values for the stationary gyroscope raw register reads. So the culprit has to be somewhere in my Zephyr implementation.
Is there any advice on what could be going wrong here? Any help is greatly appreciated!