VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Dienstag nachmittag passt.
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von e69-fan »

:(V):

Super - ist notiert - Danke
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Ich habe jetzt mal die Library rausgesucht die ich für den VL53L0X verwendet habe.

Und das ist die Lib für den Multiplexer TCA9548A.

Franz
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von e69-fan »

Hallo Franz,

:(V): :(V): :(V):

viele Dank für die Fleißaufgabe.

In der Lib für das LCD Display habe ich mir mal ein "example" angeschaut - aber leider kein I2C drin. Ich muss wohl weitersuchen.

Ich komme erst heute Abend dazu - Krankenfahrdienst für einen Freund.


Einen sonnigen Tag wünscht Dir
Wolfgang
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Jetzt habe ich auf meiner Mühle die Lib gesucht. Und gefunden. habe so lange "liquidCrystal" Dateien runtergeschmissen, bis der Compiler gemault hat, dass er liquidCrystal_I2C.h nicht mehr findet. Dann war klar dass das die richtigen Dateien sind. :)
Ich habe sie jetzt mal gezippt und verlinkt. So habe ich jetzt wenigstens den ganzen Müll mal wieder runtergeschissen, den ich am Anfang zum Testen installiert habe. Da gab es sehr viel, was nie funktioniert hatte. :evil:

Ich schaue mal ob es die im Netz noch gibt. Die ist ja von 2016 :O: .........was neueres ware da schon schön :roll:

Ich habe jetzt auf GitHub das hier gefunden. Wäre interessant ob das die Fortführung meiner NewLiquidCrystal Lib ist. Aber ich habe jetzt keine Lust, dass ich meine Lib nochmal von Rechner lösche und dann diese hier verlinkte installiere. Vielleicht mache ich es am Wochenende nochmal, wenn ich viel Lust habe :(o): . Weil meine hat ja seit 2016 kein UpDate bekommen. Die war ja noch nicht offiziell als ich mir die geschossen habe. :roll:
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Ich habe jetzt mal in das Programm oben Sesoren mit Multiplexer zusätzlich zum Relais diese Wechselblink Anlage dazu gebaut. Dann schaut das Programm so aus:

Code: Alles auswählen

/* Dieses Beispiel zeigt, wie man eine Einzelschussreichweite erhält
  Messungen vom VL53L0X. Der Sensor kann optional sein
  mit unterschiedlichen Ranging-Profilen konfiguriert, wie in . beschrieben
  das VL53L0X API-Benutzerhandbuch, um eine bessere Leistung für
  eine bestimmte Anwendung. Dieser Code basiert auf den vier
  "SingleRanging"-Beispiele in der VL53L0X-API.

  Die voreingestellte I2C Adresse (0x29)

  Die Entfernungsmesswerte sind in mm angegeben. */

#include <Wire.h>
#include <VL53L0X.h>
VL53L0X sensor;
#include <LiquidCrystal_I2C.h> // LCD Display
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

#include <MobaTools.h>

#include <Arduino.h>            // I2C Multiplexer einrichten
#include "TCA9548A.h"
TCA9548A I2CMux;

// Festlegen der Ports Wechselblink
const int Blinker1P  =  6;  // Die beiden Led's des
const int Blinker2P  =  7;  // Wechselblinkers.
// Weitere Konstanten
const int wbZykl = 1100;    // Zykluszeit des Wechselblinkers
const int wbSoft = 400;     // Auf/Abblendzeit der Lampen
boolean Gleis1    = false;  // Gleis 1 belegt/frei
boolean SchalterP = false;  // Blinkschaltung on/off

int messung1 = 0;
int messung2 = 0;
const byte LS_Relais01 = 2; // Pin 2 ist für Relais Lichtschranke
byte MerkerLS1 = 0;
unsigned long LS_Laufzeit01 = 0; // Lichtschranke01 Ablauf Zeit
const unsigned long LS_Pausezeit01 = 3000; // Lichtschranke01 Prüfzeit Überbrückung 3 Sek.
unsigned long milli_aktuell = 0;
byte LS_Status01 = 0;
byte LS_Status02 = 0;

// Zustand des Wechselblinker
byte wblZustand = 0;        // In dieser Variable wird hinterlegt, in welchem Zustand
// sich der Wechselblinker gerade befindet
#define   WBL_AUS     0     // beide Lampen sind aus
#define   WBL_START   1     // Startphase: beide Lampen sind an
#define   WBL_BLINKT  2     // Die Lampen blinken normal im Wechsel
byte ledState;              // HIGH : Blinker1 ist an, LOW Blinker2 ist an

MoToSoftLed Blinker1;
MoToSoftLed Blinker2;
MoToTimer BlinkUhr;

// Entkommentieren Sie diese Zeile, um den Langstreckenmodus zu verwenden. Diese
// erhöht die Empfindlichkeit des Sensors und verlängert seine
// potenzielle Reichweite, erhöht aber die Wahrscheinlichkeit, dass
// eine ungenaue Lesung aufgrund von Reflexionen von Objekten
// anders als das beabsichtigte Ziel. Es funktioniert am besten im Dunkeln
// Bedingungen.

//#define LONG_RANGE


// Entkommentieren Sie EINE dieser beiden Zeilen, um folgendes zu erhalten.
// - höhere Geschwindigkeit auf Kosten einer geringeren Genauigkeit oder
// - höhere Genauigkeit auf Kosten einer geringeren Geschwindigkeit

//#define HIGH_SPEED
#define HIGH_ACCURACY


void setup()
{
  digitalWrite (LS_Relais01, HIGH); // Relaisausgang beim Start "aus"
  pinMode(LS_Relais01, OUTPUT);

  Blinker1.attach(Blinker1P);     // die Ausgänge werden automatisch auf OUTPUT gesetzt
  Blinker1.riseTime( wbSoft );    // Aufblendzeit in ms

  Blinker2.attach(Blinker2P);
  Blinker2.riseTime( wbSoft );    // Aufblendzeit in ms

  I2CMux.begin(Wire);             // Wire-Instanz wird an die Bibliothek übergeben für I2C Multiplexer
  I2CMux.closeAll();              // Alle Kanäle schließen

  Serial.begin(9600);
  Wire.begin();
  I2CMux.openChannel(0);         // I2C Multiplexer Display Kanal 0 ativieren
  lcd.begin(20, 4);
  lcd.backlight();
  lcd.clear();
  lcd.setCursor (2, 0);
  lcd.print (F("Abstandsmessung 1"));
  lcd.setCursor (2, 1);
  lcd.print (F("mm:"));
  lcd.setCursor (2, 2);
  lcd.print (F("Abstandsmessung 2"));
  lcd.setCursor (2, 3);
  lcd.print (F("mm:"));

  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(1);    // I2C Multiplexer IR-Sensor 1 Kanal 1 ativieren
  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Sensor 1 konnte nicht erkannt und initialisiert werden!");
    while (1) {}
  }
  delay(200);
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(2);    // I2C Multiplexer IR-Sensor 2 Kanal 2 ativieren
  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Sensor 2 konnte nicht erkannt und initialisiert werden!");
    while (1) {}
  }
  delay(200);
#if defined LONG_RANGE
  // Verringern Sie die Begrenzung der Rücksendesignalrate (Standard ist 0,25 MCPS)
  // Sensor 1
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(1);        // I2C Multiplexer IR-Sensor 1 Kanal 1 ativieren
  sensor.setSignalRateLimit(0.1);
  // Laserpulsperioden erhöhen (Standardwerte sind 14 und 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
  delay(200);
  //Sensor 2
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(2);        // I2C Multiplexer IR-Sensor 2 Kanal 2 ativieren
  sensor.setSignalRateLimit(0.1);
  // Laserpulsperioden erhöhen (Standardwerte sind 14 und 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
  delay(200);
  // Sensor 1
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(1);        // I2C Multiplexer IR-Sensor 1 Kanal 1 ativieren
#if defined HIGH_SPEED
  // Timing-Budget auf 20 ms reduzieren (Standard ist etwa 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // Timing-Budget auf 200 ms erhöhen
  sensor.setMeasurementTimingBudget(200000);
#endif
  delay(200);
  // Sensor 2
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(2);        // I2C Multiplexer IR-Sensor 2 Kanal 2 ativieren
#if defined HIGH_SPEED
  // Timing-Budget auf 20 ms reduzieren (Standard ist etwa 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // Timing-Budget auf 200 ms erhöhen
  sensor.setMeasurementTimingBudget(200000);
#endif
  delay(200);
}

void loop()
{
  // ---Millis übergeben----------------------------
  milli_aktuell = millis();
  // ---Lichtschranke01 Kontrolle-------------------
  if (messung1 <= 200) {
    LS_Status01 = LOW;
  }
  else {
    LS_Status01 = HIGH;
  }
  if (messung2 <= 200) {
    LS_Status02 = LOW;
  }
  else {
    LS_Status02 = HIGH;
  }
  if ((LS_Status01 == LOW) || (LS_Status02 == LOW)) {
    digitalWrite (LS_Relais01, LOW); // Relais01 auf Pin2 einschalten
    Gleis1 = true;
    LS_Laufzeit01 =  milli_aktuell;
    MerkerLS1 = 1;
  }
  else {
    if ((milli_aktuell - LS_Laufzeit01 >= LS_Pausezeit01) && (MerkerLS1 == 1)) // Überbrückungszeit abgelaufen ?
    {
      digitalWrite (LS_Relais01, HIGH); // Relais01 auf Pin2 ausschalten
      Gleis1 = false;
      MerkerLS1 = 0;
    }
  }
  //---Lichtschranke01 Ende------------------------
  SchalterP = Gleis1; // Blinken, wenn Gleis 1 belegt
  //Sensor 1
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(1);        // I2C Multiplexer IR-Sensor 1 Kanal 1 ativieren
  messung1 = (sensor.readRangeSingleMillimeters());
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(0);        // I2C Multiplexer Display Kanal 0 aktivieren
  lcd.setCursor (10, 1);
  lcd.print (F("     "));
  lcd.setCursor (10, 1);
  lcd.print (messung1);

  //Sensor 2
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(2);        // I2C Multiplexer IR-Sensor 2 Kanal 2 ativieren
  messung2 = (sensor.readRangeSingleMillimeters());
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(0);        // I2C Multiplexer Display Kanal 0 aktivieren
  lcd.setCursor (10, 3);
  lcd.print (F("     "));
  lcd.setCursor (10, 3);
  lcd.print (messung2);

  // Sensor 1
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(1);    // I2C Multiplexer IR-Sensor 1 Kanal 1 ativieren
  if (sensor.timeoutOccurred()) {
    Serial.print(F(" TIMEOUT Sensor 1"));
  }
  // Sensor 2
  I2CMux.closeAll();        // Close all
  I2CMux.openChannel(2);    // I2C Multiplexer IR-Sensor 2 Kanal 2 ativieren
  if (sensor.timeoutOccurred()) {
    Serial.print(F(" TIMEOUT Sensor 2"));
  }
  // Wechselblinker -------------------------------------------------------------------
  switch (wblZustand) {
    case WBL_AUS:
      // Beide Lampen sind aus, warten auf einschalten
      if ( SchalterP == true && BlinkUhr.running() == false ) {
        // Beide Leds einschalten, Timer für gemeinsames Startleuchten
        Blinker1.on();
        Blinker2.on();
        BlinkUhr.setTime( wbSoft );
        wblZustand = WBL_START;
      }
      break;
    case WBL_START:
      // Startphase: Nach Zeitablauf erste Led wieder aus
      if ( BlinkUhr.running() == false ) {
        // Die Startzeit ist abgelaufen, Übergang zur normalen Blinkphase
        ledState = HIGH;
        Blinker2.off();
        BlinkUhr.setTime(wbZykl / 2); // Zeitverzögerung setzen
        wblZustand = WBL_BLINKT;
      }
      break;
    case WBL_BLINKT:
      if ( BlinkUhr.running() == false ) {
        BlinkUhr.setTime(wbZykl / 2); // Zeitverzögerung setzen
        if ( ledState == LOW ) {
          Blinker1.on();
          Blinker2.off();
          ledState = HIGH;
        } else {
          ledState = LOW;
          Blinker2.on();
          Blinker1.off();
        }
      }
      if ( SchalterP == false ) {
        // Wechselblinker abschalten
        Blinker1.off();
        Blinker2.off();
        wblZustand = WBL_AUS;
        BlinkUhr.setTime(wbZykl);   // minimale 'Aus' zeit des Blinkers
        //( schützt vor Schalterprellen )
      }
      break;
  } // Ende switch Wechselblinker -------------------------------------------------
}
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Diese Wechselblink ist eine ganze Menge Programmcode. Da möchte ich mal schauen ob man das nicht mit nem schlankeren Code schaft.

Franz
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

Admin hat geschrieben: So 8. Aug 2021, 13:53 OK, ich habe jetzt nochmal den einzelnen Sensor ohne Multiplexer aufgebaut. Der misst bis 30cm zufriedenstellend. Dann habe ich wieder zwei sensoren mit Multiplexer aufgebaut, und dann misst einer genauso zufriedenstellend, der andere misst ~25mm zuviel. Beim letzten Aufbau sind beide Sensoren bei grösser 25cm nicht mehr zuverlässig gewesen. Ich vermute jetzt, dass es an den Kabeln liegt. Die haben 30cm länge. Und da werden ziehmlich viele Störsignale reinkommen. Der Unterschied ist wohl im Moment einfach nur, wie die Kabel zufällig gerade daliegen. Ich baue mir jetzt mal geschirmte Kabel für die Datenwege. Dann dürfte der Spuck vorbei sein. Du wirst ja bei deiner Eisenbahn sowieso die Kabel geschirmt verlegen. Dann wird das Problem Geschichte sein.
Ich habe inzwischen ganz kurze Steckkabelchen von 10cm. Ich dacht eigentlich da sind die Störungen weg. Aber Pustekuchen. Das ist auch nicht einwandfrei. Also nur in Verbindung mit genauer Feststellung der Entfernung gibts Probleme. Worauf es ja bei deinen Anwendungen nicht ankommt. Da gehts ja nur darum ob in einer bestimmten Mindestentfernung was ist. Und das ist eindeutig. Aber wenn ich die zutreffende Entfernung in mm will, dann wird es ein Problem.
.
VL53L0X über I2C Multiplexer.jpg
VL53L0X über I2C Multiplexer.jpg (145.63 KiB) 1041 mal betrachtet
Hier ist der Aufbau mit möglichst kurzen kurzen Kabeln vom Multiplexer zum Sensor. Auch die +/- Kabel mit kurzen Kabeln zum Sensor. Nur die Zuleitungen vom Arduino I2C und +/- kommen über 20cm Kabel. Also das kürzen der Kabel hat nichts gebracht. Das mit den Geschirmten Kabeln hatte ich vergessen zu testen. Aber jetzt bin ich wieder drann, weil die kurzen Kabel nichts bringen. Ich muss noch eine Fahrradgarage fertig bauen, dann bin ich da dran. Denke am Wochenende.

Das Brett mit den Sensoren habe ich jetzt gleich noch erweitert, dass ich die Sensoren getrennt über Datenkabel anfahren kann. Als nächstes mache ich einen solchen Multiplexer auch geschirmt, dass sich die I2C Leitungen die dort rein und raus gehen nicht mehr begegnen. Dann sollte das Problem weg sein. Wenn es dann immer noch da ist, bin ich am Ende mit meinen Ideen :sad: .....aber ich bin seeeeehr zuversichtlich dass es dann geht. :)
.
VL53L0X über geschirmte Kabel.jpg
VL53L0X über geschirmte Kabel.jpg (110.95 KiB) 1036 mal betrachtet
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von e69-fan »

:agt: :agt:

Bei mir funktioniert es nur mit einem Sensor - eventuell ist der Multiplexer defekt. Das müssten wir mal testen
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1197
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: VL53L0X ToF Sensor Laser Entfernungsmessung am Arduino

Beitrag von Admin »

OK, ich mache meinen Test mal am WE fertig und wenn das dann bei mir gut ist, können wir es bei dir mal anstecken.

Wünsche gut zu schlafen
Franz :(V):
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste