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.
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.
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 ...
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.
ins Datenblatt unter Punkt 2.9.1 Power up and boot sequence:
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.
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).
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.
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.
#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.
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: