Tres sensores laser VL53L0X no se comunican de manera adecuada

Programe un sensor laser VL53L0X con Arduino uno para leer lecturas en mm y me funciono, después quiero hacer tres lecturas con tres y solo me muestra lectura el 2, sin embargo probé cada uno por aparte y funcionan entonces tengo un problema en enlazar los tres, gracias por su atención. Adjunto aquí el codigo que he hecho para tener una referencia.

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor1;
VL53L0X sensor2;
VL53L0X sensor3;

// Configuración de los pines XSHUT
const int sensor1XSHUTPin = 2;  // Pin XSHUT del primer sensor
const int sensor2XSHUTPin = 3;  // Pin XSHUT del segundo sensor
const int sensor3XSHUTPin = 4;  // Pin XSHUT del tercer sensor

void setup() {

  // Inicialización de los pines XSHUT
  pinMode(sensor1XSHUTPin, OUTPUT);
  pinMode(sensor2XSHUTPin, OUTPUT);
  pinMode(sensor3XSHUTPin, OUTPUT);


 // Establecer las direcciones I2C de los sensores
  digitalWrite(sensor1XSHUTPin, LOW);   // Establecer el primer sensor en dirección única
  digitalWrite(sensor2XSHUTPin, HIGH);  // Establecer el segundo sensor en dirección única
  digitalWrite(sensor3XSHUTPin, HIGH);  // Establecer el tercer sensor en dirección única


  Serial.begin(9600);
  Wire.begin();

  // Inicialización del primer sensor
  Wire.beginTransmission(0x29);
  Wire.write(byte(0x88));
  Wire.write(byte(0x00));
  Wire.endTransmission();
  sensor1.setAddress(0x29);
  sensor1.init();
  sensor1.setTimeout(500);

  // Inicialización del segundo sensor
  Wire.beginTransmission(0x30);
  Wire.write(byte(0x88));
  Wire.write(byte(0x00));
  Wire.endTransmission();
  sensor2.setAddress(0x30);
  sensor2.init();
  sensor2.setTimeout(500);

  // Inicialización del tercer sensor
  Wire.beginTransmission(0x31);
  Wire.write(byte(0x88));
  Wire.write(byte(0x00));
  Wire.endTransmission();
  sensor3.setAddress(0x31);
  sensor3.init();
  sensor3.setTimeout(500);

scanI2CDevices();

}

void loop() {
  Serial.print("Distancia Sensor 1: ");
  Serial.print(sensor1.readRangeSingleMillimeters());
  Serial.println(" mm");

  Serial.print("Distancia Sensor 2: ");
  Serial.print(sensor2.readRangeSingleMillimeters());
  Serial.println(" mm");

  Serial.print("Distancia Sensor 3: ");
  Serial.print(sensor3.readRangeSingleMillimeters());
  Serial.println(" mm");

  delay(500);
}


void scanI2CDevices() {
  byte error, address;
  int deviceCount = 0;

  Serial.println("Escaneando dispositivos I2C...");

  for (address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("Dispositivo encontrado en dirección 0x");
      if (address < 16) {
        Serial.print("0");
      }
      Serial.print(address, HEX);
      Serial.println(" !");
      deviceCount++;
    }
  }

  if (deviceCount == 0) {
    Serial.println("No se encontraron dispositivos I2C.");
  } else {
    Serial.println("Escaneo I2C finalizado.");
  }
}


Probá con esta librería Adafruit_VL53L0X
Y este ejemplo esta para 2 pero fácilmente lo modificas a 3

NOTA
La dirección por defecto de I2C es 0x29, pero recuerde que es posible programar esta dirección en el VL53L0X. Con la biblioteca Adafruit, hay dos maneras de establecer la nueva dirección. Durante la inicialización, en lugar de llamar a lox.begin(), se llama a lox.begin(0x30) para establecer la dirección en 0x30. O se puede, más adelante, llamar a lox.setAddress(0x30) en cualquier momento. Es importante realizar esta operación con una sola placa VL53L0X conectada al bus I2C, o todas quedarán cambiadas.

1 Like

Gracias, me ha servido de mucho, ahora, agregué algo de codigo para en lazar los tres, pero, dice que la sección de datos excede el espacio disponible en la placa.

#include "Adafruit_VL53L0X.h"

// address we will assign if dual sensor is present
#define LOX1_ADDRESS 0x30
#define LOX2_ADDRESS 0x31
#define LOX3_ADDRESS 0x32

// set the pins to shutdown
#define SHT_LOX1 2
#define SHT_LOX2 3
#define SHT_LOX3 4

// objects for the vl53l0x
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox3 = Adafruit_VL53L0X();

// this holds the measurement
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;
VL53L0X_RangingMeasurementData_t measure3;

/*
    Reset all sensors by setting all of their XSHUT pins low for delay(10), then set all XSHUT high to bring out of reset
    Keep sensor #1 awake by keeping XSHUT pin high
    Put all other sensors into shutdown by pulling XSHUT pins low
    Initialize sensor #1 with lox.begin(new_i2c_address) Pick any number but 0x29 and it must be under 0x7F. Going with 0x30 to 0x3F is probably OK.
    Keep sensor #1 awake, and now bring sensor #2 out of reset by setting its XSHUT pin high.
    Initialize sensor #2 with lox.begin(new_i2c_address) Pick any number but 0x29 and whatever you set the first sensor to
 */
void setID() {
  // all reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  digitalWrite(SHT_LOX3, LOW);
  delay(10);
  // all unreset
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, HIGH);
  digitalWrite(SHT_LOX3, HIGH);
  delay(10);

  // activating LOX1 and resetting LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);
  digitalWrite(SHT_LOX3, LOW);
  

  // initing LOX1
  if(!lox1.begin(LOX1_ADDRESS)) {
    Serial.println(F("Failed to boot first VL53L0X"));
    while(1);
  }
  delay(10);

  // activating LOX2
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

  //initing LOX2
  if(!lox2.begin(LOX2_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }

  // activating LOX3
  digitalWrite(SHT_LOX3, HIGH);
  delay(10);

  //initing LOX3
  if(!lox2.begin(LOX3_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }

}

void read_dual_sensors() {
  
  lox1.rangingTest(&measure1, false); // pass in 'true' to get debug data printout!
  lox2.rangingTest(&measure2, false); // pass in 'true' to get debug data printout!
  lox3.rangingTest(&measure3, false);

  // print sensor one reading
  Serial.print(F("1: "));
  if(measure1.RangeStatus != 4) {     // if not out of range
    Serial.print(measure1.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.print(F(" "));

  // print sensor two reading
  Serial.print(F("2: "));
  if(measure2.RangeStatus != 4) {
    Serial.print(measure2.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.print(F(" "));

  // print sensor one reading
  Serial.print(F("3: "));
  if(measure3.RangeStatus != 4) {     // if not out of range
    Serial.print(measure3.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }


}

void setup() {
  Serial.begin(9600);


  // wait until serial port opens for native USB devices
  while (! Serial) { delay(1); }

  pinMode(SHT_LOX1, OUTPUT);
  pinMode(SHT_LOX2, OUTPUT);
  pinMode(SHT_LOX3, OUTPUT);

  Serial.println(F("Shutdown pins inited..."));

  digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, LOW);
  digitalWrite(SHT_LOX2, LOW);

  Serial.println(F("Both in reset mode...(pins are low)"));
  
  
  Serial.println(F("Starting..."));
  setID();
 
}

void loop() {
   
  read_dual_sensors();
  delay(100);
}

Loque ocurre que un UNO no es buena opción hoy en dia.
Las librerías crecen de tamaño y con solo 2K de RAM en el UNO y espacioi reducido en flash las cosas se complican
A ver.. por lo que veo ya has tomado recaudos con los print.
Consejo busca otro micro de mas capacidad, si usas un shield bueno, lo comprendo.

1 Like

Muchas gracias.

He decidido usar una tarjeta de desarrollo ESP-32 DEVKIT V1 para realizar mi proyecto con los dos sensores laser, sin embargo he subido el codigo pero no muestra nada en el monitor serial, solo modifique la ubicación de los pines ya que es otra tarjeta.

Dejo el codigo de referencia, es el mismo solo modifique los pines:

#include "Adafruit_VL53L0X.h"
#include <Wire.h>

#define SDA_PIN 16  // Asigna el pin GPIO deseado para SDA
#define SCL_PIN 17  // Asigna el pin GPIO deseado para SCL

#define SDA_PIN2 18  // Asigna el pin GPIO deseado para SDA
#define SCL_PIN2 19  // Asigna el pin GPIO deseado para SCL

// address we will assign if dual sensor is present
#define LOX1_ADDRESS 0x30
#define LOX2_ADDRESS 0x31

// set the pins to shutdown
#define SHT_LOX1 26
#define SHT_LOX2 27

// objects for the vl53l0x
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();

// this holds the measurement
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;

/*
    Reset all sensors by setting all of their XSHUT pins low for delay(10), then set all XSHUT high to bring out of reset
    Keep sensor #1 awake by keeping XSHUT pin high
    Put all other sensors into shutdown by pulling XSHUT pins low
    Initialize sensor #1 with lox.begin(new_i2c_address) Pick any number but 0x29 and it must be under 0x7F. Going with 0x30 to 0x3F is probably OK.
    Keep sensor #1 awake, and now bring sensor #2 out of reset by setting its XSHUT pin high.
    Initialize sensor #2 with lox.begin(new_i2c_address) Pick any number but 0x29 and whatever you set the first sensor to
 */
void setID() {
  // all reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  delay(10);
  // all unreset
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

  // activating LOX1 and resetting LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);

  // initing LOX1
  if(!lox1.begin(LOX1_ADDRESS)) {
    Serial.println(F("Failed to boot first VL53L0X"));
    while(1);
  }
  delay(10);

  // activating LOX2
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

  //initing LOX2
  if(!lox2.begin(LOX2_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }
}

void read_dual_sensors() {
  
  lox1.rangingTest(&measure1, false); // pass in 'true' to get debug data printout!
  lox2.rangingTest(&measure2, false); // pass in 'true' to get debug data printout!

  // print sensor one reading
  Serial.print(F("1: "));
  if(measure1.RangeStatus != 4) {     // if not out of range
    Serial.print(measure1.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.print(F(" "));

  // print sensor two reading
  Serial.print(F("2: "));
  if(measure2.RangeStatus != 4) {
    Serial.print(measure2.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.println();
}

void setup() {
  Serial.begin(115200);

Wire.begin(SDA_PIN, SCL_PIN); // Convertimos un par de pines GPIO a SDA y SCL
  Wire.begin(SDA_PIN2, SCL_PIN2); // Convertimos otro par de pines GPIO a SDA y SCL

  // wait until serial port opens for native USB devices
  while (! Serial) { delay(1); }

  pinMode(SHT_LOX1, OUTPUT);
  pinMode(SHT_LOX2, OUTPUT);

  Serial.println(F("Shutdown pins inited..."));

  digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, LOW);

  Serial.println(F("Both in reset mode...(pins are low)"));
  
  
  Serial.println(F("Starting..."));
  setID();
 
}

void loop() {
   
  read_dual_sensors();
  delay(100);
}

Creo que inicializas incorrectamente los GPIO para I2C, según la documentación de Espressif

Para cambiar los pines, debemos llamar a la función
Wire.setPins(int sda, int scl);
antes de llamar a
Wire.begin();.

int sda_pin = 16; // GPIO16 as I2C SDA 
int scl_pin = 17; // GPIO17 as I2C SCL 

void setup() { 
  Wire.setPins(sda_pin, scl_pin); // Set the I2C pins before begin
  Wire.begin(); // join i2c bus (address optional for master) 
}

Lo he hecho, pero, sigo teniendo el mismo inconveniente, el monitor no muestra nada en lo absoluto, cabe destacar que en la velocidad de subida de la tarjeta la tengo en 115200 baud, el monitor tienen lo mismo de velocidad y en el codigo también como se puede ver, entonces, no hallo la incógnita.

#include "Adafruit_VL53L0X.h"
#include <Wire.h>

int sda_pin = 16; // GPIO16 as I2C SDA 
int scl_pin = 17; // GPIO17 as I2C SCL


// address we will assign if dual sensor is present
#define LOX1_ADDRESS 0x30
#define LOX2_ADDRESS 0x31

// set the pins to shutdown
#define SHT_LOX1 26
#define SHT_LOX2 27

// objects for the vl53l0x
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();

// this holds the measurement
VL53L0X_RangingMeasurementData_t measure1;
VL53L0X_RangingMeasurementData_t measure2;

/*
    Reset all sensors by setting all of their XSHUT pins low for delay(10), then set all XSHUT high to bring out of reset
    Keep sensor #1 awake by keeping XSHUT pin high
    Put all other sensors into shutdown by pulling XSHUT pins low
    Initialize sensor #1 with lox.begin(new_i2c_address) Pick any number but 0x29 and it must be under 0x7F. Going with 0x30 to 0x3F is probably OK.
    Keep sensor #1 awake, and now bring sensor #2 out of reset by setting its XSHUT pin high.
    Initialize sensor #2 with lox.begin(new_i2c_address) Pick any number but 0x29 and whatever you set the first sensor to
 */
void setID() {
  // all reset
  digitalWrite(SHT_LOX1, LOW);    
  digitalWrite(SHT_LOX2, LOW);
  delay(10);
  // all unreset
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

  // activating LOX1 and resetting LOX2
  digitalWrite(SHT_LOX1, HIGH);
  digitalWrite(SHT_LOX2, LOW);

  // initing LOX1
  if(!lox1.begin(LOX1_ADDRESS)) {
    Serial.println(F("Failed to boot first VL53L0X"));
    while(1);
  }
  delay(10);

  // activating LOX2
  digitalWrite(SHT_LOX2, HIGH);
  delay(10);

  //initing LOX2
  if(!lox2.begin(LOX2_ADDRESS)) {
    Serial.println(F("Failed to boot second VL53L0X"));
    while(1);
  }
}

void read_dual_sensors() {
  
  lox1.rangingTest(&measure1, false); // pass in 'true' to get debug data printout!
  lox2.rangingTest(&measure2, false); // pass in 'true' to get debug data printout!

  // print sensor one reading
  Serial.print(F("1: "));
  if(measure1.RangeStatus != 4) {     // if not out of range
    Serial.print(measure1.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.print(F(" "));

  // print sensor two reading
  Serial.print(F("2: "));
  if(measure2.RangeStatus != 4) {
    Serial.print(measure2.RangeMilliMeter);
  } else {
    Serial.print(F("Out of range"));
  }
  
  Serial.println();
}

void setup() {
  Serial.begin(115200);

Wire.setPins(sda_pin, scl_pin); // Set the I2C pins before begin
  Wire.begin(); // join i2c bus (address optional for master) // Convertimos otro par de pines GPIO a SDA y SCL

  // wait until serial port opens for native USB devices
  while (! Serial) { delay(1); }

  pinMode(SHT_LOX1, OUTPUT);
  pinMode(SHT_LOX2, OUTPUT);

  Serial.println(F("Shutdown pins inited..."));

  digitalWrite(SHT_LOX1, LOW);
  digitalWrite(SHT_LOX2, LOW);

  Serial.println(F("Both in reset mode...(pins are low)"));
  
  
  Serial.println(F("Starting..."));
  setID();
 
}

void loop() {
   
  read_dual_sensors();
  delay(100);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.