Самодельный лидар на Arduino и VL53L0X TOF-дальномере


Как работает лазерный дальномер

Способ точного бесконтактного определения расстояния с выводом данных на дисплей, представляет собой сложную электронную схему. В основе конструкции лежит излучатель, приёмник, блок измерения времени и микропроцессор, чья совокупность позволяет нам в полной мере эксплуатировать лазерный дальномер. Устройство прибора, в более детальном разборе процессорных плат и модулей, имеет приличную сеть, чья структура лежит далеко за гранью понимания среднестатистического обывателя. Даже радиолюбители, увлекающиеся электроникой, собирают дальномеры из готовых элементов при помощи пайки и программирования.

Говоря по сути, принцип работы лазерного дальномера базируется на скорости света и времени прохождения луча до поверхности и обратно. Выпущенный из излучателя лазер, отражается от первого попавшегося на пути твердого объекта (даже с большим углом преломления), и частично возвращается к устройству, где его распознает принимающий модуль и фиксирует время, потребовавшееся ему для преодоления этого расстояния. Поскольку свет перемещается со скоростью 299 792 458 метров в секунду или 29.2 сантиметров в микросекунду (мкс), то, зная затраченное на путь время, можно легко вычислить длину проделанного им пути. Таким образом, основная формула, используемая дальномерами, имеет следующий вид.

Представленный выше принцип, относиться к импульсным дальномерам, имеющим максимально широкое представление на рынке строительного инструмента. Данные приборы имеют приличную точность с погрешностью от 0.5 до 3-х мм, в зависимости от встроенного датчика приема сигнала, чья скорость обработки должна быть молниеносно быстрой.

Помимо импульсного, существует ещё фазовый способ измерения, все также основанный на лазере, но кардинально отличающийся по способу получения информации. В основе данного принципа лежит частота испускаемого лазера, которая не превышает 450 МГц (в среднем от 10 до 150). Вместо времени, здесь определяется разница фаз (исходящей и принимаемой), на основе которой рассчитывается расстояние до объекта. Фазовому дальномеру требуется больше времени для получения значения, но точность измерений превосходит импульсный.

Скетч для Arduino

#include Adafruit_VL53L0X sensor = Adafruit_VL53L0X(); //Outputs/inputs #define dirPin 3 //Pin for direction of the stepper driver #define stepPin 4 //Pin for steps of the stepper driver #define Enable 5 //Pin for enable the stepper driver //Variables int Value = 1200; //Delay value between steps float angle = 0; //Start angle /* —————-Step angle calculation—————- We need 1.5 rotations for 360�. (pully ratio 1.5 : 1) Each 200 steps the motor will make a rotation. We move 2 steps and the we make a measurement. This equals to 360�/(200steps * 1.5) * 2 = 2.4angle/loop -> —————-Step angle calculation—————-*/ float angle_step = 2.4; //So place that value here float maxdist = 400; //I’ve set the maximum distance around the sensor to only 400mm. Change to any other value. bool loop_starts = false; byte last_PIN_state; void setup() { // Declare pins as output: pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); pinMode(Enable, OUTPUT); digitalWrite(Enable, LOW); //Place enable to low so the driver is enabeled digitalWrite(dirPin, HIGH); //Place dirPin to HIGH so we spin CW Serial.begin(9600); //Start serial port sensor.begin(); PCICR |= (1 << PCIE0); //enable PCMSK0 scan so we can use interrupts PCMSK0 |= (1 << PCINT0); //Set pin «D8» trigger an interrupt on «any» state change. } void loop() { if (loop_starts) //We reset angle when the magnet is detected on D8 { angle = 0; loop_starts = false; } digitalWrite(stepPin, HIGH); //Make one step delayMicroseconds(Value); //Small delay digitalWrite(stepPin, LOW); //Make another step delayMicroseconds(Value); //Add another delay VL53L0X_RangingMeasurementData_t measure; sensor.rangingTest(&measure, false); // pass in ‘true’ to get debug data printout! if (measure.RangeStatus != 4) { int r = measure.RangeMilliMeter; if (r > maxdist) //Limit the dsitance to maximum set distance above r = maxdist; Serial.print(angle); //Print the values to serial port Serial.print(«,»); Serial.print(r); Serial.println(«,»); angle = angle + angle_step; //Increase angle value by the angle/loop value set above (in this case 2.4� each loop) } else { //phase failures have incorrect data //Serial.println(» out of range «); } } //This is the magnet detection interruption routine //———————————————- ISR(PCINT0_vect) { if (PINB & B00000001) //We make an AND with the pin state register, We verify if pin 8 is HIGH??? { if (last_PIN_state == 0) { last_PIN_state = 1; } } else if (last_PIN_state == 1) //Now verify if pin 8 is LOW??? -> Magnet was detected { last_PIN_state = 0; loop_starts = true; //If yes, we set loop_starts to true so we reset the angle value } }//End of ISR

Откройте Arduino IDE и скопируйте в него скетч. Если при загрузке скетча в плату появится сообщение, что отсутствует библиотека «Adafruit_VL53L0X.h»:

Её нужно будет установить. Для этого в меню «Инструменты» выберете пункт «Управлять библиотеками…» и в появившемся окне найдите «Adafruit_VL53L0X» (что бы сократить список, можно ввести в поле поиска «VL53»:

Для VL53L0X кроме библиотеки от Adafruit есть и от Pololu. Подключается она аналогичным образом, но код нужно немного изменить:

#include #include 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 //Outputs/inputs #define dirPin 3 //Pin for direction of the stepper driver #define stepPin 4 //Pin for steps of the stepper driver #define Enable 5 //Pin for enable the stepper driver //Variables int Value = 1200; //Delay value between steps float angle = 0; //Start angle /* —————-Step angle calculation—————- We need 1.5 rotations for 360º. (pully ratio 1.5 : 1) Each 200 steps the motor will make a rotation. We move 2 steps and the we make a measurement. This equals to 360º/(200steps * 1.5) * 2 = 2.4angle/loop -> —————-Step angle calculation—————-*/ float angle_step = 2.4; //So place that value here float maxdist = 400; //I’ve set the maximum distance around the sensor to only 400mm. Change to any other value. bool loop_starts = false; byte last_PIN_state; void setup() { Serial.begin(115200); Wire.begin(); // Declare pins as output: pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); pinMode(Enable, OUTPUT); digitalWrite(Enable, LOW); //Place enable to low so the driver is enabeled digitalWrite(dirPin, HIGH); //Place dirPin to HIGH so we spin CW 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 PCICR |= (1 << PCIE0); //enable PCMSK0 scan so we can use interrupts PCMSK0 |= (1 << PCINT0); //Set pin «D8» trigger an interrupt on «any» state change. //See interrupt vector below the void loop } void loop() { if (loop_starts) //We reset angle when the magnet is detected on D8 { angle = 0; loop_starts = false; } digitalWrite(stepPin, HIGH); //Make one step delayMicroseconds(Value); //Small delay digitalWrite(stepPin, LOW); //Make another step delayMicroseconds(Value); //Add another delay int r = sensor.readRangeSingleMillimeters(); //Get distance from sensor if (r > maxdist) //Limit the dsitance to maximum set distance above { r = maxdist; } Serial.print(angle); //Print the values to serial port Serial.print(«,»); Serial.print(r); Serial.println(«,»); angle = angle + angle_step; //Increase angle value by the angle/loop value set above (in this case 2.4º each loop) } //This is the magnet detection interruption routine //———————————————- ISR(PCINT0_vect) { if (PINB & B00000001) //We make an AND with the pin state register, We verify if pin 8 is HIGH??? { if (last_PIN_state == 0) { last_PIN_state = 1; } } else if (last_PIN_state == 1) //Now verify if pin 8 is LOW??? -> Magnet was detected { last_PIN_state = 0; loop_starts = true; //If yes, we set loop_starts to true so we reset the angle value } }//End of ISR

В коде для обоих библиотек, в самом начале цикла loop мы проверяем, не сработал ли датчик Холла (в прерывании для этого переменной loop_starts устанавливается значение true) и, если сработал, устанавливаем переменной angle значение 0. Если у вас магнит находится не центру под датчиком, присвойте этой переменной соответствующее число.

Далее в коде отправляем команду драйверу мотора провернуть вал на один шаг, небольшая пауза с помощью delayMicroseconds, затем опять проворачиваем вал на один шаг и опять пауза.

После этого вызываем функцию измерения расстояния и проверяем, считал ли датчик корректные данные. При получении корректных данных от датчика, полученные данные о расстоянии присваиваются переменной r. Затем происходит проверка, выходит ли измеренное расстояние за установленные границы (переменная maxdist) и, если выходит, переменной r присваивается значение maxdist.

В конце цикла в последовательный порт выводятся полученные данные и к текущему значению переменной angle прибавляется значение переменной angle_step (в данном коде это 2.4, т.е. 2.4 градуса). Если у вас шаговый мотор с другим шагом, будете использовать режим микрошага, измените размеры шкивов или будете делать не два, а один, три или ещё сколько-то шагов, не забудьте пересчитать на какой угол будет вращаться датчик и присвоить переменной angle_step соответствующее значение.

Неисправности лазерного дальномера

Производство электронных измерительных приборов, подразумевает высочайшую точность сборки с обязательным контролем качества каждого изделия. Сложную конструкцию лазерных рулеток, стараются максимально изолировать от контакта с внешней средой и обезопасить от грубого физического воздействия. Поскольку эксплуатация устройств зачастую проходит в условиях повышенной опасности (в мастерских, на производствах или стой-площадках), они нередко подвергаются ударам и сильным вибрациям, способным нанести фатальный ущерб мельчайшим узлам устройства.

Читать также: Тиристорный регулятор мощности схема на 12 вольт

Несмотря на общий принцип действия лазерных дальномеров, они зачастую имеют уникальный набор компонентов и программного обеспечения. Даже если корни неисправности будут схожими, то конструкция самой детали или схемы будет индивидуальной для каждой отдельно взятой модели. Проблемы физического характера, могут быть связаны с расфокусировкой лазерного луча, изломом откидной скобы, деформацией кнопок или корпуса. При желании и умелых руках, подобные дефекты можно устранить самостоятельно.

Ремонт электронных компонентов требует куда более специфичных навыков, и даже специального образования. Неисправности такого рода, часто выражаются в проблемах с включением устройства, дисплеем, приёмником сигнала, определением заряда батареи. Количество дефектов, пропорционально функционалу, которым оснащен конкретный дальномер. Ремонт прибора своими руками, в случае неисправной электроники, не удастся выполнить без определенных познаний, и лучше будет отнести его в специализированный сервис на диагностику.

Рулетка с мерной лентой

Это самый доступный инструмент, который имеется в рабочем комплекте практически у каждого мастера.


Он имеет простое устройство и нехитрые приспособления, которые незаметны на первый взгляд. Поэтому не все владельцы о них знают.

Особенности конструкции

Общий вид

С лицевой стороны корпуса расположены:

  • мерная лента с наконечником;
  • ремешок;
  • кнопка фиксации ленты.

Ремонт лазерного дальномера

Если повреждения несут в основном физический характер, а электроника работает исправно, прибор можно восстановить самостоятельно, при наличии желания и смекалки. В первую очередь необходимо установить источник проблемы, исходя из имеющегося дефекта. В данной теме, мы рассмотрим 2 случая поломок на конкретных моделях, и приведем рекомендации по их устранению.

В качестве первого пациента выступает дальномер Bosch DLE 50, с поврежденной фокусировкой луча в следствии падения со 2-го этажа. Вместо сконцентрированной точки, лазер принял форму фонарика с размытым пятном света. Измерительная способность устройства сократилась до 70 см, и при попытке измерения больших расстояний дисплей отображает ошибку “Error”. Задача заключается в калибровке фокусирующей линзы по отношению к измерительному каналу. Все элементы расположены внутри корпуса, поэтому разбирать необходимо.

Вполне вероятно, что производители модели Bosch DLE 50, исключили надобность в самостоятельном ремонте ещё на стадии проектирования. Корпус прибора, имеет всего 3 внешних резьбовых соединения (2 под батарейками и 1 на откидной скобе), в то время, как остальные элементы спаяны или приклеены. Разумеется, в гарантийном сервисе, разборка и сборка подобного монолита происходит без проблем, однако в быту этот процесс может вызвать затруднение. Потребуется паяльник, для отсоединения контактов питания, и термофен, для снятия приклеенной клавиатуры. Все соединительные элементы, представлены на приведенных ниже фотографиях, в порядке разборки инструмента.

Добравшись до линзы и блока привода штоки, можно приступать к фокусировке. Для этого отмеряем расстояние от 5 до 15 метров (чем больше, тем лучше), и в конце дистанции, располагаем ровный объект с хорошим отражением. Подключаем лазер к источнику питания (преобразователю) и начинаем аккуратно шевелить линзу, пока пучок света не примет вид точки. Процесс настройки достаточно кропотливый и стоит запастись терпением. При достижении оптимальной фокусировки, линзу следует зафиксировать термоклеем. Таким образом, можно продлить срок службы дальномеру с поврежденным лазером.

В качестве второго примера, рассмотрим поломку откидной скобы прибора того-же бренда “Bosch”, по уже под маркой “GLM 80”. Пластиковый элемент сломан пополам и подлежит замене. Крепление скобы к инструменту осуществляется винтом, поэтому процесс извлечения старой и установки новой детали, не составит труда. Загвоздка заключается в поиске и приобретении замены. Можно заказать новый крепежный комплект, который обойдется порядка 400 рублей (для данной модели), и с большой вероятностью будет доступен в крупных мегаполисах.

Альтернативным вариантом будет изготовление детали посредством печати на 3D-принтере. В таком случае, требуется провести точные измерения всех граней скобы и создать трехмерную модель в программе “Tinkercad” или ей подобной. Если у вас нет опыта моделирования, можно отнести лист с измерениями и сломанную деталь в ближайший сервис, где предоставляют услуги 3D-печати. Качество подобного изделия сравнимо с обычным гибким пластиком, чего вполне хватает для выполнения поставленных задач.

В большинстве случаев, ремонт лазерных дальномеров требует индивидуального подхода к каждой отдельно-взятой поломке. Разбор всех возможных неполадок займет объем стандартного учебника, что не возможно уместить в одну статью ознакомительного характера. Если вы хотите определить причину или узнать способ устранения поломки, изложите симптомы устройства к комментариях ниже. Наш мастер обязательно подскажет, где и как следует разбираться. Если же вы не уверены в своих навыках или терпении, то лучше всего будет обратиться в специализированный сервис.

Схема

Схема проста, часть деталей запаивается на макетной плате.

Через скользящие контакты от Arduino к датчику VL53L03X подключаются контакты +5В, земля и две линии интерфейса I2C (SCL и SDA). К датчику Холла подключается земля, +5В и вывод D8 от Arduino. Также между +5В и D8 устанавливается резистор на 10кОм.

На повышающего преобразователя подаётся 5В. На плате построечным резистором устанавливается выходное напряжение примерно 12В. Эти 12В с выхода стабилизатора подключаются к выводам «питание мотора» модуля драйвера моторов. Так же по линии 12В устанавливается электролитический конденсатор, который нужен что бы драйвер мотора работал без сбоев (на плате его может не быть совсем, а даже когда запаян керамический или танталовый конденсатор, его ёмкости обычно недостаточно). 5В подключается к выводам «питание логики» драйвера моторов. Не перепутайте, где выводы «питание логики» и «питание мотора», иначе драйвер может выйти из строя.

Платы бывают разные, иногда плюс питания для мотора обозначается, допустим надписью VMOT, а плюс питания логики обозначаться как VCC. Выводов GND на плате может быть один или несколько, в данном случае это не имеет значения.

Выводы STEP, DIR и EN от драйвера моторов подключаются к Arduino, а выводы RESET и SLEEP соединяются между собой.

На платах с драйвером моторов A4988 обычно запаян подстроечный резистор, им настраивается ограничение по току для шагового мотора. Ограничение тока для шаговых моторов очень желательно настроить. Если ограничить ток слишком сильно, мотор под нагрузкой или не сможет вообще проворачивать вал или будут пропуски шагов. Если задать слишком большой ток и источник питания способен будет его обеспечить, мотор будет греться или его обмотки просто сгорят. Так же это абсолютно ненужная нагрузка на источник питания. При питании от аккумулятора это приведёт к тому, что он будет быстрей разряжаться. При питании от USB (блока питания, порт компьютера или ноутбука и т.д.) в лучшем случае будет просто лишняя нагрузка, в худшем, когда блок питания или порт не рассчитан на такой ток и нет защиты, это даже может привести к выходу из строя блока питания или порта.

Вот и все. В качестве источника питания используется USB-кабель, подключенный к Arduino NANO.

Датчик VL6180X

VL6180X – это оптический датчик от компании STMicroelectronics. Его также называют датчиком света (освещенности) и приближения. Его внешний вид показан на следующем рисунке.

Датчик VL6180 содержит ИК-излучатель, датчик внешней освещенности и датчик дальности. К микроконтроллерам и другим электронным устройствам он подключается по интерфейсу I2C. Также датчик имеет встроенный стабилизатор напряжения 2,8 В, поэтому он не повредится если подключить к нему напряжение больше 2,8 В (ну в пределах разумного, конечно же). Еще в датчике присутствуют два программируемых вывода GPIO. Распиновка датчика показана на следующем рисунке.


VL6180X в отличие от других подобных датчиков содержит в своем составе точные часы для измерения времени пролета светового потока, что позволяет ему обеспечивать значительно большую точность измерений по сравнению с другими аналогичными датчиками. Это также делает его практически невосприимчивым к шуму.

Датчик VL6180X способен измерять расстояния до 25 см. Поэтому, к примеру, в домашнем использовании он отлично подойдет для измерения фокусного расстояния камеры или фотоаппарата. Если же вам необходим лидар, работающий на большие расстояния, то в данном случае вам вместо датчика VL6180X необходимо использовать датчик Vl53l0x, который также отличается большей точностью измерений и не имеет проблем с линейностью, приводящих к “двойному изображению”.

Рейтинг
( 1 оценка, среднее 4 из 5 )
Понравилась статья? Поделиться с друзьями:
Для любых предложений по сайту: [email protected]