Construye un Sistema LIDAR con Arduino, VL6180X y Motor Servo
Componentes y suministros
| Componente | Cantidad | Notas |
|---|---|---|
| Arduino UNO | 1 | |
| Sensor ToF SparkFun VL6180 | 1 | VL53L0X para largo alcance y VL6180X para corto alcance. Aquí usé VL6180X |
| Motor servo | 1 |
Aplicaciones y servicios en línea
- Arduino IDE
- Processing
Sobre el proyecto
Algunas cosas sobre LIDAR
LIDAR (Detección y Medición de Luz) es un sistema de teledetección óptica que puede medir la distancia de un objetivo iluminándolo con luz. La tecnología LIDAR se usa en robótica para la percepción del entorno y clasificación de objetos. La capacidad de LIDAR para proporcionar mapas de elevación 2D del terreno, distancia de alta precisión al suelo y velocidad de aproximación puede permitir el aterrizaje seguro de vehículos robóticos y tripulados con alta precisión.
LIDAR consiste en un transmisor que ilumina un objetivo con un haz láser, y un receptor capaz de detectar el componente de luz esencialmente coaxial con el haz transmitido. Los sensores receptores calculan una distancia basada en el tiempo necesario para que la luz alcance el objetivo y regrese. Un mecanismo mecánico con un espejo barre el haz de luz para cubrir la escena requerida en un plano o incluso en tres dimensiones, usando un espejo giratorio asintiendo.
Una forma de medir el tiempo de vuelo del haz de luz es usar un láser pulsado y medir el tiempo transcurrido directamente. Se requiere electrónica capaz de resolver picosegundos en tales dispositivos y son por tanto muy caros. Otro método es medir el cambio de fase de la luz reflejada.
Se usa láser infrarrojo colimado para la medición de cambio de fase. Para superficies con rugosidad mayor que la longitud de onda de la luz incidente, ocurrirá reflexión difusa. El componente de luz infrarroja retornará casi paralelo al haz transmitido para objetos.
El sensor mide el cambio de fase entre las señales transmitida y reflejada. La imagen muestra cómo esta técnica puede usarse para medir distancia. La longitud de onda de la señal moduladora obedece la ecuación:
c = f · τ
donde c es la velocidad de la luz, f la frecuencia moduladora y τ la longitud de onda moduladora conocida.
La distancia total D' recorrida por la luz emitida es:
D' = B + 2A = B + (θ · τ) / 2π
donde A es la distancia medida. B es la distancia desde la unidad de medición de fase. La distancia requerida D, entre el divisor de haz y el objetivo, es por tanto:
D = τ · θ / 4π
donde θ es la diferencia de fase medida electrónicamente entre los haces de luz transmitido y reflejado.
Se puede demostrar que el alcance es inversamente proporcional al cuadrado de la amplitud de la señal recibida, afectando directamente la precisión del sensor.
(Copiado de home.roboticlab.eu).
Como parte de mi proyecto de fin de carrera necesito el mapa 2D del entorno para mi vehículo autónomo, así que elegí LIDAR porque es muy rápido y preciso. A diferencia de los sonares que rebotan ondas ultrasónicas, el "cono" de detección es muy estrecho.
VL6180X o VL53L0X es un sensor óptico de STMicroelectronics. VL53L0X es mucho más preciso y no tiene problemas de linealidad ni "doble imagen" donde no puedes saber si un objeto está muy lejos o muy cerca.
Este sensor de tiempo de vuelo se usa en nuestros móviles para ajustar el enfoque de la cámara.
Diagrama de circuito

Instalar librería Adafruit

Código Arduino
#include <Wire.h>
#include "Adafruit_VL6180X.h"
#include <Servo.h>
Adafruit_VL6180X vl = Adafruit_VL6180X();
Servo myservo;
float pos = 0;
const float Pi = 3.14159;
void setup() {
myservo.attach(9);
Serial.begin(115200);
while (!Serial) { delay(1); }
if (!vl.begin()) { while (1); }
}
void loop() {
for (pos = 0; pos <= 180; pos += 0.5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
/* Para barrido de retorno (comentado)
for (pos = 180; pos >= 0; pos -= 0.5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
*/
myservo.write(0);
delay(2000);
}
Código Processing
(Consulta otros proyectos de radar si necesitas una mejor interfaz) Cambia el número de puerto Arduino (ej. "COM 3") antes de ejecutar.
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
String portName = "COMx"; // x = tu número de puerto Arduino
myPort = new Serial(this, portName, 115200);
background(255);
}
void draw() {
if (myPort.available() > 0) {
val = myPort.readStringUntil('\n');
if (val != null) {
String[] nums = split(val, "p");
if (nums.length == 3) {
range = int(nums[0]);
pos = float(nums[1]);
i = int(nums[2]);
if (i == 180) { background(255); }
}
}
}
translate(25, -50);
line(250, 500, 250 - 2 * (range * cos(pos)), 500 - 2 * (range * sin(pos)));
}

La velocidad del sensor está limitada a 10Hz y la respuesta del servo es pobre a mayor velocidad. Si alguien planea hacer un LIDAR de alta velocidad, use motor paso a paso o motores DC con sistema de retroalimentación. Use anillos deslizantes para rotación continua (Adafruit 736).
¡Preguntas y sugerencias son bienvenidas!
Código
Código Arduino
#include <Wire.h>
#include "Adafruit_VL6180X.h"
#include <Servo.h>
Adafruit_VL6180X vl = Adafruit_VL6180X();
Servo myservo;
float pos = 0;
const float Pi = 3.14159;
void setup() {
myservo.attach(9);
Serial.begin(115200);
while (!Serial) { delay(1); }
if (!vl.begin()) { while (1); }
}
void loop() {
for (pos = 0; pos <= 180; pos += .5) {
myservo.write(pos);
uint8_t range = vl.readRange();
Serial.println(String(range) + "p" + String(pos * Pi / 180) + "p" + String(pos));
delay(10);
}
myservo.write(0);
delay(1000);
}
Código Processing
import processing.serial.*;
Serial myPort;
String val;
int range, i = 0;
float pos;
void setup() {
size(550, 500);
frameRate(36);
String portName = "COMx"; // x = tu número de puerto Arduino
myPort = new Serial(this, portName, 115200);
background(255);
}
void draw() {
if (myPort.available() > 0) {
val = myPort.readStringUntil('\n');
if (val != null) {
String[] nums = split(val, "p");
if (nums.length == 3) {
range = int(nums[0]);
pos = float(nums[1]);
i = int(nums[2]);
if (i == 180) { background(255); }
}
}
}
translate(25, -50);
line(250, 500, 250 - 2 * (range * cos(pos)), 500 - 2 * (range * sin(pos)));
}
Proceso de manufactura
- Faroles de Gas: Evolución, Diseño y Fabricación Moderna
- Puntero Láser: Diseño, Fabricación y Resumen de Seguridad
- Linterna: de su invención a la innovación moderna
- El Caleidoscopio: De la Ciencia de Brewster al Diseño Moderno
- Láseres de Semiconductor: Generación Precisa de Luz para Tecnología Moderna
- El arte y la ciencia de los procesos fotográficos: del daguerrotipo al film moderno
- Semáforos: Ingeniería, Historia e Innovaciones Futuras
- Del Fuego al Filamento: Evolución y Producción de la Bombilla Moderna
- Fibra Óptica: Tecnología, Producción y Futuro
- Lámpara de mesa RGB controlada por gestos – Iluminación interactiva y sin manos
- Kodiak 3D LiDAR: Telemetría Espacial de Precisión para Misiones de Alta Órbita