Arduino 360 LIDAR com VL53L0X e 28BYJ48 – p1v1

Projecto de elaboração de um LIDAR 360 graus caseiro efectuado com base no microcontrolador Arduino, os sensores de distancia laser VL53L0X e no stepper 28BYJ48.

Este é o primeiro protótipo feito no projecto, e consiste numa implementação grosseira dos conceitos base que pretendo usar para construir o LIDAR.

Arduino 360 LIDAR com VL53L0X e 28BYJ48

Arduino 360 LIDAR com VL53L0X e 28BYJ48Video da primeira versão experimental do prototipo do LIDAR 360 com o Arduino, sensores VL53L0X e stepper 28BYJ48 a funcionar.

Hardware usado no Arduino LIDAR 360

  • 1 x Arduino Nano 168
  • 1 x Motor de passos 28 BYJ-48
  • 1 x Driver ULN2003
  • 1 x Conversor de nivel lógico (5V – 3.3)
  • 2 x Sensor de distância laser (1 x CJVL53L0XV2 + 1 x VL53L0X pololu)
  • 1 x Slip Ring de 6 fios
  • 1 x LED IR emissor (branco) + 1 x resistencia de 47 ohm
  • 1 x LED IR receptor (escuro) + 1 x resistencia de 1M ohm
  • 1 x Alimentação ( 1 x 7805 + 2 x condensadores)
  • Peças em impressora 3D
    • Suporte do motor de passos
    • Pinhão do motor de passos
    • Suporte da engrenagem maior
    • Engrenagem maior (suporte dos sensores)
    • Apoios do suporte do motor de passos
    • Suportes dos sensores
  • Fios, Placas de teste

 

Visão de pormenores do LIDAR

Arduino e placa de testes do 360 LIDAR
Arduino e placa de testes inferior

 

Arduino 360 LIDAR - Sensors
Arduino 360 LIDAR – Sensores

 

Arduino 360 LIDAR - Breadbord Sensors
Arduino 360 LIDAR – Placa teste dos sensores

 

Arduino 360 LIDAR - Breadbord e Sensor
Arduino 360 LIDAR – Breadbord e Sensor

 

Software usado no teste do LIDAR

Programa usado para teste básico das funcionalidades do Arduino 360 LIDAR.

VL53L0X_28BYJ-48_lidar_v3

//
// Lidar v.1.x
//

#include <Wire.h>

//BOF VL53L0X
#include <VL53L0X.h>
#define PIN1 11
#define PIN2 12
VL53L0X sensor1;
VL53L0X sensor2;
#define SENSOR_INTERVAL 20
unsigned long nextSensorTimer = 0;
byte nextSensorIndex = 1;
int sensor1Value = 0;
int sensor2Value = 0;

// 28BYJ-48
#include <AccelStepper.h>
#define stepperPin1 4 // IN1 on the ULN2003 driver 1
#define stepperPin2 5 // IN2 on the ULN2003 driver 1
#define stepperPin3 6 // IN3 on the ULN2003 driver 1
#define stepperPin4 7 // IN4 on the ULN2003 driver 1
AccelStepper stepper(AccelStepper::HALF4WIRE, stepperPin1, stepperPin3, stepperPin2, stepperPin4);

// IR sync
#define LIMIT 100 // builtin LED trigger value
#define RXDPIN 2
#define RXAPIN 0
#define LEDPIN LED_BUILTIN
#define SYNC_INTERVAL 20
unsigned long nextSyncTimer = 0;

// time control
unsigned long lastLoopMillis = 0;
byte loopTime;

void setup() {

// IR sync
pinMode(RXDPIN, OUTPUT); 
pinMode(LEDPIN, OUTPUT); 
digitalWrite(RXDPIN, HIGH); // supply 5 volts to emitter photodiode TODO... get 5V on power? 
digitalWrite(LEDPIN, LOW); // builtin LED initially off
nextSyncTimer = millis() + SYNC_INTERVAL;

//BOF VL53L0X
// prepare address configuration
pinMode(PIN1, OUTPUT);
pinMode(PIN2, OUTPUT);
digitalWrite(PIN1, LOW);
digitalWrite(PIN2, LOW);

// start i2c
delay(500);
Wire.begin();

// start serial
Serial.begin (115200);

// sensor1 address configuration
pinMode(PIN1, INPUT);
delay(150);
//Serial.println("00");
sensor1.init(true);

//Serial.println("01");
delay(100);
sensor1.setAddress((uint8_t)22);
//Serial.println("02");

// sensor2 address configuration
pinMode(PIN2, INPUT);
delay(150);
sensor2.init(true);
//Serial.println("03");
delay(100);
sensor2.setAddress((uint8_t)25);
//Serial.println("04");

// configuration
sensor1.setTimeout(500);
sensor2.setTimeout(500);
sensor1.startContinuous();
sensor2.startContinuous();

nextSensorTimer = millis() + SENSOR_INTERVAL;
//EOF VL53L0X

// 28BYJ-48
stepper.setMaxSpeed(1500);
stepper.setSpeed(1200);

// time control
lastLoopMillis = millis();
loopTime = 0;
}

void loop() {
static int syncVal = 0;
if(millis() > nextSyncTimer) {
nextSyncTimer = millis() + SYNC_INTERVAL;
syncVal = analogRead(RXAPIN);
// BOF TODO
// just show on led for now
if(syncVal <= LIMIT) {
digitalWrite(LEDPIN, HIGH); 
} else { 
digitalWrite(LEDPIN, LOW); 
} 
// EOF TODO
}

// VL53L0X
if(millis() > nextSensorTimer) {
nextSensorTimer = millis() + SENSOR_INTERVAL;
switch(nextSensorIndex) {
case 1:
//Serial.print(sensor1.readRangeContinuousMillimeters()); Serial.print("\t");
sensor1Value = sensor1.readRangeContinuousMillimeters();
if (sensor1.timeoutOccurred()) { Serial.print(" TIMEOUT S1 "); }

nextSensorIndex++;
break;
case 2:
//Serial.print(sensor2.readRangeContinuousMillimeters()); Serial.print("\t");
sensor2Value = sensor2.readRangeContinuousMillimeters();
if (sensor2.timeoutOccurred()) { Serial.print(" TIMEOUT S2 "); }

nextSensorIndex = 1;
break;
}
// show sync value
Serial.print(syncVal); Serial.print("\t");
Serial.print(sensor1Value); Serial.print("\t");
Serial.print(sensor2Value); Serial.print("\t");
Serial.print(loopTime); Serial.print("\t");
Serial.println();
}

// 28BYJ-48
stepper.runSpeed();

// time control
loopTime = millis() - lastLoopMillis;
lastLoopMillis = millis();
}

 

Considerações sobre o protótipo do LIDAR 360

As primeiras impressoes foram positivas. A engenhoca muito rudimentar funcionou conforme esperado, mas com deficiencias também esperadas.

A engrenagem maior, se bem que com folgas e oscilante rodou, mas muito devagar. Tem muitos dentes face ao pinhão do motor de passos.

Os sensores de distancia faziam as leituras, mas todo o processo de temporização e determinação do angulo da leitura está por fazer.

O principal problema a ser trabalhado será a determinação do angulo da leitura pois a deteção do IR que estou a pensar usar para marcar a origem (o angulo zero) necessita de ser pensada de modo a eliminar as interferencias da luz, e conduzir a passagem da luz por um orificio muito pequeno, de modo a ter precisão na determinação da origem.

Ver o prótotipo seguinte do Arduino LIDAR 360 v2.