I2C Devices adressieren (VL53LXX-V2)

Bin noch nicht so erfahren im Einsatz von I2C. Habe hier einen TOF-Sensor VL53LXX-V2 an einen ESP32-Wroom angeschlossen und die Auslese funktioniert.

Jetzt sollen ingesamt 5 dieser TOF-Module an den I2C-Bus angeschlossen werden. Das Modul hat die Adresse 2C. Die 4 Stck. VL53L0/1XV2 (also leicht andere Bezeichnung), die ich noch bestellt habe, werden ja wahrscheinlich die gleiche (2C) haben, oder zumindest 4x dieselbe Adresse.

Man kann ja die I2C Adresse programmieren. Wenn die alle an dem 3-Wire Bus (GDN,SCLK,SDA) hĂ€ngen, wird das ja wohl nicht möglich sein. Also mĂŒĂŸte ich noch jeweils eine extra Verbindung zu jedem einzelnen Modul (XSHUT) fĂŒhren, um alle bis auf jeweils einen abzuschalten?

Nur mal so ein Gedanke: ich könnte mir ja auch ein Verfahren vorstellen, wo alle ein Signal bekommen "bitte Adresse setzen" und ein random timer sendet "hier ich". Der erste, der kommt, bekommt eine Adresse zugewiesen, dann der nÀchste, der ja zu einer spÀteren Zeit (random) kommt, bekommt eine neue Adresse, usw., bis alle bedient sind.

Das Datenblatt der Sensoren könnte gesicherte Informationen enthalten.

Danke. Fand zumindest schon mal die AN4846. Individuelle XSHUT-Leitungen von GPIO-pins setzen und dann jeden einzeln resetten und ein VL53L0X_SetDeviceAddress (&BoardDevs[i], FinalI2cAddr) absetzen.

Hi @krischu ,

denkbar sind solche Verfahren, sie bedingen aber einen Eingriff in die Firmware der Module oder zusÀtzliche Hardware ...

Wenn die Doku von Adafruit weiterhin zutrifft, wirst Du wohl um die zusÀtzliche Verdrahtung des XSHUT-Pins nicht herumkommen...

https://cdn-learn.adafruit.com/downloads/pdf/adafruit-vl53l0x-micro-lidar-distance-sensor-breakout.pdf

Nach der o.a. PDF gilt:

Das wĂŒrde bedeuten, dass es nach jedem(!) Einschalten selbst einzelner Module erforderlich wĂ€re, diese nach und nach hochzufahren und umzuprogrammieren ... Das klingt nicht gerade beruhigend.

Alternativ empfiehlt es sich dann wohl einen I2C-Multiplexer einzusetzen, zum Beispiel einen solchen ...

https://eckstein-shop.de/AdafruitTCA9548AI2CMultiplexer2CSupportupto8xI2CDevices?msclkid=59229438b35a16e3df46f1ed6408095a

P.S.: Ggf. kann diese Seite fĂŒr Dich interessant sein (ist zwar aus 2019, aber insgesamt hilfreich)
https://wolles-elektronikkiste.de/vl53l0x-und-vl53l1x-tof-abstandssensoren

Viel Erfolg!
ec2021

Ich versuche gerade, ein angeschlossenes VL53LXX-V2 mittels der XSHUT Leitung abzuschalten.
Habe die Leitung an D15 des ESP32 angeschlossen und sende ein digitalWrite(15,1);.

WĂŒrde jetzt erwarten, daß die Messung, die durch lox.rangingTest(&measure, false); unterbunden wird. Passiert aber nicht. Der Chip sendet fleißig.

Schau mal hier

https://www.st.com/resource/en/datasheet/vl53l0x.pdf

ins Datenblatt unter Punkt 2.9.1 Power up and boot sequence:

image

Wird XSHUT wÀhrend des Zuschaltens der Spannungsversorgung zunÀchst auf LOW gehalten, so sollte das Modul im HW Standby verbleiben.

Wenn danach von LOW auf HIGH gewechselt wird, startet der Boot-Vorgang der Firmware, der maximal 1,2 Millisekunden dauern soll. Danach wÀre das Modul im SW Standby ...

Ein Wechsel von HIGH auf LOW (und dort bleiben) sollte das Modul in den HW Standby bringen (siehe AufzÀhlungspunkte 2. und 3. im Post 4.

Danke fĂŒr das Timingdiagramm.

Ich habe außerdem noch ein OLED Display am I2C bus. Dies hat keinen XSHUT Eingang. Muß noch mal drĂŒber nachdenken, wie ich dem Problem begegnen kann.
Kann ich einen zweiten I2C Bus am ESP32 betreiben?

EDIT: ursprĂŒnglich aus Versehen von Deutsch nach Englisch gewechselt und dies korrigiert (wie auch den Inhalt des Posts etwas modifiziert). :slight_smile:

Any reason for changing the language? :wink:

Oh, tut mir leid :slight_smile:

Im englischen Teil des Forum mĂŒssen die BeitrĂ€ge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Kein Problem, hat mich nur ĂŒberrascht ...

Dass das OLED sich auf gleiche Weise wie die VL52XX umprogrammieren lÀsst, wÀre schon ein ziemlicher Zufall ...

Hier sind die I2C-Möglichkeiten des ESP32 sehr ausfĂŒhrlich beschrieben:

https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/

unter anderem auch die Verwendung der zwei I2C-Schnittstellen des Controllers.

Darf ich aus Deinem Post entnehmen, dass das Umprogrammieren mit XSHUT wie oben beschrieben funktioniert?

Das wĂŒrde aber erfordern, daß ich AVDD zuschalten kann, was nicht ohne zusĂ€tzliche externe Hardware möglich sein dĂŒrfte.

Habe mit I2C Scanner jetzt einmal nach Powercyle gescannt und bekomme:

Type [C-a] [C-h] to see available commands
Terminal ready
Scanning...

I2C device found at address 0x29

done


Dann weite Device unter Power gehalten, die V53L0XX App geflasht, diese Sequenz ausgefĂŒhrt:

  digitalWrite(15,0);
  delay(10);
  digitalWrite(15,1);
  
  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin(0x30)) {
                  ^^^^______________ hier steht in der Original-App keine Adresse drin.

Danach wieder die Scanner App (Test_I2C v. Rui Santos) geflasht und
die gibt dann aus:

Scanning...

I2C device found at address 0x30

done

Das OLED Display hatte ih wÀhrend der obigen Prozedur abgeklemmt.

Scheint auch nicht verÀndert worden zu sein. Und wird ja wahrscheinlich von der lox-Umaddressiermethode nicht tangiert. Könnte ich also dranlassen. Momentan fehlen mir noch die 4 andere VL53LXX Devices. Kommen morgen oder Samstag. Dann kann ich 5 Devices am Bus testen.

Hatte ich die Diskussion nicht ohnehin im deutschen Teil des Forums begonnen?

Das Diagramm zeigt nur die typische Einschaltsequenz. XSHUT sollte vor dem Einschalten auf LOW liegen (pulldown).

Nein:
image

Wenn Du je eine Leitung von einem digitalen GPIO des ESP32 zu den Modulen 2 ... 5 mit zusÀtzlicher Hardware meinst, stimmt das.

Hier gab es die Aufgabe ĂŒbrigens schon einmal:

https://forum.arduino.cc/t/mehrere-vl53l0x-gleichzeitig-nutzen/432569/5

Der TO postete diesen Sketch:

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

//#define XSHUT_pin6 not required for address change
#define XSHUT_pin5 9
#define XSHUT_pin4 8
#define XSHUT_pin3 7
#define XSHUT_pin2 6
#define XSHUT_pin1 5

//ADDRESS_DEFAULT 0b0101001 or 41
//#define Sensor1_newAddress 41 not required address change
#define Sensor2_newAddress 42
#define Sensor3_newAddress 43
#define Sensor4_newAddress 44
#define Sensor5_newAddress 45
#define Sensor6_newAddress 46

VL53L0X Sensor1;
VL53L0X Sensor2;
VL53L0X Sensor3;
VL53L0X Sensor4;
VL53L0X Sensor5;
VL53L0X Sensor6;

void setup()
{ /*WARNING*/
  //Shutdown pins of VL53L0X ACTIVE-LOW-ONLY NO TOLERANT TO 5V will fry them
  pinMode(XSHUT_pin1, OUTPUT);
  pinMode(XSHUT_pin2, OUTPUT);
  pinMode(XSHUT_pin3, OUTPUT);
  pinMode(XSHUT_pin4, OUTPUT);
  pinMode(XSHUT_pin5, OUTPUT);
  
  Serial.begin(9600);
  
  Wire.begin();
  //Change address of sensor and power up next one
  Sensor6.setAddress(Sensor6_newAddress);
  pinMode(XSHUT_pin5, INPUT);
  delay(10); //For power-up procedure t-boot max 1.2ms "Datasheet: 2.9 Power sequence"
  Sensor5.setAddress(Sensor5_newAddress);
  pinMode(XSHUT_pin4, INPUT);
  delay(10);
  Sensor4.setAddress(Sensor4_newAddress);
  pinMode(XSHUT_pin3, INPUT);
  delay(10);
  Sensor3.setAddress(Sensor3_newAddress);
  pinMode(XSHUT_pin2, INPUT);
  delay(10);
  Sensor2.setAddress(Sensor2_newAddress);
  pinMode(XSHUT_pin1, INPUT);
  delay(10);
  
  Sensor1.init();
  Sensor2.init();
  Sensor3.init();
  Sensor4.init();
  Sensor5.init();
  Sensor6.init();
  
  Sensor1.setTimeout(500);
  Sensor2.setTimeout(500);
  Sensor3.setTimeout(500);
  Sensor4.setTimeout(500);
  Sensor5.setTimeout(500);
  Sensor6.setTimeout(500);

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  Sensor1.startContinuous();
  Sensor2.startContinuous();
  Sensor3.startContinuous();
  Sensor4.startContinuous();
  Sensor5.startContinuous();
  Sensor6.startContinuous();

}

void loop()
{
  Serial.print(Sensor1.readRangeContinuousMillimeters());
  Serial.print(',');
  Serial.print(Sensor2.readRangeContinuousMillimeters());
  Serial.print(',');
  Serial.print(Sensor3.readRangeContinuousMillimeters());
  Serial.print(',');
  Serial.print(Sensor4.readRangeContinuousMillimeters());
  Serial.print(',');
  Serial.print(Sensor5.readRangeContinuousMillimeters());
  Serial.print(',');
  Serial.print(Sensor6.readRangeContinuousMillimeters());
  Serial.println();
}

Zu beachten:

  • Die GPIOs der XSHUT-AnschlĂŒsse werden zunĂ€chst als OUTPUT gesetzt, das setzt diese nach einem Neustart eines AVR-Controllers in den Status LOW.
  • Danach werden die GPIOs/XSHUT-Pins der Module nach und nach auf INPUT gesetzt, wodurch die GPIO-Pins hochohmig werden (im Gegensatz zu INPUT_PULLDOWN oder INPUT_PULLUP). Damit kann der XSHUT-Pin des Moduls anhand des externen Pullup-Widerstands auf dem Breakout-Board wieder den Zustand HIGH einnehmen.

Externer Pullup:

image

image

siehe Datenblatt des Moduls (https://www.st.com/resource/en/datasheet/vl53l0x.pdf)

Hi @DrDiettrich ,

so hatte ich es zunĂ€chst auch aus den Unterlagen von ST gelesen, allerdings sprechen die Beschreibung von Adafruit (siehe Link in Post 4) und der Forum-Link in Post 18 dafĂŒr, dass der HW Standby-Modus auch zu einem "spĂ€teren" Zeitpunkt geschaltet werden kann.

Insofern ist die State-Machine- Darstellung m.E. nicht eindeutig, da hier der Zustand Hw Standby scheinbar nur aus Power Off oder Fw Initial Boot eingenommen werden kann:

Das lĂ€sst sich aber sicher leicht testen ... wenn man ein solches Modul zur VerfĂŒgung hat :wink:

Da bin ich leider raus und kann nur anhand der Dokumente Annahmen treffen.

Gruß
ec2021

Wenn sich das Teil nicht einfach (via Jumper / LötbrĂŒcken) auf einen andere Adresse einstellen lĂ€sst wĂŒrde ich ein Spezialmodul dazwischen schalten.

z.b. So was :

Nur so als Gedankenspiel + Vorschlag.

Gruß

Pucki

In dem Fall ist noch einfacher, ohne zusatz Hardware :wink:
Mall alles lesen, auch die Links verfolgen.