Interfacing IMU Sensor (LSM6DSL) with i2c

hi ,I am using nrf52840dk- nrf52840 board to interface the IMU Sensor using  I2C using nrf connect sdk for vs code.
But I am facing error:

i'm using the code in ncs/samples/sensor/lsm6dso

here is prj.conf:

CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_LSM6DSO_TRIGGER_GLOBAL_THREAD=y
CONFIG_LSM6DSO=y
here is thr overlay file:
&pinctrl {
    i2c0_default: i2c0_default {
        group1 {
            psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
                <NRF_PSEL(TWIM_SCL, 0, 27)>;
                bias-pull-up;
        };
    };

    i2c0_sleep: i2c0_sleep {
        group1 {
            psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,
                <NRF_PSEL(TWIM_SCL, 0, 27)>;
            low-power-enable;
        };
    };
};



&i2c0 {
    compatible = "nordic,nrf-twi";
    status = "okay";
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    label = "I2C_0";
    clock-frequency = <I2C_BITRATE_STANDARD>;
    lsm6dso@6a {
        compatible = "st,lsm6dso";
        reg = <0x6a>;
       
    };
};
the probleme is when i flash my code this the output :
*** Booting nRF Connect SDK v2.5.2 ***
Testing LSM6DSO sensor in trigger mode.

Could not set sensor type and channel
  • Hello,

    Have you seen any activity on the I2C pins? Did you use any logic analyzer or oscilloscope to see any activity on the I2C pins? 

    You may try to use other I2C pin to check if that works?

  • yes i'm sure that  I2C pins are working fine but still i'm facing the same problem

  • i don't know  if i'm right but i think the probleme have to do with the interrupt pin ,but i don't know how exactly  please correct me if i'm wrong

  • Hello Rania,

    Could you please share your project file so Ican look at the overlay file and the relevant code in the main.c file?

  • hi i solved the earlier issue by replacing the tigger code by the pooling code in the main.c.But now i'm trying to calculate the roll and pitch angles using accx,accy and accz ,here is main.c code:

    /*
     * Copyright (c) 2020 Yestin Sun
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <stdio.h>
    #include <zephyr.h>
    #include <device.h>
    #include <drivers/sensor.h>
    #include <math.h> // Include math library for trigonometric functions
    
    
    #define LSM6DSO DT_INST(0, st_lsm6dso)
    
    #if DT_NODE_HAS_STATUS(LSM6DSO, okay)
    #define LSM6DSO_LABEL DT_LABEL(LSM6DSO)
    #else
    #error Your devicetree has no enabled nodes with compatible "st,lsm6dso"
    #define LSM6DSO_LABEL "<none>"
    #endif
    #ifndef M_PI
    #define M_PI 3.14159265358979323846
    #endif
    
    
    static inline float out_ev(struct sensor_value *val)
    {
    	return (val->val1 + (float)val->val2 / 1000000);
    }
    
    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);
    	
    	// Calculate Roll angle in degrees
        float AccX = out_ev(&x);
        float AccY = out_ev(&y);
        float AccZ = out_ev(&z);
    	printf("AccX = %.2f, AccY = %.2f, AccZ = %.2f\n", AccX, AccY, AccZ);
        float Roll = atan2( AccY, sqrt(AccX * AccX + AccZ * AccZ)) * 180 / M_PI;
    
        // Calculate Pitch angle in degrees
        float Pitch = atan2(-AccX, sqrt(AccY * AccY + AccZ * AccZ)) * 180 / M_PI;
    
        printf("Roll = %.2f degrees; Pitch = %.2f degrees\n", Roll, Pitch);
    
    
    
    	/* 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 dps y:%f dps z:%f dps\n",
    			out_ev(&x), out_ev(&y), 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 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));
    	}
    }
    
    
    #else
    static void trigger_handler(const struct device *dev,
    			    const struct sensor_trigger *trig)
    {
    	fetch_and_display(dev);
    }
    static void test_trigger_mode(const struct device *dev)
    {
    	struct sensor_trigger trig;
    
    	if (set_sampling_freq(dev) != 0)
    		return;
    
    	trig.type = SENSOR_TRIG_DATA_READY;
    	trig.chan = SENSOR_CHAN_ACCEL_XYZ;
    
    	if (sensor_trigger_set(dev, &trig, trigger_handler) != 0) {
    		printf("Could not set sensor type and channel\n");
    		return;
    	}
    #endif
    
    void main(void)
    {
    	const struct device *dev = device_get_binding(LSM6DSO_LABEL);
    
    	if (dev == NULL) {
    		printf("No device \"%s\" found.\n", LSM6DSO_LABEL);
    		return;
    	}
    
    #ifdef CONFIG_LSM6DSO_TRIGGER
    printf("Testing LSM6DSO sensor in polling mode.\n\n");
    	test_polling_mode(dev);
    	
    #else
    	printf("Testing LSM6DSO sensor in trigger mode.\n\n");
    	test_trigger_mode(dev);
    #endif
    }
    

    and here is the prj.conf file

    :

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_LSM6DSO=y
    CONFIG_LSM6DSO_TRIGGER_GLOBAL_THREAD=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
    CONFIG_NEWLIB_LIBC=y

    the probleme is when i run this code is not outputing the values :

    
    AccX = , AccY = , AccZ = 
    Roll =  degrees; Pitch =  degrees
    gyro x: dps y: dps z: dps
    trig_cnt:9
    
    AccX = , AccY = , AccZ = 
    Roll =  degrees; Pitch =  degrees
    gyro x: dps y: dps z: dps
    trig_cnt:10
    

    and when i searched about it i found out that i should includes proper settings for floating-point CONFIG_ARM_FPU=y

    but when i do it' s unkown symbol so i guess Floating Point Unit) if available on your target device  which is nrf52840dk

    .so i stuck in this problem

Related