Vibration Monitoring using LIS3DH sensor on nRF52840

Hi Nordic team,

I hope this message finds you well. I am currently working on developing applications for custom boards utilizing the nRF Connect SDK v2.4.0, with a particular focus on the nRF52840 microcontroller.

In our ongoing project, we have a requirement to implement a feature involving Vibration Monitoring, which triggers whenever a threshold level is crossed. I have successfully interfaced the sensor and am able to obtain X, Y, and Z values using the LIS2DH drivers. However, I am encountering difficulties in implementing the vibration detection using the interrupt pin. Although I have specified the interrupt pin in the .overlay file, I am not receiving the expected output.

&i2c0 {
    lis2dh@19 {
        compatible = "st,lis2dh";
        reg = <0x19>;
		status = "okay";		
        label = "LIS3DH";
		irq-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>, <&gpio0 1 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
    };
};

Could you please provide some sample code for reference regarding Vibration Monitoring?

Additionally, I would like to inquire if LIS3DH drivers are available, as it would be beneficial for our project.

Best regards,


Anmol

Parents
  • Hello,

    Although I have specified the interrupt pin in the .overlay file, I am not receiving the expected output.

    can you please provide more information about the problem? Maybe some logs and such.

  • Hello Hakon,

    I'm using LIS3DH sensor and having trouble understanding how to utilize interrupts that trigger whenever a vibration threshold level, for example, 5m/s^2, is exceeded. Could you please provide some sample code for reference regarding Vibration Monitoring?

    Regards,

    Anmol

  • Hi,

    I have solved the problem. Directly used the interrupt trigger function from lis2dh sample and threshold attribute in sensor_attr_set() function with some manual computations. This is giving me readings whenever threshold level is crossed.

    /*Enable trigger handler for LIS*/
    static void lis_trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
    {
    	int64_t uptime = k_uptime_get();
        
        if(uptime >= 750){
    
    		LOG_INF("Vibration is beyond the 750ms\n");
    		vibration_detected = 1;
    		read_sound();
    
    	}
    	else
    	{
    		vibration_detected = 0;
    	}
    
    }
    
    /*Threshold for Vibration Monitering*/
    void configure_lis_vibration_threshold(const struct device *lis_dev) {
    
        int ret;
        struct sensor_value vib_val;
    	
        vib_val.val1 = lowG_vib_threshold; // Adjust this threshold value as needed
        vib_val.val2 = 0; //(int32_t) SENSOR_G *1.5
       
           struct sensor_trigger lis_trig = {
            .type = SENSOR_TRIG_DATA_READY,
            .chan = SENSOR_CHAN_ACCEL_XYZ,
        };
        
        // Set sensor attribute for upper threshold
        ret=	sensor_attr_set(lis_dev, SENSOR_CHAN_ACCEL_X, SENSOR_ATTR_UPPER_THRESH,&vib_val);
        if (ret) {
            LOG_ERR("Failed to set sensor attribute: %d", ret);
            return;
        }
    	
        // Register trigger handler
        ret = sensor_trigger_set(lis_dev, &lis_trig, lis_trigger_handler);
        if (ret) {
            LOG_ERR("Failed to set sensor trigger: %d", ret);
            return;
        }
    }
    
    /*Read Sound Values with/without Vibration*/
    void read_sound(){
        
    	configure_lis_vibration_threshold(lis2dux12);
        wakeup_now();
    
    	LOG_INF("Sound reading is started");
    	LOG_INF("Vibration detected flag = %d", vibration_detected);
    	if(vibration_detected) 
    	{
    		Motion_Started = 1;
    		// Add sleep mode
    		k_sleep(K_MSEC((1000 * motion_sound_rate) - 1000));  
    		vibration_detected = 0;
    	}
    	else
    	{
    		Motion_Started = 0;
    	}
    
    	sleep_now();
    }
    
    
    

  • Hi  Can you share your overlay file and main.c I am trying to run lis2dh example with nrf52 using i2c at 24 and 25 respectively with INT1 at p0_30 and INT2 at P0_29 but i am getting error no sensor found

  • Hi Ahtasham,

    I've attached my main.c and overlay file. Hopefully, these can assist you in getting the LIS2DH example up and running with your nRF52 setup. Make sure that the I2C pins are correctly configured in the overlay file as per your requirement. I have mentioned the same in respective file as well.

    main.c file

    /**
    * \file main.c
    *
    * \brief LIS3DH Sensor Interfacing
    *
    * \date 2024-05-04
    */
    
    #include <stdio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(LIS3DH, CONFIG_LOG_DEFAULT_LEVEL);
    
    static void fetch_and_display(const struct device *sensor)
    {
    	struct sensor_value accel[3];
    
    	int rc = sensor_sample_fetch(sensor);
    	if (rc != 0) {
            LOG_INF("ERROR: Sensor sample fetch failed: %d\n", rc);
            return;
        }
    
    	rc = sensor_channel_get(sensor, SENSOR_CHAN_ACCEL_XYZ, accel);
        if (rc != 0) {
            LOG_INF("ERROR: Sensor channel get failed: %d\n", rc);
        } else {
            LOG_INF("X: %.2f,   Y: %.2f,   Z: %.2f",
                   sensor_value_to_double(&accel[0]),
                   sensor_value_to_double(&accel[1]),
                   sensor_value_to_double(&accel[2]));
        }
    }
    
    
    int main(void)
    {
    	const struct device *const sensor = DEVICE_DT_GET_ANY(st_lis2dh);
    
    	if (sensor == NULL) {
    		LOG_INF("No device found\n");
    		return 0;
    	}
    	if (!device_is_ready(sensor)) {
    		LOG_INF("Device %s is not ready\n", sensor->name);
    		return 0;
    	}
    
    	k_sleep(K_MSEC(1000));
    
    	LOG_INF("Acceleration measured are as follows:");
    
    	while (true) 
    	{
    		fetch_and_display(sensor);
    		k_sleep(K_MSEC(2000));
    	}
    }

    lis.overlay file

    /*
    * \file lis.overlay
    *
    * \date 2024-07-04
    */
    
    &pinctrl {
        i2c0_default: i2c0_default {
            group1 {
                psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,  /* Change this SDA pin as per your requirement */
                        <NRF_PSEL(TWIM_SCL, 0, 25)>;  /* Change this SCL pin as per your requirement */
            };
        };
    
        i2c0_sleep: i2c0_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SDA, 0, 26)>,  /* Change this SDA pin as per your requirement */
                        <NRF_PSEL(TWIM_SCL, 0, 25)>;  /* Change this SCL pin as per your requirement */
                low-power-enable;
            };
        };
    
    };
    
    
    &i2c0 {
        lis2dh@19 {
            compatible = "st,lis2dh";
            reg = <0x19>;
    		status = "okay";		
            label = "LIS2DH";
    		irq-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>, <&gpio1 1 GPIO_ACTIVE_HIGH>; /* Change the gpio0 pin as per your requirement, first is for int1 & other for int2 */
    		disconnect-sdo-sa0-pull-up;
    		int2-gpio-config =<1>;
        };
    };

    Regards,

    Anmol

  • Hi  I tried your changes but I am still unable to get device struct. However I used i2c and register programming able to communicate with sensor

  • Hi Ahtasham,

    Which sensor are you working on? I didn't get what exact problem you are facing. Can you explain me it in brief your exact requirement?

    Btw, have you enabled prj configurations? Try including these:

    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_LIS2DH=y
    CONFIG_GPIO=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
     
    CONFIG_LOG=y
    CONFIG_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_PRINTK=y
    Regards,
    Anmol
Reply
  • Hi Ahtasham,

    Which sensor are you working on? I didn't get what exact problem you are facing. Can you explain me it in brief your exact requirement?

    Btw, have you enabled prj configurations? Try including these:

    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_LIS2DH=y
    CONFIG_GPIO=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
     
    CONFIG_LOG=y
    CONFIG_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_PRINTK=y
    Regards,
    Anmol
Children
  • Hi  i also want to run lis3dh using interrupt I am able to run sensor with registers writing but when I follow your above overlay and try to run lis2dh example I get device struct empty 

    following are MACROs i am using in my prj.conf

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_CBPRINTF_FP_SUPPORT=y
    CONFIG_UART_CONSOLE=n
    CONFIG_RTT_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LIS2DH=y
    Regards
    Ahtasham
Related