Get data from Lidar Lite V3 over I2C (Zephyr os)

Hi,

I am trying to get the data from the Lidar Lite V3 sensor via the I2C bus. However, I only receive a 0 back.
So my question is the implementation generally correct?

Lidar V3 datasheet: https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf

Overlay file:

&arduino_i2c { /* i2c */
    compatible = "nordic,nrf-twim";
    status = "okay";
    clock-frequency = <I2C_BITRATE_FAST>;
};

prj.conf file:

CONFIG_LOG=y
CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y

main.c file :

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(main);

#define I2C_NODE		DT_ALIAS(arduino_i2c)
#define LIDAR_I2C_ADDR	0x62
#define I2C_DEV_NAME	DT_NODELABEL(arduino_i2c)
#define DELAY_TIME K_MSEC(500)



void main(void)
{
	uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_CONTROLLER;
	const struct device *const i2c_dev = DEVICE_DT_GET(I2C_DEV_NAME);
	uint8_t data[2] = {0};
	int i2c_device_ready, ret = 0;

	if (i2c_dev == NULL || !device_is_ready(i2c_dev)) {
		LOG_INF("I2C: Device is not ready.\n");
		return;
	}else
	{
		LOG_INF("I2C: Device is ready.\n");
	}

	if (i2c_configure(i2c_dev, i2c_cfg)) {
		LOG_INF("I2C config failed\n");
		return;
	}
	while (1) 
	{
		ret = i2c_reg_write_byte(i2c_dev, LIDAR_I2C_ADDR, 0x00, 0x04);
		if (ret) {
				printk("Error writing to reg 0x00! error code (%d)\n", ret);
				return;
			}
		
		while (!i2c_device_ready)
		{	
			uint8_t ready = 55;
				ret = i2c_reg_read_byte(i2c_dev, LIDAR_I2C_ADDR, 0x01, &ready);
			if (ret) {
				printk("Error reading reg 0x01! error code (%d)\n", ret);
				return;
			}
			if (ready == 0){
				i2c_device_ready = 1;
			}
			printk("data ready: %d \n", ready);
			k_sleep(DELAY_TIME);

		}
		i2c_device_ready = 0;	

		ret =  i2c_burst_read(i2c_dev, LIDAR_I2C_ADDR, 0x8f, &data, sizeof(data));
		if (ret) {
			printk("Error writing to FRAM! error code (%d)\n", ret);
			return;
		}
		printk("data: %d \n", (data[0] << 8 + data[1]));
	}

}

Parents
  • Thank for u help i got it now Slight smile

    For anyone who is interested in the solution. Is not very nice implements, but is works:) 

    Overlay file:

    &i2c0 {
        status = "okay";
        clock-frequency = <I2C_BITRATE_FAST>;
    };

    main.c file:

    #include <stdio.h>
    #include <string.h>
    #include <zephyr/zephyr.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/i2c.h>
    
    #define I2C_DEV_NAME DT_NODELABEL(i2c0)
    #define LIDAR_LITE_V3_ADDRESS 0x62
    #define REG_DISTANCE 0x8f
    #define REG_READ 0x01
    
    #define LIDAR_LITE_V3_ADDRESS 0x62
    
    // Variable to store the distance measurement
    uint16_t distance;
    uint8_t register_value;
    
    // Function to get the distance
    void get_distance(struct device *i2c)
    {
        uint8_t reg_distance = REG_DISTANCE;
        uint8_t data[2] = {0};
    
        // // Send the distance register address
        i2c_write(i2c, &reg_distance, 1, LIDAR_LITE_V3_ADDRESS);
        // Read the two bytes from the Lidar Lite V3 sensor
        i2c_read(i2c, &data, 2, LIDAR_LITE_V3_ADDRESS);
    
        // Combine the two bytes into a 16-bit distance value
        distance = (data[0] << 8) | data[1];
    }
    
    void read_register(struct device *i2c)
    {
        uint8_t reg = REG_READ;
    
        // set the register 0x01 to read.
        i2c_write(i2c, &reg, 1, LIDAR_LITE_V3_ADDRESS);
        // read the status od the register 0x01
        i2c_read(i2c, &register_value, 2, LIDAR_LITE_V3_ADDRESS);
    }
    
    void main(void)
    {
        struct device *i2c;
        int ret;
    
        // Initialize the I2C bus
        i2c = DEVICE_DT_GET(I2C_DEV_NAME);
        if (!i2c)
        {
            printf("I2C: Device not found.\n");
            return;
        }
        // initiate sensor
        // for Lidar Lite V3 we have to send 0x04 to the command register before reading distance data
        uint8_t data0[2] = {0x00, 0x04};
        i2c_write(i2c, &data0, 2, LIDAR_LITE_V3_ADDRESS);
        if (ret != 0)
        {
            printf("I2C: Error while writing to command register.\n");
            return;
        }
    
        // configurie the Lidar Sensor
        uint8_t data[2] = {0x02, 0x80};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data, 2, LIDAR_LITE_V3_ADDRESS);
        // configurie the Lidar Sensor
        uint8_t data1[2] = {0x04, 0x08};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data1, 2, LIDAR_LITE_V3_ADDRESS);
        // configurie the Lidar Sensor
        uint8_t data2[2] = {0x1c, 0x00};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data2, 2, LIDAR_LITE_V3_ADDRESS);
    
        while (1)
        {
            // Read the register 0x01 and check the value of the LSB
            read_register(i2c);
            if (register_value & 0x01)
            {
                printf("LSB is high\n");
            }
            else
            {
                printf("LSB is low\n");
                // Get the distance measurement from the Lidar Lite V3 sensor
                get_distance(i2c);
                // Print the distance measurement
                printf("Distance: %d cm\n", distance);
            }
    
            // for Lidar Lite V3 we have to send 0x04 to the command register 0x00 before reading distance data
            i2c_write(i2c, &data0, 2, LIDAR_LITE_V3_ADDRESS);
    
            k_sleep(K_MSEC(100));
        }
    }

Reply
  • Thank for u help i got it now Slight smile

    For anyone who is interested in the solution. Is not very nice implements, but is works:) 

    Overlay file:

    &i2c0 {
        status = "okay";
        clock-frequency = <I2C_BITRATE_FAST>;
    };

    main.c file:

    #include <stdio.h>
    #include <string.h>
    #include <zephyr/zephyr.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/i2c.h>
    
    #define I2C_DEV_NAME DT_NODELABEL(i2c0)
    #define LIDAR_LITE_V3_ADDRESS 0x62
    #define REG_DISTANCE 0x8f
    #define REG_READ 0x01
    
    #define LIDAR_LITE_V3_ADDRESS 0x62
    
    // Variable to store the distance measurement
    uint16_t distance;
    uint8_t register_value;
    
    // Function to get the distance
    void get_distance(struct device *i2c)
    {
        uint8_t reg_distance = REG_DISTANCE;
        uint8_t data[2] = {0};
    
        // // Send the distance register address
        i2c_write(i2c, &reg_distance, 1, LIDAR_LITE_V3_ADDRESS);
        // Read the two bytes from the Lidar Lite V3 sensor
        i2c_read(i2c, &data, 2, LIDAR_LITE_V3_ADDRESS);
    
        // Combine the two bytes into a 16-bit distance value
        distance = (data[0] << 8) | data[1];
    }
    
    void read_register(struct device *i2c)
    {
        uint8_t reg = REG_READ;
    
        // set the register 0x01 to read.
        i2c_write(i2c, &reg, 1, LIDAR_LITE_V3_ADDRESS);
        // read the status od the register 0x01
        i2c_read(i2c, &register_value, 2, LIDAR_LITE_V3_ADDRESS);
    }
    
    void main(void)
    {
        struct device *i2c;
        int ret;
    
        // Initialize the I2C bus
        i2c = DEVICE_DT_GET(I2C_DEV_NAME);
        if (!i2c)
        {
            printf("I2C: Device not found.\n");
            return;
        }
        // initiate sensor
        // for Lidar Lite V3 we have to send 0x04 to the command register before reading distance data
        uint8_t data0[2] = {0x00, 0x04};
        i2c_write(i2c, &data0, 2, LIDAR_LITE_V3_ADDRESS);
        if (ret != 0)
        {
            printf("I2C: Error while writing to command register.\n");
            return;
        }
    
        // configurie the Lidar Sensor
        uint8_t data[2] = {0x02, 0x80};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data, 2, LIDAR_LITE_V3_ADDRESS);
        // configurie the Lidar Sensor
        uint8_t data1[2] = {0x04, 0x08};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data1, 2, LIDAR_LITE_V3_ADDRESS);
        // configurie the Lidar Sensor
        uint8_t data2[2] = {0x1c, 0x00};
        // Write the register address and the desired value to the device
        i2c_write(i2c, &data2, 2, LIDAR_LITE_V3_ADDRESS);
    
        while (1)
        {
            // Read the register 0x01 and check the value of the LSB
            read_register(i2c);
            if (register_value & 0x01)
            {
                printf("LSB is high\n");
            }
            else
            {
                printf("LSB is low\n");
                // Get the distance measurement from the Lidar Lite V3 sensor
                get_distance(i2c);
                // Print the distance measurement
                printf("Distance: %d cm\n", distance);
            }
    
            // for Lidar Lite V3 we have to send 0x04 to the command register 0x00 before reading distance data
            i2c_write(i2c, &data0, 2, LIDAR_LITE_V3_ADDRESS);
    
            k_sleep(K_MSEC(100));
        }
    }

Children
No Data
Related