Power off LSM6DSO Sensor between measurements

Hello,
I want to switch off the power supply to my LSM6DSO IMU between measurements. The measurements only take place once a minute. If I operate it permanently with voltage, it would consume about 200uA. To save this, I switched off the voltage. Unfortunately this does not work, I no longer get any values back when I query the sensor. I tried it with different delays between switching on and measuring, but 0 values are always displayed. If I constantly power the IMU, everything works.
You can watch it briefly in a video. www.youtube.com/watch


nrf connect sdk 2.1.2

What do I have to change to make this work? or how can I initialize the lsm6dso manually?

Best regards, Jonas

		gpio_pin_set(gpio_dev, VDD_PIN_IMU, 1);
		k_sleep(K_MSEC(10));
		remap_pins_imu();
		pm_device_action_run(imu_dev,PM_DEVICE_ACTION_TURN_ON);		
		get_rotation(imu_dev);
		pm_device_action_run(imu_dev,PM_DEVICE_ACTION_TURN_OFF);
		k_sleep(K_MSEC(10));
		// gpio_pin_set(gpio_dev, VDD_PIN_IMU, 0);
dynamic_pinctrl_evaluation.zip

Parents Reply Children
  • Okay, is there Any LSM9... LSM6... driver, where this is implemented and I can have a look how to do it right?

  • Not that I know of but I used the BME280 Zephyr driver as a reference for how to handle the *_pm_state_action function.

  • Thanks, I just added the power management functionality in the lsm6dso driver and receive now measurement values. Not correct ones, but better than only zeros, 
    If someone has the same Problem here a quick guide how to add power management functionality to a sensor driver: 

    The <driver_model>.c file has to be expanded with a pm_action function. 

    #ifdef CONFIG_PM_DEVICE
    static int lsm6dso_pm_action(const struct device *dev,
    			    enum pm_device_action action)
    {
    	int ret = 0;
    
    	switch (action) {
    	case PM_DEVICE_ACTION_RESUME:
    		/* Re-initialize the chip */
    		ret = lsm6dso_init(dev);
    		break;
    	case PM_DEVICE_ACTION_SUSPEND:
    		/* Put the chip into sleep mode - 
    		I haven't done this, because I don't need it actually */
    		break;
    	default:
    		return -ENOTSUP;
    	}
    	return ret;
    }
    #endif /* CONFIG_PM_DEVICE */

    Next the DEVICE_INIT define has to be edited: 

    #define LSM6DSO_DEVICE_INIT(inst)					\
    	DEVICE_DT_INST_DEFINE(inst,					\
    			    lsm6dso_init,				\
    			    PM_DEVICE_DT_INST_GET(inst),	\  // <- instead of NULL add this
    			    &lsm6dso_data_##inst,			\
    			    &lsm6dso_config_##inst,			\
    			    POST_KERNEL,				\
    			    CONFIG_SENSOR_INIT_PRIORITY,		\
    			    &lsm6dso_driver_api);

    Lastly edit the <Device>_DEFINE :

    #define LSM6DSO_DEFINE(inst)						\
    	static struct lsm6dso_data lsm6dso_data_##inst;			\
    	static const struct lsm6dso_config lsm6dso_config_##inst =	\
    		COND_CODE_1(DT_INST_ON_BUS(inst, spi),			\
    			(LSM6DSO_CONFIG_SPI(inst)),			\
    			(LSM6DSO_CONFIG_I2C(inst)));			\
    	PM_DEVICE_DT_INST_DEFINE(inst, lsm6dso_pm_action); \     // <- add this
    	LSM6DSO_DEVICE_INIT(inst)
    
    DT_INST_FOREACH_STATUS_OKAY(LSM6DSO_DEFINE)

    when you call pm_device_action_run(dev,PM_DEVICE_ACTION_RESUME); the init function in the device driver is called.

    Thanks   Slight smile

Related