Lidar ist die Abkürzung für Light detection and ranging. Man versteht also darunter die Entfernungsbestimmung mittels Laserlicht. Scannt man einen Raumwinkelbereich ab, so kann man auch ein 3D-Abbild der Umgebung erzielen (engl. laserscanning).
Zur Abstandsbestimmung verwende ich einen gewöhnlichen Laserdistanzmesser vom Typ UNI-T UT390b. Dieser ist auf einer mit 2 Servos betriebenen Montierung fixiert. Per Knopfdruck rastert die Montierung/der Sensor einen größeren Raumwinkelbereich ab und bestimmt somit die Entfernung d in Abhängigkeit der beiden Winkel φ (horizontal) und θ (vertikal). Mit diesen Daten (φ, θ, d) kann man sodann ein 3D-Abbild erstellen. Ich setzte dies mit der Uraltsprache Turbo-Pascal um. Um das 3D-Abbild realistischer erscheinen zu lassen, verbinde ich sämtliche Raumpunkte mit Geraden. So kommt ein schönes Gitternetz zustande.
Da der Laserentfernungsmesser während des Scans immer wieder einmal abstürzt (fehlerhafte Messung), habe ich einen Reset-Schalter installiert. Dadurch verliere ich keine Werte während der Messung.
Mit dem Lidar Lite-V3 oder dem Sharp GP2Y0A710K0F gibt es speziell auf den Einsatz mit dem Arduino abgestimmte Lidar-Entfernungsmesser.





Bildquelle: https://www.scansurveying.com/en/services/terrestrial-laser-scanning/









Arduino-Code:
// =========================================================
// ====== Programm zur Erstellung eines 3D-Raumbilds =======
// ========= mit dem UT390b-Laserentfernungsmesser =========
// =========================================================
// =======================================
// ====== Fehlermeldungen des Geräts =====
// =======================================
/*
ERR_BATTERY_LOW = 101,
ERR_CALCULATION = 104,
ERR_HIGH_TEMP = 152,
ERR_LOW_TEMP = 153,
ERR_OUT_OF_RANGE = 154,
ERR_WEAK_SIGNAL = 155,
ERR_STRONG_SIGNAL = 156,
ERR_BACKGROUND_ILLUM = 157,
ERR_DEVICE_SHAKING = 160
*/
#include <Servo.h> // Inkludiert die Servodateien
#include <i2cmaster.h> // Inkludiert die i2c-Bus-Dateien
#include <UT390B.h>
UT390B laser(Serial1); // create a laser object
Servo servo_horiz; // Definiert den horizontalen servo
Servo servo_verti; // Definiert den vertikalen servo
int taste; // Tastaturpin für Start des Scans
int horiz_start = 60; // horizontaler Startwinkel
int verti_start = 0; // vertikaler Startwinkel
int schritte = 30; // horizontale bzw. vertikale Schritte
int schrittweite = 2; // Schrittweite der Servos
long lastMeasurement = -10000;
boolean recdata = true;
boolean data;
int buf[64];
int rc=0;
int Distanz;
// ************************************
// ************** SETUP ***************
// ************************************
void setup()
{
Serial.begin(115200);
//Serial1.begin(115200);
servo_horiz.attach(9); // Set horizontalen servo to digital pin 9
servo_verti.attach(10); // Set vertikalen servo to digital pin 10
pinMode(13, OUTPUT);
}
// ********************************************
// ************** HAUPTSCHLEIFE ***************
// ********************************************
void loop()
{
taste = analogRead(A0); // Abfrage, ob die Taste gedrückt wird und der Scan gestartet werden kann
servo_horiz.write(horiz_start);
servo_verti.write(verti_start);
if (taste < 500)
{
// ********** Messung gestartet ************
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
for (int i = 0; i < schritte; i++)
{
servo_horiz.write(horiz_start + i * schrittweite);
servo_verti.write(verti_start);
delay(50);
for (int j = 0; j < schritte; j++)
{
servo_verti.write(verti_start + j * schrittweite);
delay(20);
// Einlesen der Distanz
// ====================
laser.triggerMeasurement(); // Triggerung einer neuen Messung
do
{
if(laser.measurementAvailable())
{
Distanz = laser.readMeasurement(); // Distanzmessung
lastMeasurement = millis(); // Rücksetzung der Messzeit
}
else // keine Messung erfolgt
{
laser.triggerMeasurement();
Distanz = -1;
}
/*
if(millis() - lastMeasurement > 2000) // Überprüfung, ob letzte Messung zu lange her
{
laser.triggerMeasurement();
lastMeasurement = millis();
}
*/
}
while(Distanz <= 0); // Wiederholung bis korrekte Distanz > 0
Serial.print(horiz_start + i * schrittweite);
Serial.print(" ");
Serial.print(verti_start + j * schrittweite);
Serial.print(" ");
Serial.println(Distanz/10); // Ausgabe der gemessenen Distanz in cm
}
}
// ********** Messung beendet ************
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
servo_horiz.write(horiz_start);
servo_verti.write(verti_start);
}
}
