0

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.

2
  • use the I2CScanner sketch Commented Jun 21, 2021 at 14:55
  • @Juraj how would that help (no ill will intended)? I know the address of the device, I'm trying to read a given series of bytes but I'm asking how to go about it instead. &i already used it to confirm I'm trying to read from the correct device anyhow Commented Jun 21, 2021 at 17:58

1 Answer 1

1

According to the data sheet the correct read command is five bytes: 5A 05 00 01 60. It doesn't work like a typically i2c device.

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
}
Sign up to request clarification or add additional context in comments.

2 Comments

While this may be OK in your application, I'd be very careful about adding delay/wait in a real-time/embedded system - especially 100ms which may well trigger a watchdog!
@Andrew This was just what I used to solve my issue of reading - In the actual application of the system, i essentially pushed to the ROS network the previous read value after issuing the read command, then read the current value, etc., and minimised the remaining needed delay through testing (100 was recommended by datasheet). I totally agree with your premise though, good shout!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.