1

I have 2 Lidars which are Lidar Lite v3 and Lidar Lite v4, both of these sensor having the same i2c address. I'm trying to change my Lidar Lite v3's i2c address on arduino mega2560 using a function from LidarLite library from 0x62 to 0x63. However it doesn't seem to work, after I uploaded a code the serial monitor display

> nack 

and when I'm using i2c scanner it still show a default address (0x62).

here is my arduino code

#include <Wire.h>
#include <LIDARLite.h>

LIDARLite myLidarLite;

void setup(){
  Serial.begin(115200); // Initialize serial connection to display distance readings
  char newAddress = 0x63;
  myLidarLite.setI2Caddr(newAddress , true);
  Wire.begin();
}

void loop(){
  
  **** i2c scanner code ****

}

setI2Caddr function from library

void LIDARLite::setI2Caddr(char newAddress, char disableDefault, char lidarliteAddress)
{
  byte dataBytes[2];

  // Read UNIT_ID serial number bytes and write them into I2C_ID byte locations
  read ((0x16 | 0x80), 2, dataBytes, false, lidarliteAddress);
  write(0x18, dataBytes[0], lidarliteAddress);
  write(0x19, dataBytes[1], lidarliteAddress);

  // Write the new I2C device address to registers
  dataBytes[0] = newAddress;
  write(0x1a, dataBytes[0], lidarliteAddress);

  // Enable the new I2C device address using the default I2C device address
  dataBytes[0] = 0;
  write(0x1e, dataBytes[0], lidarliteAddress);

  // If desired, disable default I2C device address (using the new I2C device address)
  if (disableDefault)
  {
    dataBytes[0] = (1 << 3); // set bit to disable default address
    write(0x1e, dataBytes[0], newAddress);
  }
}

I've checked a read function and found this condition

    // A nack means the device is not responding, report the error over serial
    int nackCatcher = Wire.endTransmission();
    if(nackCatcher != 0)
    {
      Serial.println("> nack");
    }

the datasheet of Lidar Lite v3 is here and changing i2c address topic can be found in 5th page

I've tried to compare the function to a datasheet but still have no idea why it didn't work. So, how can I change an I2C address of Lidar Lite v3 to make them able to work together?


Update

Finally I have found the mistake. The simple way to fix is just call function Wire.begin() or myLidarLite.begin() (which containing Wire.begin inside the function) before using setI2Caddr().

So, the code will be like this

#include <Wire.h>
#include <LIDARLite.h>

LIDARLite myLidarLite;

void setup(){
  Serial.begin(115200); // Initialize serial connection to display distance readings
  Wire.begin(); // or myLidarLite.begin();
  char newAddress = 0x63;
  myLidarLite.setI2Caddr(newAddress , true);
}

void loop(){
  **** i2c scanner code ****
}

After upload to the board, the address is finally changed.

Ps. Btw, when I set 0x64 to setI2Caddr it changed to 0x63 instead of 0x64 and still keep the old address eventhough I set disabledefault as true.

0
0

You probably need to use LIDARLite_v3HP.h. The setI2Caddr() function is not same between LIDARLite_v3HP.h and LIDARLite.h.

The datasheet you provided, has the instruction on how to update the I2C address. LIDARLite_v3HP.h's setI2Caddr() followed those instructions.

To check, if you go to this line of the source code of LIDARLite.h, you will see the function doesn't write 0x08 to 0x1e, instead writes 0x00. Either that's how it was in the earlier versions or maybe it's a bug.

Also, it is mentioned in the datasheet that, if you power cycle the Lidar the address will be restored to default.


Update

After I gone through the library more carefully I noticed that writing `0x08` into `0x01` is actually handled but differently in the `LIDERLite.h'.

Here is the setI2Caddr() code from the library (check the last two lines):

void LIDARLite::setI2Caddr(char newAddress, char disableDefault, char lidarliteAddress)
{
  byte dataBytes[2];

  // Read UNIT_ID serial number bytes and write them into I2C_ID byte locations
  read ((0x16 | 0x80), 2, dataBytes, false, lidarliteAddress);
  write(0x18, dataBytes[0], lidarliteAddress);
  write(0x19, dataBytes[1], lidarliteAddress);

  // Write the new I2C device address to registers
  dataBytes[0] = newAddress;
  write(0x1a, dataBytes[0], lidarliteAddress);

  // Enable the new I2C device address using the default I2C device address
  dataBytes[0] = 0;
  write(0x1e, dataBytes[0], lidarliteAddress);

  // If desired, disable default I2C device address (using the new I2C device address)
  if (disableDefault)
  {
    dataBytes[0] = (1 << 3); // set bit to disable default address
    write(0x1e, dataBytes[0], newAddress);
  }
}

All you have to do is set disableDefault to any positive int when you call setI2Caddr().

3
  • Hi Fahad, thank you for response. However I've tried LIDARLite_v3HP , it still doesn't work, the address doesn't change and when I try example code it always display 0 m. As well as, I still got > nack again when I enter read function because a transmission won't stop ` (Wire.endTransmission == false) ` . As you mentioned that _ the function doesn't write 0x08 to 0x1e, instead writes 0x00._ . Could you please guide me how to change 0x00 to 0x08 because I'm not good at programming in binary level. Apr 29 at 14:17
  • I have updated the answer.
    – Fahad
    Apr 30 at 3:59
  • Finally I've found the solution (updated in my post). The problem is not because a library but my code. I just switch Wire.begin() with setI2Caddr and that is. As well as, as you mentioned about wirting 0x08 to 0x1e is true, after the address is set, the old one still show on the serial monitor together with the new one. However, I didn't notice a change in the code you have provided, did I miss something? May 6 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.