How do I read from a correct data address of LIDAR using Arduino in I2C?

I need to read the distance data from a lidar in I2C using an Arduino Nano. Currently, this is the code I've written.

unsigned int readDistance()
{
  unsigned int dist = 0 ; // LiDAR actually measured distance value. static so we can return previous dist
  
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(0x10) ; // transmit to device 0x10
  Wire.write(2) ; // sets distance data address (addr)
  Wire.write(3) ; // sets distance data address (addr)
  Wire.endTransmission() ; // stop transmitting
  
  // step 2: wait for readings to happen
  delay(100) ; // datasheet suggests at least 100ms
  
  // step 3: request reading from sensor
  Wire.requestFrom(0x10, 2) ; // request 2 bytes (DIST_L, DIST_H) from slave device #0x10
  dist = Wire.read() ; dist += Wire.read() << 8; // calculate distance value, bit shift high distance
  return dist ; // return updated dist
}

But I have a feeling I'm requesting from the wrong data address', since I'm not getting the results I expect (ie. varying distance data). Furthermore, I used an I2C scanner which 100% confirms the lidar is on the (default address) of 0x10.

Datasheet of (TF02 Pro): https://www.unmannedtechshop.co.uk/wp-content/uploads/2020/01/TF02-Pro-Product-Manual-Alpha.pdf

Question: am i reading from the right data address
Any help would be appreciated.

The sensor uses 3.3V I/O. If you are using a 5V Arduino, do you have the required logic level shifters on the I2C lines?

The I2C protocol that the device uses appears to be nonstandard, and I did not see enough information in the data sheet to proceed. However, this table entry on page 13 gives some hints:

Obtain Data Frame
5A 05 00 01 60
Data Frame(9bytes-cm) >
Only works in I2C mode

Hi @daleksla
veja se isto ajuda:
https://create.arduino.cc/projecthub/Abhinav_Abhi/arduino-lidar-917404
RV mineirin

No, it is only available in 5V.

Interface I²C 
Max transmission rate 400kbps
Master/slave mode Slave mode
Default address  0x10
Address range    0x01~0x7F

Seems pretty standard to me, where do you see the problem?

@daleksla You should send the same data as described in the data sheet,
there are no registers, just a command response protocol.

Where did you get that idea? I would go by what the manufacturer states on page 6 of the data sheet:

Capture

Calm down, I/O wise.

Q1: Is TF02-Pro available with 3.3V or other power supply voltage? A1: Sorry, it is not available for the time being. The Standard power supply of TF02-Pro is 5V~12V. If you have any further requirement, please contact our sales person to consult a customization design matter.

So If you power the sensor with 5V, a Nano should work.

I have no problem with the manufacturer's specification of 5V MINIMUM power and 3.3V I/O.

Where do you get the 3.3V I/O voltage from?

Oh, I found it.

I think that only means it will accept 3.3V signals, like most 5V devices.

Page 6 of the data sheet, photo posted in reply #6.

In any case, this is clearly the wrong read command:

  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(0x10) ; // transmit to device 0x10
  Wire.write(2) ; // sets distance data address (addr)
  Wire.write(3) ; // sets distance data address (addr)
  Wire.endTransmission() ; // stop transmitting

According to the data sheet the correct read command is five bytes: 5A 05 00 01 60

2 Likes

Hi, I'm new to doing this kind of thing, so how would I go about doing that?

Yeah, they claim that the data format is identical to that of the serial protocol.

Did the sensor work with the manufacturer software?

Somehow it must have been placed in I2C mode, the default is UART.

It's for a project and I think the guy who gave it to me converted it to i2c. Admittedly, i don't know if it worked with the manufacturer software or not. Either way I think i got it working now.

You are a life saver. It works now.

That is what Ii wrote here:

You're right, you did. Thank you very much too, running kind of slow today

Glad you got it working.

Please post the working code! It would benefit others who might use the sensor.

1 Like
unsigned int readDistance()
{
  unsigned int dist = 0 ; // LiDAR actually measured distance value
  
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(0x10) ; // transmit to device 0x10
  Wire.write(0x5A) ; // some read command.
  Wire.write(0x05) ;
  Wire.write(0x00) ;
  Wire.write(0x01) ;
  Wire.write(0x60) ;
  Wire.endTransmission() ; // stop transmitting
  
  // step 2: wait for readings to happen
  delay(100) ; // datasheet suggests at least 100ms
  
  // step 3: request reading from sensor
  Wire.requestFrom(0x10, 4) ; // request first 4 bytes from slave device #0x10
  Wire.read() ; Wire.read() ; //ignore header bytes
  // remaining two bytes for distance (DIST_L, DIST_H) 
  dist = Wire.read() ; dist += Wire.read() << 8 ; // calculate distance value, bit shift high distance
  return dist ; // return updated dist
}

Working code!

The comment does not match the code. :wink:

P.S. I dislike space-semicolon as much as space-comma.