Парковочный ассистент в гараже я собирал на HC-SR04: машина подъезжает, ультразвук меряет дистанцию, зуммер пищит чаще. Работало ровно до первого дождя. Мокрый брезент съедал эхо почти целиком, торчащий из стены кронштейн ловился раньше самой машины, а показания плясали на пару сантиметров от замера к замеру. Половину вечера я двигал порог — и так ничего не вылечил: у звука свои отношения с материалами и воздухом, и никакой порог их не перепишет.
В этом уроке — противоположный подход к той же задаче: VL53L0X, лазерный дальномер от STMicroelectronics на принципе времени пролёта фотона. Разберём, как чип делает замер за 20-33 миллисекунды, почему свету всё равно, какая на улице температура, где у него адрес 0x29 и потолок 2000 мм, за что я недолюбливаю его после длинных проводов — и в каких задачах он честно сильнее ультразвука, а в каких внезапно хуже. Модуль стоит дешевле двух обедов, а времени экономит больше, чем любой из моих калибровочных вечеров.
Время пролёта фотона против эха звука
Идея у обоих дальномеров одна: послать импульс, дождаться отражения, посчитать время. Дальше начинается разница. HC-SR04 гонит звук: 343 метра в секунду при двадцати градусах, и эта скорость ползёт вместе с погодой — на морозе минус десять она падает до 325, на жаре плюс тридцать растёт до 349. Пять процентов ухода без всякой компенсации — вот откуда пляшущие сантиметры. VL53L0X выпускает невидимый импульс инфракрасного лазера с длиной волны 940 нм, и матрица фотодетекторов SPAD ловит момент, когда фотоны вернулись. Чип измеряет время пролёта напрямую и умножает его на константу: скорость света не зависит от влажности.
Итог по цифрам: замер занимает 20-33 мс, шаг показаний — 1 мм, паспортная дальность — до 2000 мм, но с оговоркой ST: в темноте. На ярком солнце приёмник слепнет от засветки, и честный потолок опускается — у меня на подоконнике в июле дальномер уверенно видел чуть больше метра. Ультразвуковую механику с эхом и пересчётом 58 микросекунд на сантиметр я разбирал в уроке про HC-SR04 — там же о том, откуда у pulseIn берётся дрожь в показаниях.
На шине дальномер сидит на адресе 0x29 — третьем по частоте в моей коллекции после 0x27 у LCD и 0x68 у часов. Адрес зашит на заводе: чип отвечает на 0x29 после каждой подачи питания. Сменить его можно программно, но живёт новый номер ровно до первого выключения — о двух дальномерах на одной шине скажу отдельно ниже. После пайки модуля на плату прогоните сканер адресов: тридцать секунд кода показывают, слышна ли микросхема вообще, а таблица адресов типовых модулей подскажет, кто из соседей по макетке с кем ссорится. С питанием аккуратнее: сам чип хочет 2,6-3,5 В, но модули вроде GY-VL53L0X несут на борту стабилизатор и принимают пять вольт от Uno напрямую. Уровни SDA и SCL у голого чипа трёхвольтовые — если ваш модуль без согласования, освежите правила стыковки 3,3 и 5 вольт.
Отдельная тема — скорость шины. Дальний замер с полной точностью живёт на стоковых ста килогерцах: поднимая частоту до четырёхсот, вы выигрываете миллисекунды и рискуете стабильностью на длинных хвостах. Я оставляю стоковые сто и добавляю паузы между замерами, а не гонку — дальномер всё равно делает свою работу без меня.
#include <Wire.h>#include <VL53L0X.h> VL53L0X sensor; void setup() { Serial.begin(9600); Wire.begin(); sensor.setTimeout(500); // предел ожидания ответа, мс if (!sensor.init()) { Serial.println("VL53L0X molchit: prover SDA/SCL i XSHUT"); while (true) {} } sensor.startContinuous(100); // замер каждые ~100 мс} void loop() { Serial.print("mm="); Serial.print(sensor.readRangeContinuousMillimeters()); if (sensor.timeoutOccurred()) { // шина молчала Serial.print(" TIMEOUT"); } Serial.println(); delay(200);}Библиотека Pololu — самая тонкая из обёрток: init() поднимает чип, setTimeout() ставит предел ожидания, startContinuous() запускает цикл измерений, а readRangeContinuousMillimeters() отдаёт готовые миллиметры. Ловушка прячется в возвращаемом значении: если замер не состоялся, функция вернёт 8193 — специальный маркер, а не реальную дистанцию. Отдельно проверяйте timeoutOccurred(): метод честно скажет, что шина молчала, и 8193 значит именно это. Я пару раз принимал 8193 за «цель на восемь метров» — не повторяйте мой подвиг. Одиночный замер через readRangeSingleMillimeters() сообщает о провале тем же числом: формат тот же, скорость ниже, смысла в нём меньше.
Где лазер выигрывает, а где проигрывает
| VL53L0X | HC-SR04 | |
|---|---|---|
| Принцип | время пролёта света, лазер 940 нм | эхо ультразвука 40 кГц |
| Дальность и темп | до 2000 мм в темноте, замер 20-33 мс | от 2 см до ~4 м, замер от 20 мс |
| Шаг показаний | 1 мм | паспортные 3 мм плюс дрейф от температуры воздуха |
| Слепое место | чёрный матовый материал: свет поглощается целиком | ткань, поролон, наклонные поверхности: эхо уходит в сторону |
Узкий луч — и сила, и слабость лазера. Конус VL53L0X прижат, поэтому мимо цели он не промахивается: тонкий провод, край полки, палец — честные мишени, на которых ультразвук с его широким конусом отдаёт среднюю температуру по больнице. Взамен появляются свои невидимки: чёрный матовый материал съедает свет целиком, и чип ответит 8193 или завышенным числом. Зеркало и гладкий пол под острым углом уводят отражение мимо приёмника — эффект тот же, что у звука, только предсказуемее. Ещё одна хитрость: на глянце показания врут сильнее, чем на шершавой тёмной резине — отражательность важнее цвета. Мой практический вывод: для узких мишеней, миллиметровой точности и уличных перепадов температур беру ToF; для мягких тканей и пыльных поверхностей ультразвук ещё не сдался.
Практика — где ToF у меня прижился, а где лежит в ящике. Робот-поливальщик объезжает горшки: тонкие пластиковые опоры ультразвук не слышал вовсе, лазер видит с полуметра. Датчик бумаги в лотке принтера, счётчик проездов в турникете, парковочный «стоп» с шагом в сантиметр — всё это про узкий луч и миллиметровый шаг. Опрос при этом не блокирует loop: замер уже идёт сам, остаётся забирать готовые миллиметры раз в сто — общий приём неблокирующей логики разобран в уроке про millis вместо delay. Куда я ToF не ставлю: ёмкости с сыпучим — пыль ложится на окошко за неделю, и чип начинает видеть собственное стекло.
- 1. Чем VL53L0X меряет расстояние в принципе?
- 2. На каком адресе VL53L0X отвечает по умолчанию?
- 3. Паспортные 2000 мм дальномер выжимает в темноте. Что будет на ярком солнце?
- 4. readRangeContinuousMillimeters вернул 8193. Что это чаще всего значит?
- 5. Какая цель выпадет из поля зрения ультразвука, но увидится VL53L0X?
- Принцип — время пролёта фотона: лазер 940 нм и матрица SPAD, скорость света от погоды не зависит.
- Адрес по I2C — 0x29 после каждой подачи питания; программная смена адреса живёт до перезагрузки.
- readRangeContinuousMillimeters() отдаёт миллиметры до 2000, а 8193 — маркер несостоявшегося замера.
- Замер занимает 20-33 мс; на ярком солнце дальность проседает из-за засветки приёмника.
- Длинные провода — главный убийца шины: укорачивать, снижать частоту, ресетить через XSHUT.
Частые вопросы по теме урока
- Чем VL53L0X меряет расстояние в принципе?
- Чип выпускает импульс инфракрасного лазера 940 нм и засекает, когда фотоны вернутся: время умножается на скорость света и делится пополам. Ни звука, ни силы сигнала в формуле нет, а шаг показаний — 1 мм. Временем пролёта собственного светового импульса до цели и обратно
- На каком адресе VL53L0X отвечает по умолчанию?
- Фабричный адрес 0x29. Его можно сменить программно, но после снятия питания чип снова отвечает на 0x29 — учитывайте при двух дальномерах на одной шине. 0x29
- Паспортные 2000 мм дальномер выжимает в темноте. Что будет на ярком солнце?
- Два метра в паспорте ST даёт для темноты; на ярком свету приёмник слепнет, и честный потолок опускается. На моём подоконнике в июле это было чуть больше метра. Проверяйте датчик в тех условиях, где ему предстоит работать. Засветка приёмника укорачивает достоверную дальность
- readRangeContinuousMillimeters вернул 8193. Что это чаще всего значит?
- 8193 — маркер несостоявшегося замера: библиотека не дождалась ответа за отведённый таймаут. Проверяйте timeoutOccurred() и провода, а не показания. Замер не состоялся: сработал таймаут библиотеки
- Какая цель выпадет из поля зрения ультразвука, но увидится VL53L0X?
- Ультразвуку нужна акустическая мишень: тонкий провод отражает слишком мало энергии в сторону приёмника, а широкий конус звука добавляет путаницы. Узкому лазерному пятну маленькая цель по плечу — здесь ToF выигрывает. Тонкий провод диаметром 3 мм на фоне стены