De modo a desenvolver um lidar rotativo com vários sensores de distância laser VL53L0X ou VL53L1X para os meus robots, para o qual já imprimi umas peças na impressora 3D é necessário alterar os endereços I2C dos vários VL53LXX no bus I2C.
Essa alteração de endereço tem um procedimento especial, para o qual é necessário usar um pino digital do Arduino ligado ao pino XSHUT de cada VL53LXX no bus I2c.
Como o Arduino funciona com um nivel lógico de 5V, e o pino XSHUT não tem conversor de nivel lógico, é necessário colocar um conversor externo em cada pino.
Hardware
Arduino, e dois VL53L0X, um VL53L0X da Pololu e outro VL53L0X sem marca.

Software
Programa de teste que define os novos endereços para dois sensores de distancia VL53L0X e depois faz um varrimento ao bus I2C à procura de dispositivos.
vl53l0x_change_address_test_v1
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
VL53L0X sensor2;
#define PIN1 7
#define PIN2 8
void setup() {
pinMode(PIN1, OUTPUT);
pinMode(PIN2, OUTPUT);
digitalWrite(PIN1, LOW);
digitalWrite(PIN2, LOW);
delay(500);
Wire.begin();
Serial.begin (115200);
pinMode(PIN1, INPUT);
delay(150);
Serial.println("00");
sensor.init(true);
Serial.println("01");
delay(100);
sensor.setAddress((uint8_t)22);
Serial.println("02");
pinMode(PIN2, INPUT);
delay(150);
sensor2.init(true);
Serial.println("03");
delay(100);
sensor2.setAddress((uint8_t)25);
Serial.println("04");
Serial.println("addresses set");
}
void loop() {
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
for (byte i = 1; i < 120; i++) {
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0) {
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
delay (1); // maybe unneeded?
} // end of good response
} // end of for loop
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
delay(3000);
}
Resultado

Foto do ecran ao detectar os dois VL53L0X
Programa de teste que define os novos endereços para dois sensores de distancia VL53L0X e apresenta os dispositivos existentes no bus I2C, passando a exibir as leituras dos dois sensores.
vl53l0x_multiple_test_v1
#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor1;
VL53L0X sensor2;
#define PIN1 7
#define PIN2 8
void setup() {
pinMode(PIN1, OUTPUT);
pinMode(PIN2, OUTPUT);
digitalWrite(PIN1, LOW);
digitalWrite(PIN2, LOW);
delay(500);
Wire.begin();
Serial.begin (115200);
pinMode(PIN1, INPUT);
delay(150);
Serial.println("00");
sensor1.init(true);
Serial.println("01");
delay(100);
sensor1.setAddress((uint8_t)22);
Serial.println("02");
pinMode(PIN2, INPUT);
delay(150);
sensor2.init(true);
Serial.println("03");
delay(100);
sensor2.setAddress((uint8_t)25);
Serial.println("04");
Serial.println("addresses set");
// end configuration
sensor1.setTimeout(500);
sensor2.setTimeout(500);
sensor1.startContinuous();
sensor2.startContinuous();
// scan i2c
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
for (byte i = 1; i < 120; i++) {
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0) {
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
delay (1); // maybe unneeded?
} // end of good response
} // end of for loop
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
}
void loop() {
Serial.print(sensor1.readRangeContinuousMillimeters());
if (sensor1.timeoutOccurred()) { Serial.print(" TIMEOUT S1"); }
Serial.print("\t");
Serial.print(sensor2.readRangeContinuousMillimeters());
if (sensor2.timeoutOccurred()) { Serial.print(" TIMEOUT S2"); }
Serial.println();
}
