Multiple VL53L0X time of flight sensors

Hello all,

I am trying to write some code to read the sensor values from two VL53L0X tof sensors, but I'm having some trouble.

My current code:

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/gpio.h>

static const struct device *const leftSensor = DEVICE_DT_GET(DT_NODELABEL(right_st_vl53l0x));
static const struct device *const rightSensor = DEVICE_DT_GET(DT_NODELABEL(left_st_vl53l0x));

int main(void)
{
        struct sensor_value leftSensorValue;
        struct sensor_value rightSensorValue;
        int ret;

        k_sleep(K_MSEC(1000));

        if (!device_is_ready(leftSensor)) {
	        printk("Left Sensor: device not ready.\n");
	        return 0;
	}
        if (!device_is_ready(rightSensor)) {
	        printk("Right Sensor: device not ready.\n");
	        return 0;
	}
	while (1) {
		ret = sensor_sample_fetch(leftSensor);
		if (ret) {
			printk("sensor_sample_fetch failed ret %d\n", ret);
			return 0;
		}

		ret = sensor_channel_get(leftSensor, SENSOR_CHAN_PROX, &leftSensorValue);
		printk("prox is %d\n", leftSensorValue.val1);

		ret = sensor_channel_get(leftSensor,
					 SENSOR_CHAN_DISTANCE,
					 &leftSensorValue);
		printf("distance is %.3fm\n", sensor_value_to_double(&leftSensorValue));
                
		k_sleep(K_MSEC(1000));
	}
	return 0;
}

My devicetree:

&i2c1 {
    
    right_st_vl53l0x: right_st_vl53l0x@29{
        compatible = "st,vl53l0x";
        status = "okay";
        reg = < 0x29 >;
        xshut-gpios = < &gpio0 15 (GPIO_ACTIVE_LOW)>;
    };
    left_st_vl53l0x: left_st_vl53l0@52{
        compatible = "st,vl53l0x";
        status = "okay";
        reg = < 0x52 >;
        xshut-gpios = < &gpio0 16 (GPIO_ACTIVE_LOW)>;
    };
};
&pinctrl {
	i2c1_default: i2c1_default{
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
				<NRF_PSEL(TWIM_SCL, 0, 4)>;
		};
	};

	i2c1_sleep: i2c1_sleep{
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
				<NRF_PSEL(TWIM_SCL, 0, 4)>;
			low-power-enable;
		};
	};

};

And Kconfig:

CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_GPIO=y
CONFIG_SENSOR=y
CONFIG_VL53L0X_PROXIMITY_THRESHOLD=100
CONFIG_TFM_SECURE_UART=n
CONFIG_TFM_LOG_LEVEL_SILENCE=y
CONFIG_VL53L0X_RECONFIGURE_ADDRESS=y
#debug
#CONFIG_DEBUG=y
#CONFIG_LOG=y
#CONFIG_SENSOR_LOG_LEVEL_DBG=y
CONFIG_CBPRINTF_FP_SUPPORT=y

Whenever I run this code I get a ret error (-19) or sometimes (-5).

Any help is much appreciated!

Parents
  • Hello,

    Which Nordic chip or development kit (DK) are you using? Could you also provide details of the SDK version you are using?

    Whenever I run this code I get a ret error (-19) or sometimes (-5).

    I recommend attaching the complete log to troubleshoot the issue. Please ensure that the I2C addresses (0x29 and 0x52) are correctly set and do not conflict. Additionally, I noticed that static const struct device *const leftSensor = DEVICE_DT_GET(DT_NODELABEL(right_st_vl53l0x)); and DEVICE_DT_GET(DT_NODELABEL(left_st_vl53l0x)); refer to different labels than those used in your device tree overlay. While this might work, it is somewhat confusing.

    Kind Regards,

    Abhijith

  • Quite chuffed, I fixed the issue.

    It seems as though in the process or initialisation the tof sensor with the non-default address has to be initialised first, why? No clue. Below is the working code for anyone who runs into the same problem:

    My application code:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/gpio.h>
    
    #define LEFT_SENSOR_NODE DT_NODELABEL(left_sensor)
    #define RIGHT_SENSOR_NODE DT_NODELABEL(right_sensor)
    
    static const struct device *const leftSensor = DEVICE_DT_GET(LEFT_SENSOR_NODE);
    
    static const struct device *const rightSensor = DEVICE_DT_GET(RIGHT_SENSOR_NODE);
    
    int main(void)
    {
        struct sensor_value leftSensorValue;
        struct sensor_value rightSensorValue;
        int ret;
    
        k_sleep(K_MSEC(1000));
    
        if (!device_is_ready(rightSensor)) {
    	    printk("Left Sensor: device not ready.\n");
    	    return 0;
    	}
    
    	k_sleep(K_MSEC(1000));
    
        ret = sensor_sample_fetch(rightSensor);
    	if (ret) {
    		printk("leftSensor_sample_fetch failed ret %d\n", ret);
    		return 0;
    	}
    
    	k_sleep(K_MSEC(1000));
    
        if (!device_is_ready(leftSensor)) {
    	    printk("Right Sensor: device not ready.\n");
    	    return 0;
    	}
    	ret = sensor_sample_fetch(leftSensor);
    	if (ret) {
    		printk("leftSensor_sample_fetch failed ret %d\n", ret);
    		return 0;
    	}
    	
    	while (1) {
    		ret = sensor_sample_fetch(leftSensor);
    		if (ret) {
    			printk("sensor_sample_fetch failed ret %d\n", ret);
    			return 0;
    		}
    
    		//ret = sensor_channel_get(leftSensor, SENSOR_CHAN_PROX, &leftSensorValue);
    		//printk("prox is %d\n", leftSensorValue.val1);
    
    		ret = sensor_channel_get(leftSensor,
    					 SENSOR_CHAN_DISTANCE,
    					 &leftSensorValue);
    		printf("Left Sensor distance is %.3fm\n", sensor_value_to_double(&leftSensorValue));
                    
    		k_sleep(K_MSEC(100));
    		ret = sensor_sample_fetch(rightSensor);
    		if (ret) {
    			printk("sensor_sample_fetch failed ret %d\n", ret);
    			return 0;
    		}
    
    		//ret = sensor_channel_get(leftSensor, SENSOR_CHAN_PROX, &leftSensorValue);
    		//printk("prox is %d\n", leftSensorValue.val1);
    
    		ret = sensor_channel_get(rightSensor,
    					 SENSOR_CHAN_DISTANCE,
    					 &rightSensorValue);
    		printf("Right Sensor distance is %.3fm\n", sensor_value_to_double(&rightSensorValue));
                    
    		k_sleep(K_MSEC(1000));
    	}
    	
    	return 0;
    }
    

    My devicetree overlay:

    &i2c1 {
        
        left_sensor: left_st_vl53l0x@29{
            compatible = "st,vl53l0x";
            status = "okay";
            reg = < 0x29 >;
            xshut-gpios = < &gpio0 30 (GPIO_ACTIVE_LOW)>;
        };
        right_sensor: right_st_vl53l0@2a{
            compatible = "st,vl53l0x";
            status = "okay";
            reg = < 0x2a >;
            xshut-gpios = < &gpio0 8 (GPIO_ACTIVE_LOW)>;
        };
    };
    &pinctrl {
    	i2c1_default: i2c1_default{
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
    				<NRF_PSEL(TWIM_SCL, 0, 4)>;
    		};
    	};
    
    	i2c1_sleep: i2c1_sleep{
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
    				<NRF_PSEL(TWIM_SCL, 0, 4)>;
    			low-power-enable;
    		};
    	};
    
    };

    Kconfig:

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_GPIO=y
    CONFIG_SENSOR=y
    CONFIG_VL53L0X_PROXIMITY_THRESHOLD=100
    CONFIG_TFM_SECURE_UART=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y
    CONFIG_VL53L0X_RECONFIGURE_ADDRESS=y
    #debug
    CONFIG_DEBUG=y
    CONFIG_LOG=y
    CONFIG_SENSOR_LOG_LEVEL_DBG=y
    CONFIG_CBPRINTF_FP_SUPPORT=y

    Best,

    Declan S

Reply
  • Quite chuffed, I fixed the issue.

    It seems as though in the process or initialisation the tof sensor with the non-default address has to be initialised first, why? No clue. Below is the working code for anyone who runs into the same problem:

    My application code:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/sensor.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/gpio.h>
    
    #define LEFT_SENSOR_NODE DT_NODELABEL(left_sensor)
    #define RIGHT_SENSOR_NODE DT_NODELABEL(right_sensor)
    
    static const struct device *const leftSensor = DEVICE_DT_GET(LEFT_SENSOR_NODE);
    
    static const struct device *const rightSensor = DEVICE_DT_GET(RIGHT_SENSOR_NODE);
    
    int main(void)
    {
        struct sensor_value leftSensorValue;
        struct sensor_value rightSensorValue;
        int ret;
    
        k_sleep(K_MSEC(1000));
    
        if (!device_is_ready(rightSensor)) {
    	    printk("Left Sensor: device not ready.\n");
    	    return 0;
    	}
    
    	k_sleep(K_MSEC(1000));
    
        ret = sensor_sample_fetch(rightSensor);
    	if (ret) {
    		printk("leftSensor_sample_fetch failed ret %d\n", ret);
    		return 0;
    	}
    
    	k_sleep(K_MSEC(1000));
    
        if (!device_is_ready(leftSensor)) {
    	    printk("Right Sensor: device not ready.\n");
    	    return 0;
    	}
    	ret = sensor_sample_fetch(leftSensor);
    	if (ret) {
    		printk("leftSensor_sample_fetch failed ret %d\n", ret);
    		return 0;
    	}
    	
    	while (1) {
    		ret = sensor_sample_fetch(leftSensor);
    		if (ret) {
    			printk("sensor_sample_fetch failed ret %d\n", ret);
    			return 0;
    		}
    
    		//ret = sensor_channel_get(leftSensor, SENSOR_CHAN_PROX, &leftSensorValue);
    		//printk("prox is %d\n", leftSensorValue.val1);
    
    		ret = sensor_channel_get(leftSensor,
    					 SENSOR_CHAN_DISTANCE,
    					 &leftSensorValue);
    		printf("Left Sensor distance is %.3fm\n", sensor_value_to_double(&leftSensorValue));
                    
    		k_sleep(K_MSEC(100));
    		ret = sensor_sample_fetch(rightSensor);
    		if (ret) {
    			printk("sensor_sample_fetch failed ret %d\n", ret);
    			return 0;
    		}
    
    		//ret = sensor_channel_get(leftSensor, SENSOR_CHAN_PROX, &leftSensorValue);
    		//printk("prox is %d\n", leftSensorValue.val1);
    
    		ret = sensor_channel_get(rightSensor,
    					 SENSOR_CHAN_DISTANCE,
    					 &rightSensorValue);
    		printf("Right Sensor distance is %.3fm\n", sensor_value_to_double(&rightSensorValue));
                    
    		k_sleep(K_MSEC(1000));
    	}
    	
    	return 0;
    }
    

    My devicetree overlay:

    &i2c1 {
        
        left_sensor: left_st_vl53l0x@29{
            compatible = "st,vl53l0x";
            status = "okay";
            reg = < 0x29 >;
            xshut-gpios = < &gpio0 30 (GPIO_ACTIVE_LOW)>;
        };
        right_sensor: right_st_vl53l0@2a{
            compatible = "st,vl53l0x";
            status = "okay";
            reg = < 0x2a >;
            xshut-gpios = < &gpio0 8 (GPIO_ACTIVE_LOW)>;
        };
    };
    &pinctrl {
    	i2c1_default: i2c1_default{
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
    				<NRF_PSEL(TWIM_SCL, 0, 4)>;
    		};
    	};
    
    	i2c1_sleep: i2c1_sleep{
    		group1 {
    			psels = <NRF_PSEL(TWIM_SDA, 0, 5)>,
    				<NRF_PSEL(TWIM_SCL, 0, 4)>;
    			low-power-enable;
    		};
    	};
    
    };

    Kconfig:

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_GPIO=y
    CONFIG_SENSOR=y
    CONFIG_VL53L0X_PROXIMITY_THRESHOLD=100
    CONFIG_TFM_SECURE_UART=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y
    CONFIG_VL53L0X_RECONFIGURE_ADDRESS=y
    #debug
    CONFIG_DEBUG=y
    CONFIG_LOG=y
    CONFIG_SENSOR_LOG_LEVEL_DBG=y
    CONFIG_CBPRINTF_FP_SUPPORT=y

    Best,

    Declan S

Children
No Data
Related