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(); }