Servo mit VL53L0X ansteuern

Servus Jungs,

Voller Freude habe ich einen Servo mittels einem Taster angesteuert.
Nun möchte ich statt den Taster den VL53L0X TOF Laser Distanz Sensor verwenden.
Das soll heißen ab 30cm soll sich der Servo drehen, unter 30cm wieder zurück.
Leider fehlt mir das Verständnis wie ich da Anfangen soll.

hier der Servo Code mit Taster

#include <Servo.h>

const int BUTTON = 2; // Pushbutton Pin auf dem Board (2)

int ziel = 1; // 180 oder 0
int akt = 0; //  langsame Änderung
int val = 0; // speichert den Zustand des Tasters
int old_val = 0; // speichert den vorherigen wert von val

const int MIN = 1;     // Servo Stellung am Anfang
const int MAX = 90;   // Servo Stellung am Ende 
const int SPEED = 20;  // ms / je Schritt, (MAX-MIN)*SPEED für den gesamten Weg

Servo servo; // deklariert den Namen des ersten Servos

void setup() {
  pinMode(BUTTON, INPUT); // Gibt an dass Buttom ein Input ist - DAS IST GEÄNDERT
  servo.attach(9); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servo.write(1); // gibt die Grundstellung des Servo beim start an
}

void loop(){
  val = digitalRead(BUTTON); // liest den Taster aus und checkt ob er gedrückt ist.
   if ((val == LOW) && (old_val == HIGH)) {   // Taster neu gedrückt
     ziel = MAX - ziel;  // springt bei jedem neuen Tasten zwischen MAX und MIN
     delay(20); // entprellen
   }  
  old_val = val; // aktueller val wird zu val alt
     if (akt != ziel) {   // Wenn ziel nicht erreicht ist
     if (akt < ziel) akt++; else akt--;   // akt nähert sich ziel schrittweise
     servo.write(akt);
     delay(20) ; // Geschwindigkeit: 1.8 sec für 180 °

  }  
}

Hier der Code für den VL53L0X von pololu

/* This example shows how to get single-shot range
 measurements from the VL53L0X. The sensor can optionally be
 configured with different ranging profiles, as described in
 the VL53L0X API user manual, to get better performance for
 a certain application. This code is based on the four
 "SingleRanging" examples in the VL53L0X API.

 The range readings are in units of mm. */

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

VL53L0X sensor;


// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.

//#define LONG_RANGE


// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed

//#define HIGH_SPEED
//#define HIGH_ACCURACY


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

  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }

#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif

#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
}

void loop()
{
  Serial.print(sensor.readRangeSingleMillimeters());
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();
}

Vielen dank, wenn ihr mir ein wenig auf die sprünge helfen könnt :slight_smile:

lg

Ich versteh noch nicht ganz die Aufgabenstellung.
Aber das zusammensetzen der Codes ist ja nu nicht so schwer, da sich da nichts überschneidet.

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

VL53L0X sensor;


// Uncomment this line to use long range mode. This
// increases the sensitivity of the sensor and extends its
// potential range, but increases the likelihood of getting
// an inaccurate reading because of reflections from objects
// other than the intended target. It works best in dark
// conditions.

//#define LONG_RANGE


// Uncomment ONE of these two lines to get
// - higher speed at the cost of lower accuracy OR
// - higher accuracy at the cost of lower speed

//#define HIGH_SPEED
//#define HIGH_ACCURACY







const int BUTTON = 2; // Pushbutton Pin auf dem Board (2)

int ziel = 1; // 180 oder 0
int akt = 0; //  langsame Änderung
int val = 0; // speichert den Zustand des Tasters
int old_val = 0; // speichert den vorherigen wert von val

const int MIN = 1;     // Servo Stellung am Anfang
const int MAX = 90;   // Servo Stellung am Ende
const int SPEED = 20;  // ms / je Schritt, (MAX-MIN)*SPEED für den gesamten Weg

Servo servo; // deklariert den Namen des ersten Servos

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  Wire.begin();
  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }
#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif
  pinMode(BUTTON, INPUT); // Gibt an dass Buttom ein Input ist - DAS IST GEÄNDERT
  servo.attach(9); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servo.write(1); // gibt die Grundstellung des Servo beim start an
}

void loop()
{
  /*
    val = digitalRead(BUTTON); // liest den Taster aus und checkt ob er gedrückt ist.
    if ((val == LOW) && (old_val == HIGH))     // Taster neu gedrückt
    {
    ziel = MAX - ziel;  // springt bei jedem neuen Tasten zwischen MAX und MIN
    delay(20); // entprellen
    }
    old_val = val; // aktueller val wird zu val alt
  */
  uint16_t abstand = sensor.readRangeSingleMillimeters();
  Serial.print(abstand);
  if (abstand < 300)
  {
    if (akt != ziel)     // Wenn ziel nicht erreicht ist
    {
      if (akt < ziel)
      {
        akt++;
      }
      else
      {
        akt--;  // akt nähert sich ziel schrittweise
      }
      servo.write(akt);
      delay(20) ; // Geschwindigkeit: 1.8 sec für 180 °
    }
  }
}

Vielen Dank erstmal!
Aber wenn ich den Code laufen lasse, bekomme ich im serieller Monitor nur

6:51:18.407 -> Start...
06:51:18.686 -> ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

und es geht gar nichts .

Der serielle Monitor muss die selbe Einstellung haben, wie im Code hinterlegt.

Hat er doch sonst wurde kein Start ausgegeben

ok, hab auf 9600 geändert, jetzt kommen statt lauter Fragezeichen eine Zahlenwurscht raus.

13:06:31.688 -> Start...
13:06:31.967 -> 4242414242414142434546464950524837363737363736373637363644819045481

:slight_smile: Das ist Dein Abstand.
In Zeile 86 kannst aus dem Serial.print(abstand) ein Serial.println(abstand) machen und dann kommt das Zeilenweise.
Und aus der 300 darunter mach eine 30, ich war bei 3 mtr., Du willst ja nur 30 cm.

ah super das Laser messen funktioniert, aber der Servo macht keinen Rührer wenn der Messwert über oder unter 300 geht :woozy_face:

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

VL53L0X sensor;

//#define LONG_RANGE
//#define HIGH_SPEED
#define HIGH_ACCURACY

int ziel = 1; // 180 oder 0
int akt = 0; //  langsame Änderung

const int MIN = 1;     // Servo Stellung am Anfang
const int MAX = 90;   // Servo Stellung am Ende
const int SPEED = 20;  // ms / je Schritt, (MAX-MIN)*SPEED für den gesamten Weg

Servo servo; // deklariert den Namen des ersten Servos

void setup()
{
  Serial.begin(9600);
  Serial.println(F("Start..."));
  Wire.begin();
  sensor.setTimeout(500);
  if (!sensor.init())
  {
    Serial.println("Failed to detect and initialize sensor!");
    while (1) {}
  }
#if defined LONG_RANGE
  // lower the return signal rate limit (default is 0.25 MCPS)
  sensor.setSignalRateLimit(0.1);
  // increase laser pulse periods (defaults are 14 and 10 PCLKs)
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
  sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif
#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms
  sensor.setMeasurementTimingBudget(200000);
#endif

  servo.attach(9); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servo.write(1); // gibt die Grundstellung des Servo beim start an
}

void loop()
{
  uint16_t abstand = sensor.readRangeSingleMillimeters();
  Serial.println(abstand);
  if (abstand < 300)
  {
    if (akt != ziel)     // Wenn ziel nicht erreicht ist
    {
      if (akt < ziel)
      {
        akt++;
      }
      else
      {
        akt--;  // akt nähert sich ziel schrittweise
      }
      servo.write(akt);
      delay(20) ; // Geschwindigkeit: 1.8 sec für 180 °
    }
  }
}

Ich hab den Ausgangssketch noch nicht verstanden, aber evtl. habe ich nur was übersehen.

einfach mal loop() austauschen:

void loop()
{
  uint16_t abstand = sensor.readRangeSingleMillimeters();
  Serial.println(abstand);
  if (abstand < 300)
  {
    ziel = MAX - ziel;
  }
  if (akt != ziel)     // Wenn ziel nicht erreicht ist
  {
    if (akt < ziel)
    {
      akt++;
    }
    else
    {
      akt--;  // akt nähert sich ziel schrittweise
    }
    servo.write(akt);
    delay(20) ; // Geschwindigkeit: 1.8 sec für 180 °
  }
}

Jetzt bewegt sich der Servo wenn der Laser über < 200 misst.

Der Sketch ist Grundlegend so gedacht.
Das wenn der Laser über < 200 misst das der Servo auf MAX fährt
unter > 200 auf MIN

Was mir noch auf fällt das der Servo sehr zuckt beim verfahren.

lg

Das soll eigentlich 300 sein:

die 20ms delay(20) verkürzen.

Ah sorry mein Fehler,
wo liegt der Fehler das der Servo nicht mehr zurückfährt wenn der Wert unter 300 geht?

Ich bin ja schon froh, das der Servo sich überhaupt bewegt... :wink:

Dir fehlt vermutlich ein else zweig.

Ein neues loop()

void loop()
{
  uint16_t abstand = sensor.readRangeSingleMillimeters();
  Serial.println(abstand);
  if (abstand < 300)
  {
    if (akt < MAX)
    {
      akt++;
    }
  }
  else if (abstand > 300)
  {
    if (akt > MIN)
    {
      akt--;
    }
  }
  servo.write(akt);
  delay(SPEED) ; // Geschwindigkeit: 1.8 sec für 180 °
}

Wow genau das ist es! Danke
Wo kann ich den die Servo Geschwindigkeit erhöhen?

Wenn Du die Zeit verkürzt, sollte es gehen:

Wenn ich zwischen den beiden wechsle

#if defined HIGH_SPEED
  // reduce timing budget to 20 ms (default is about 33 ms)
  sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY
  // increase timing budget to 200 ms

Auf High_Speed geht auch der Servo schneller