Реверс-инжиниринг лазерного сканера Leuze RS4

в 7:00, , рубрики: diy или сделай сам, Infineon, laser scanner, leuze, TDC, TOF, лазерный дальномер, реверс-инжиниринг, схемотехника, Электроника для начинающих

Реверс-инжиниринг лазерного сканера Leuze RS4 - 1
Ранее я уже рассказывал о реверс-инжиниринге лазерного датчика расстояния. В этот раз речь пойдет о более сложном устройстве — лазерном сканере Leuze RS4. Как и датчик, этот сканер попал ко мне в сломанном состоянии, так что пришлось заняться восстановлением его работы, и в процессе улучшить некоторые его характеристики, и, фактически, переделать его в другое устройство.

Что же представляет из себя этот лазерный сканер?

Leuze RS4 — лазерный сканер безопасности, то есть он предназначен для предотвращения попадания людей в опасные зоны на производстве, для предотвращения столкновений производственных транспортных средств и т. д. Он имеет довольно приличные характеристики — максимальная дальность: 15/50м (в зависимости от режима работы), точность измерения расстояния во всем диапазоне измерений — 5мм, угловое разрешение — 0.36 градусов, скорость сканирования — 25 об/сек (25000 измерений/сек).
Стоит отметить, что этот сканер позиционируется именно как устройство обеспечения безопасности — то есть он хранит в памяти расположение зон тревоги и предупреждения, и при попадании объекта в эти зоны в сканере размыкается один из ключей. Для настройки расположения зон сканер можно подключить к компьютеру, и наблюдать на экране расположение препятствий. Есть даже пакет для ROS, позволяющий получать данные с этого сканера.
Мне сканер достался без корпуса, разобранный на составные части. Сканер вышел из строя из за сильного удара по корпусу; что конкретно в нем перестало работать, я так и не понял — возможно, разъюстировалась оптика, отошел контакт в одном из разъемов или сдвинулся датчик энкодера, либо еще что-то. Я пробовал собрать все части вместе, сканер виделся в родном ПО, но сканирование не запускалось. Так что у меня остался только один способ запустить его — максимально полно восстановить схему сканера, и написать свою прошивку микроконтроллера сканера.
Вот как выглядели те части, что были у меня:
image
Вот так они должны располагаться в корпусе (фотография из документации, видно, что конструкция и электроника немного отличаются):
image
Также важной частью сканера является сканирующее зеркало (выделено синим на фотографии выше), установленное в его центре:
image

Структурная схема сканера:
image

Как видно из схемы, вся электроника сканера состоит из отдельных модулей (плат), соединенных разъемами и шлейфами.
Модулей достаточно много — модуль питания (DC-DC), интерфейсный модуль, модуль процессора, модуль фотоприемника (APD), модуль лазера. Кроме того, есть еще модуль энкодера и две подковообразных платы, поначалу показавшиеся странными.

В первую очередь стоит обратить внимание именно на них:
image
Очевидно, что одна из плат содержит светодиоды, а вторая — фотодиоды. Изначально я думал, что это некая разновидность энкодера, или какой-то механизм для проверки лазерного излучения. Однако позже, почитав документацию на сканер, и подробно рассмотрев фотографии в ней, я понял, что это система контроля состояния поверхности защитного стекла сканера.
На фотографии видны отверстия для светодиодов:
Реверс-инжиниринг лазерного сканера Leuze RS4 - 7
Измеряя уровень сигнала с фотодиодов, можно оценить уровень пропускания защитного стекла. Очевидно, что эта система не критична для работы сканера, так что я не стал использовать эти платы в дальнейшем.

Модуль процессора — наиболее сложная часть сканера.
Так выглядит электроника модуля с двух сторон:
image
Впервые взглянув на плату, я сразу понял, что в сканере используется времяпролетный метод измерения расстояния (TOF) — микросхемой с самой крупной маркировкой оказалась "ACAM TDC-GPX", про которые я уже слышал ранее. TDC — «Time-to-Digital Converter», то есть специализированная микросхема, предназначенная для измерения временных интервалов с очень высокой точностью, именно она и используются для измерения времени «полета» импульса лазерного излучения.
Также на плате был микроконтроллер Infineon С167 с микросхемой внешней FLASH памяти (что радовало) и ASIC (что сильно огорчало). Более подробно об этом модуле я расскажу ниже.

Модуль питания содержит некий заказной гальванически развязанный DC-DC преобразователь с несколькими напряжениями на выходе и несколько конденсаторов:
image
Напряжение питания преобразователя — 24В. Основная его особенность — на отдельный маленький разъем он выдает высокое напряжение (~230В), необходимое для работы лазера и фотоприемника.
Также он выдает на основной разъем следующие напряжения: +5В, -5В, ~15В, гальванически развязанные от остальных +5В для интерфейса RS232.

Оптическая часть сканера
image
С первого взгляда на оптику сканера не очень-то понятно, где что. В данном случае маленькое окошко с зеркалом в центе фотографии служит для вывода лазерного луча, а большая блестящая поверхность вокруг него является поверхностью интерференционного светофильтра, установленного перед объективом фотоприемника. Этот светофильтр пропускает только то излучение, длина волны которого близка к длине волны лазера.
Вот так это показано в документации сканера:
Реверс-инжиниринг лазерного сканера Leuze RS4 - 11
Сам объектив установлен внутри кожуха из черной пластмассы, так что увидеть его проблематично. На торце этого кожуха, противоположном тому, что видно на фотографии выше, закреплены модуль лазера и фотоприемника:
image

Модуль лазера
Вид модуля лазера (часть деталей промаркированы мной в процессе рисования схемы):
image
Как видно, схемотехника этого модуля достаточно простая, так что я смог полностью восстановить его схему:
image
Крупная круглая деталь на плате — специализированный лазерный излучатель. К сожалению, никаких маркировок на нем не было, так что никакой документации на него найти не удалось.
Из описания на сканер можно узнать — «Laser light wavelength — 905 nm», «Laser class — 1», «Pulse duration — 0.003 µs», «Repetition frequency — 25 kHz».
Что удалось понять, восстановив схему модуля, и проанализировав его работу:

  • На лазерный излучатель постоянно подается питающее напряжение 143 В, ограниченное стабилитронами.
  • Запуск излучателя происходит по переднему фронту импульса, подаваемого на вход «3» модуля. Насколько я понял, длина импульса может быть произвольной, модуль сам сформирует короткий импульс.
  • Излучатель содержит фотодатчик, на выходе которого появляется импульс в тот момент, когда лазер реально включается. Сигнал от него используется в качестве опорного (стартовый импульс) при измерении времени «полета» .

Все управление лазером ведется по одной линии — «LASER_PULSE». Большую часть времени на линии должен быть «высокий» уровень. При подаче отрицательного импульса по его переднему фронту сбрасывается в 0 триггер DD1, а по заднему — триггер начинает «ждать» сигнал с фотодиода и запускается лазер. При появлении сигнала с фотодиода триггер переключается в 1.
Можно заметить два коаксиальных провода, при помощи разъемов подключенных к модулю. Именно они используются для передачи дифференциального сигнала от триггера к микросхеме TDC.

Также на этом модуле установлены пять светодиодов. Управляет ими модуль процессора.

Модуль фотоприемника
Сам модуль выглядит вот так:
image

Фотография самого фотоприемника вблизи:
image
Знак высокого напряжения в углу платы явно показывает, что здесь используется лавинный фотодиод (APD) — для работы им требуется достаточно высокое напряжение.
К сожалению, на корпусе фотоприемника не было никаких видимых маркировок. По эмблеме на самом фотодиоде (в центре) удалось только определить, что он изготовлен компанией Pacific Silicon Sensor (First Sensor), однако больше никакой информации о нем не было, возможно, он является заказным. Из фотографии видно, что этот фотоприемник — гибридный, т.е. содержит встроенный усилитель — его хорошо видно над фотодиодом. Очевидно, что усилителю и фотодиоду нужно питание — оно подводится через нижние выводы (к ним припаяны конденсаторы). Большой загадкой была мелкая деталь слева от фотодиода, к которой идут три проводника. Дальнейшее исследование показало, что это аналоговый термодатчик.
Этот модуль значительно сложнее предыдущего, в нем использована многослойная печатная плата — не менее 4 слоев, при этом большая часть сигнальных линий расположены на внешнем слое платы, что сильно облегчает ее анализ. В этом модуле я восстановил около 80% схемы, оставшаяся часть мне была не особо нужна.
Получившаяся схема модуля фотоприемника:
image
Вверху схемы расположен регулируемый линейный источник высокого напряжения для лавинного фотодиода. Он может формировать стабильное напряжение как минимум до 150 В. Этот источник управляется при помощи ЦАП DA1 (LTC1451).

Поскольку основа сканера — импульсный дальномер, то основная задача модуля фотоприемника — максимально быстро обнаружить достаточно слабый сигнал лазера, отраженный от препятствия. Поскольку уровень светового сигнала очень мал, то его можно обнаружить только при помощи лавинного фототодиода, который обладает собственным усилением. В данном случае сигнал с фотодиода дополнительно усиливается встроенным в фотоприемник интегральным усилителем. За счет того, что усилитель встроен в корпус фотоприемника, уменьшается влияние помех на полезный сигнал. Сформированный фотоприемником сигнал (OUT_B) передается на некую микросхему DA4, которая, судя по всему, является еще одним высокочастотным усилителем. После нее сигнал передается на прямой вход высокоскоростного компаратора D1 (MAX9601). На инверсный вход этого компаратора подается опорный сигнал с резисторного делителя (около 50 мВ).
Сигнал на выходе компаратора — дифференциальный, он передается по коаксиальным проводом прямо на плату модуля процессора.

Кроме того, сигнал с выхода усилителя DA4 передается на некую разновидность пикового детектора, который «запоминает» максимальный уровень принятого импульса. Я не стал восстанавливать схему этого узла, и нарисовал на схеме только его выходной каскад (микросхема U1), сигнал с которого также передается на модуль процессора.

Одна из наименее понятных для меня частей сканера — транзистор Q3, установленный на выходе ВЧ усилителя. Судя по схемотехнике, он нужен для включения ослабления сигнала на выходе усилителя. Этим транзистором можно управлять при помощи сигнала с платы процессора (line10 — «digi»).

Можно заметить, что на плате имеется микросхема EEPROM. Все сигнальные выводы этой микросхемы соединены с платой процессора. Судя по всему, в этой микросхеме хранились некие параметры, уникальные для каждой платы фотоприемника, и записываемые в нее при тестировании платы. В частности, это может быть кривая зависимости усиления APD от напряжения питания, зависимость напряжения на выходе термодатчика от его температуры, и другие подобные характеристики.

Можно видеть, что питанием фотоприемника можно управлять, устанавливая определенные уровни на линиях CLK, CS, CS2, связанных с ЦАП и EEPROM.

Плата содержит несколько цепей, предназначенные для контроля ее состояния. Можно контролировать уровень напряжения APD, его температуру (line7) и порог срабатывания компаратора. Эти напряжения преобразовываются операционными усилителями DA3-DA5 и передаются на плату модуля процессора.

Возвращаясь к модулю процессора
image
Этот модуль — самый сложный из всех, он содержит большое число многовыводных микросхем, печатная плата опять же четырехслойная, причем большая часть сигнальных линий разведены во внутренних слоях, что заметно усложняет восстановление схемы.
Очень часто оказывалось так, что дорожки переходили на другую строну платы. Для того, чтобы быстро искать, куда же подключена определенная дорожка, пришлось использовать вот такую щетку, подключенную к мультиметру (находящемуся в режиме прозвонки):
image
Я восстановил около 70% схемы — остальное мне не было особо нужно.
Структурная схема модуля процессора:
image

Получившаяся схема модуля процессора:
image
Несмотря на то, что я везде называю этот модуль «модулем процессора», в действительности его основой является микроконтроллер Infineon SAK-C167CR-L33M. Он имеет 144 вывода, и построен по достаточно старой архитектуре C166. Этот микроконтроллер не имеет собственной энергонезависимой памяти — к нему обязательно нужно подключать внешнюю память по параллельной шине. В сканере для этих целей установлена микросхема Flash-памяти M29F400B (512K x 8 / 256K x 16). Также к микроконтроллеру подключены две микросхемы ОЗУ — IS61C6416AL-12 (64K x 16) и K6R4016C1D (256K x 16).
Можно заметить, что шина адресов подключена ко всем микросхемам памяти со сдвигом в один разряд — линии A0 памяти соединены с линией A1 микроконтроллера. Это связано с тем, что адреса выставляются на шине адреса в байтах, но сам контроллер и память — 16-битные. Для того, чтобы контроллер мог записывать в ОЗУ одиночные байты, не затрагивая соседние байты в 16-битном слове, микросхемы памяти имеют специальные линии UBn, LBn. Такое решение очень часто встречается в устройствах с параллельными шинами и подробно описано в документации на контроллер.

А вот другое решение в модуле процессора так и не стало мне полностью понятным. Если посмотреть на микросхему Flash-памяти U1, можно заметить, что линия A14 микросхемы подключена к земле. Соответствующая ей линия шины адреса контроллера A15 совсем не подключена к микросхеме. В результате получается, что контроллер имеет доступ лишь к половине Flash-памяти. Полностью аналогичная ситуация и с микросхемой RAM2 (DD3).
С микросхемой RAM1 (DD2) ситуация несколько другая — линия контроллера A15 к ней тоже не подключена, но при этом все адресные входы этой микросхемы соединены с шиной адреса, так что контроллер имеет доступ ко всей памяти микросхемы.

А теперь стоит обратить внимание на узел на логических элементах DX1, DX2, DD4. Именно эти микросхемы определяют, какая из микросхем памяти выбрана микроконтроллером. Видно, что они управляются следующими сигналами:

  • WRn — сигнал записи, активный уровень — низкий. На этой линии микроконтроллер устанавливает низкий уровень, когда нужно записать некие данные во внешнюю RAM память
  • A15 — та самая линия шины данных, что не подключена напрямую ни к одной из микросхем пямяти.
  • CSn0 — специализированный сигнал выбора микросхемы, активный уровень — низкий. Эта линия соединена со встроенным в контроллер дешифратором адреса. После сброса контроллера находится в низком уровне.
  • RAM2_CE — соединен с GPIO контроллера с подтяжкой к земле.

Логику работы этого узла хорошо описывает таблица:
image
Как видно, в зависимости от состояния линии RAM2_CE, микроконтроллер будет работать либо с Flash памятью, либо с микросхемой RAM2 (DD3), причем адресные пространства у них совпадают. Стоит заметить, что объем памяти этих микросхем одинаков. Возможно, это сделано для упрощения обновления прошивки устройства. Есть другой вариант — установленная RAM работает в 3 раза быстрее Flash памяти, так что после старта контроллер может копировать содержимое FLASH в RAM2, после чего программа выполняется из нее.

А вот высокий уровень на линии A15 явно определяет, что контроллер будет работать с микросхемой RAM (DD2).
В результате получается, что FLASH и RAM1 память чередуются в адресном пространстве контроллера:
image
Красным выделена та область RAM, которая уже встречалась ранее — при обращении к ней контроллер в реальности получит доступ к данным, расположенным по адресам (0x8000-0xFFFF).
Настройка компилятора при этом нетривиальна, и, как я уже упоминал выше, половина объема Flash/RAM2 теряется. Почему разработчики сканера не сделали переключение между микросхемами FLASH и RAM при помощи специализированной линии CSnX контроллера — непонятно.

Как я уже упоминал, в использованном контроллере нет Flash-памяти, а значит, и Fuse-битов. Для того, чтобы настроить некоторые параметры контроллера: ширину шины данных и адреса, параметры PLL используются Pull-Down резисторы, соединяемые с шиной данных. Сам контроллер имеет встроенные Pull-Up резисторы большого сопротивления (>100 КОм), соединенные со всей шиной. Таким образом, за счет внешних резисторов на шине устанавливается определенная комбинация сигналов, которую контроллер считывает при включении. Именно она определяет нужные настройки контроллера.
В данном случае речь идет про резисторы R3-R6. Выбранная конфигурация резисторов согласуется с получившейся схемой соединений шинных сигналов и обеспечивает тактовую частоту работы контроллера — 33 MHz.

Импульсный сигнал от энкодера зеркала подается на вход таймера «T2IN» микроконтроллера через логический элемент ИЛИ D6. Второй вход этой микросхемы соединен с GPIO контроллера, что позволяет отключить подачу импульсов на вход таймера. Зачем нужно такое решение, и почему нельзя программно выключить таймер — я так и не понял.

Теперь стоит обратить внимание на микросхему TDC (DD1).
В сканере установлена микросхема TDC-GPX — наиболее «продвинутая» из всех, что есть в ассортименте компании ACAM. Заявляемая точность измерения временных интервалов — до 10 пс RMS. Микросхема имеет 8 входных каналов LVTTL линий и 2 канала LVECL (дифференциальные).
В этом сканере для получения максимальной точности измерения времени используются именно LVECL входы, на которые при помощи четырех коаксиальных кабелей подаются сигналы с модуля лазера и модуля фотоприемника. Сигналы от модуля лазера подаются на входы DStart/DStartN, и запускают счет времени. Сигналы от модуля фотоприемника подаются на входы DStop1/DStop1N, DStop2/DStop2N, и останавливают счет времени. Как видно из схемы, стоповые сигналы подаются сразу на два канала TDC, причем с инверсной полярностью. За счет этого можно измерять не только длительность «полета» светового импульса, но и ширину принятого импульса.

TDC-GPX имеет 28-битную шину данных, но при этом ее можно переключить в 16-битный режим, что как раз и используется в сканере. Шина адреса — 4-битная, она также смещена на 1 разряд, как и у микросхем памяти. Микросхемы DD8, DD9, U2 служат для формирования сигналов управления микросхемой и согласования уровней — микроконтроллер работает от 5В, а TDC — от 3.3В. Вообще, система питания TDC достаточно сложна, там есть даже автоматическая подстройка питающего напряжения. Из-за ее сложности я не стал рисовать ее схему — подозреваю, что она не сильно отличается от даташита.
О программировании микроконтроллера и TDC я расскажу далее.

Как я уже упоминал ранее, на плате установлена заказная микросхема ASIC с надписями «LEUZE98» и «WATCHDOG». Что она из себя представляет — неизвестно. Видно, что к этой микросхеме подключен кварцевый генератор на 20МГц. После того, как я смог запрограммировать микроконтроллер, я убедился, что ASIC не мешает его работе, и не стал восстанавливать схему подключений ASIC. Насколько я понимаю, с контроллером эта микросхема общается по параллельной шине. Возможно, что именно ASIC формирует сигнал сброса RESETn, который сбрасывает контроллер и TDC.
Тем не менее, с некоторыми цепями пришлось разбираться подробнее.

Как оказалось, сигнал управления лазером «LASER_PULSE» может формироваться как микроконтроллером, так и ASIC — при помощи узла на транзисторах T1, T2. При этом при включении ASIC открывает транзистор T1, так что контроллер оказывается не способен управлять лазером. Из-за этого мне пришлось снять резистор R24 — и лазер начал нормально управляться контроллером.
Сигнал управления мотором зеркала «line_motor1» также шел от ASIC (через диод D2). Из-за этого мне пришлось перерезать дорожку и на плате и подключить этот сигнал напрямую к свободному выводу GPIO контроллера — P3.15.
Самое странное — линия «CS2», соединенная с ЦАП, установленном на плате модуля фотоприемника, тоже оказалась соединенной с ASIC. Из-за этого контроллер не мог самостоятельно установить напряжение питания APD, и включить усилитель APD. Возможно, это сделано для повышения надежности работы сканера — ошибочная настройка ЦАП может привести к выходу из строя APD. Эту линию мне тоже пришлось подключить к свободному выводу GPIO контроллера P3.4.
Точно известно, что тремя светодиодами, установленными на модуле лазера, управляет именно ASIC. Еще два светодиода, отображающие состояние сканера (наличие препятствия в рабочей зоне), управляются с контроллера — линиями LN1, LN2. Эти линии также уходят на плату модуля интерфейсов.

Так как сканер может работать в системах обеспечения безопасности, плата процессора имеет большое число узлов для диагностики своего состояния. Процессор (и возможно ASIC) может обнаруживать включение лазера (при помощи микросхемы U3), контролировать уровень нескольких питающих напряжений, напряжение питания APD, температуру APD, порог срабатывания компаратора на плате фотоприемника.
Из-за того, что опорное напряжение АЦП контроллера равно 4.1В, часть измеряемых напряжений уменьшается при помощи резисторных делителей — их видно на схеме справа.

А теперь стоит подробнее рассмотреть методику формирования необычного сигнала «digi», который я упоминал ранее при описании модуля фотоприемника.
На схеме ниже показаны узлы одновременно модуля процессора (внизу) и модуля фотоприемника (вверху):
image
Стрелками показана связь модулей при помощи проводов.
Ниже я опишу работу этих узлов, как я ее понял.
В модуле фотоприемника сигнал с выхода APD усиливается микросхемой DA4, после чего попадает на компаратор D1. Если уровень сигнала на входе компаратора оказывается больше 50 мВ, то на выходе компаратора устанавливается высокий уровень. Сигнал с выхода компаратора передается на модуль процессора. В первую очередь он поступает на вход TDC, которая считает время от начала лазерного импульса. Но кроме того, этот сигнал поступает на вход тактирования D-триггера DD1. На сигнальный вход триггера всегда подается логическая единица, а сам триггер можно сбросить в нулевое состояние при помощи GPIO лини контроллера «BASE5». Таким образом, срабатывание компаратора приводит к защелкиванию триггером «1». Этот триггер имеет дифференциальный выход, сигнал с которого поступает на вход микросхемы D3, которая преобразует его в формат LVTTL. Именно этот сигнал подается на вход «digi» модуля фотоприемника. Как я упоминал ранее, по моему мнению, появление этого сигнала приводит к ослаблению уровня сигнала на входе компаратора.
Главный вопрос — зачем это нужно и почему так сложно реализовано? Почему нельзя было сделать оба узла на плате модуля фотоприемника?
Могу лишь высказать свои предположения. Возможно, сигнал нужно ослаблять, чтобы избежать перехода компаратора или амплитудного детектора в режим насыщения. Возможно — чтобы уменьшить длину принятого импульса. Для обоих узлов просто могло не найтись места на плате фотоприемника. Возможен и другой вариант — сигнал нужно ослаблять только после того, как он успеет дойти до TDC по коаксиальным проводам, что оправдывает такую сложную конструкцию.
Исследование показало, что перед запуском нового импульса лазера нужно обязательно сбрасывать триггер, иначе импульсы не принимаются.

Модуль интерфейсов
К сожалению, у меня не нашлось хорошей фотографии этого модуля. Есть только вот такая:
image
Именно на этом модуле установлены единственные два разъема, к которым можно подключится снаружи сканера. Один из них — RS-232/RS-422, по второму на сканер подается питание, подаются сигналы управления, и сюда же подключается цепь безопасности.
Этот модуль содержит преобразователи UART-RS232/RS485 и оптопары гальванической развязки (они установлены на отдельной маленькой плате, показанной справа), силовые ключи цепи безопасности, входные цепи линий управления режимами дальномера, схему управления двигателем, преобразователь сигнала энкодера.
К этому модулю подключаются модуль питания и модуль процессора, а также модуль энкодера и мотор зеркала (при помощи разъемов снизу модуля, на фотографии их не видно).

Частичная схема модуля интерфейсов:
image
Я восстановил только часть схемы этого модуля (около 20%), так как меня не интересовали ключи и линии ввода, нужные для обеспечения безопасности. А накручено там довольно много, в документации упоминается ограничение тока по цепи безопасности, контроль КЗ, и другой функционал.

Несколько странно сделано управление скоростью вращения мотора зеркала. Регулировка скорости реализуется за счет изменения напряжения питания мотора — с этим все понятно. Но вот сама регулировка этого напряжения идет при помощи некой интегрирующей цепочки на операционном усилителе. Для того, чтобы повысить напряжение, контроллер устанавливает 0 на линии «line_mot1», чтобы понизить — 1. Очевидно, что без постоянной обратной связи от энкодера через контроллер мотор либо останавливается, либо разгоняется до максимальной скорости.

Как оказалось, микросхема-преобразователь UART-RS232 LTC1387 достаточно медленная — на скорости 500 kbit/s данные искажались. Из-за этого мне пришлось снять маленькую плату с этой микросхемой, и подключить преобразователь USB-UART напрямую к плате модуля интерфейсов.

Теперь, когда я рассказал об устройстве всех модулей, стоит подробней рассказать о самом процессе реверс-инжиниринга.

Когда я начинал разбираться с электроникой сканера, больше всего я опасался, что в результате удара могли повредиться лазер либо фотоприемник. В тоже время я не был уверен в том, что мне удастся запустить модуль процессора — смущали незнакомый микроконтроллер и ASIC. Поэтому первым делом я восстановил схему модуля лазера, а затем и модуля фотоприемника. После того, как я смог разобраться в схемотехнике этих модулей и определить назначение всех контактов на их разъемах, можно было приступать к модулю процессора. В крайнем случае, если бы я не смог его запустить, у меня была мысль сделать аналог этого модуля на микросхемах STM32 + TDC-GP2.

Очевидно, что чтобы проверить модуль, нужно запустить на установленном на нем микроконтроллере Infineon SAK-C167CR собственную программу. Опять стоит вспомнить, что у этого контроллера нет встроенной Flash памяти. Более того, как оказалось, у контроллера нет никаких специализированных отладочных интерфейсов (включая JTAG). С большой долей вероятности прошивку записывают во внешнюю Flash в программаторе на производстве. Однако, как оказалось, все не так плохо — у контроллера есть загрузчик («Bootstrap Loader»), работающий по UART. Этот загрузчик хранится во встроенной Boot-ROM контроллера, так что он обязательно должен был быть в имеющемся у меня контроллере. И работает он довольно своеобразно — для его активации при запуске нужно установить линию шины данных P0L.4 в низкий уровень, после чего контроллер начинает ждать появления байта 0x00 от хоста. Приняв этот байт, загрузчик автоматически определяет скорость передачи, и начинает ждать 32 байта данных, которые копирует в встроенное ОЗУ контролера. После того, как данные получены, контроллер начинает выполнение полученной программы (16 слов контроллера).
Фактически, в эти 32 байта нужно впихнуть еще один загрузчик («preloader»), который получит от хоста основной загрузчик «External loader», и начнет его выполнение.
Тут мне повезло — для этого процессора есть уже готовая программа FLASHit, которая умеет делать все упомянутые операции автоматически. Встроенный в нее загрузчик обладает достаточно большим функционалом — с его помощью можно автоматически определять модель установленной Flash памяти, редактировать и смотреть содержимое регистров контроллера, можно посмотреть состояние каналов АЦП.

Мне не удалось обнаружить на плате никаких тестовых площадок, соединенных с линией P0L.4 контроллера, так что для того, чтобы запускать загрузчик, мне пришлось припаять специальный штырек к этой линии. Сам штырек я приклеил к корпусу одной из микросхем RAM. Для запуска загрузчика нужно соединить этот штырек через резистор 8 кОм с землей.
После того как я подключил плату к компьютеру, и подал питание на модуль процессора, микроконтроллер действительно обнаружился в FLASHit. После этого я написал в Keil маленькую программу, переключающую один из выводов контроллера, и записал ее во Flash. Программа нормально заработала, ASIC никак не мешал (я опасался работы какого-нибудь встроенного в него механизма watchdog, или конфликтов на шинах), так что можно было двигаться дальше.
После этого я восстановил схему модуля процессора, что позволило проверить работу всех модулей в сборе.
Первым я проверил работу модуля лазера — как я уже писал ранее, для запуска лазерного импульса нужно было подать на этот модуль всего один сигнал. Лазер заработал — его вспышки можно было видеть при помощи камеры мобильного телефона. Также при помощи осциллографа проверил, что модуль нормально формирует стартовые (опорные) импульсы.
Дальше шла проверка модуля фотоприемника. Тут пришлось проверить работу ЦАП, узла формирования напряжения лавинного фотодиода и узла управления питанием усилителем фотоприемника. Все они заработали, что позволяло проверить работу самого дальномера. Для этого я собрал его модули в том виде, как его задумывали разработчики:
image
На фотографии все пять основных модулей собраны вместе вокруг оптической системы. Здесь вместо родного вращающегося зеркала я установил обычное зеркало.
После этого, я подал написал программу управления лазером по UART, настроил работу фотодиода. В результате при запуске лазера на входе компаратора я действительно смог обнаружить осциллографом импульсы, амплитуда которых явно зависела от типа препятствия перед зеркалом! Компаратор тоже нормально работал. Оставалась последняя важная часть тестирования — проверка работы TDC.

Установленная в сканере микросхема TDC-GPX имеет достаточно сложную конструкцию, и может работать в большом числе режимов.
На рисунке ниже приведена ее структурная схема:
image
Как видно, микросхема содержит 8 отдельных каналов, то есть она может принимать до 8 стоповых сигналов. В случае, если каналы дифференциальные, то можно анализировать только два стоповых сигнала плюс один стартовый сигнал. В таком случае микросхема позволяет объединить измерительные каналы, за счет чего повышается точность измерения временных интервалов:
image
Честно говоря, документация на эту микросхему мне не понравилась. Многие вещи в ней описаны довольно поверхностно, примеры кода непонятные. Часть даташита, посвященная настройке разрешения по времени полна каких-то «мигичесих чисел». Нормального «Application Note» на микросхему так же нет. Кроме того, в самом сканере мне не удалось обнаружить соединения линий «EF1/EF1» с контроллером. Именно по состоянию на этих линиях можно определить, что микросхема закончила измерять время. Из-за всего этого запуск TDC занял у меня достаточно много времени, но в результате все заработало, как надо — при запуске лазера срабатывал TDC, а результаты работы TDC явно зависели от расстояния до препятствия. Таким образом, импульсный лазерный дальномер заработал. Осталось превратить всю конструкцию в работоспособный лазерный сканер.
Первым этапом мне нужно было провести юстировку — собранный дальномер переставал «видеть» препятствия уже через несколько метров. Оптическая система выглядела неповрежденной, а вот платы мне приходилось снимать с оптической системы, так что отраженный свет фокусировался объективом на фотоприемнике не точно.
Перед юстировкой я написал программу для контроллера, которая не только определяла расстояния, но и измеряла при помощи АЦП амплитуду сигнала, сформированную пиковым детектором.
Весь процесс юстировки сводился к плавным подвижкам плат фотоприемника и лазера, и поиску такого их положения, при котором амплитуда сигнала максимальна. В результате юстировки удалось значительно улучшить амплитуду принимаемого сигнала.
Далее следует обратить внимание на некую особенность обработки данных, присущую импульсным дальномерам.
Сигнал, формируемый фотоприемником, имеет аналоговый вид. Для преобразования его в цифровую форму, которая далее обрабатывается TDC, используется компаратор, настроенный на переключение, если входной сигнал превосходит некий установленный порог. В результате из-за сложной формы входного сигнала, при изменении амплитуды сигнала появляется ошибка при определении временных интервалов:
image
Как видно из графика, сигнал с меньшей амплитудой будет обнаружен с запаздыванием. Для решения этой проблемы существуют несколько методов, как аппаратных, так и программных. Я решил использовать самый простой вариант — коррекцию результатов измерения в зависимости от амплитуды сигнала. При этом мне пришлось собрать статистику изменения результатов измерения времени от изменения амплитуды сигнала. Для того, чтобы поменять амплитуду сигнала, не изменяя остальных его параметров, я использовал бумажные накладки на объектив, которые уменьшали световой поток, попадающий на фотодиод.
В результате получилась такая зависимость:
image
На основе этой зависимости я сформировал таблицу поправок, данные из которой используются программой контроллера при определении расстояния до объекта.

Следующий этап — запуск двигателя зеркала и энкодера.
Ранее я уже приводил фотографию зеркала:
image
Двигатель зеркала — бесколлекторный, очень похожий на те, что используются в вентиляторах кулеров. Из него выходят три провода — 2 из них питание, еще один — импульсный сигнал скорости. Все эти провода подключаются к модулю интерфейсов, при этом сигнал скорости, формируемый двигателем, не используется — управление идет по данным от энкодера.
Как видно из фотографии, на оси двигателя закреплен прозрачный диск с метками для энкодера. Можно заметить, что на диске есть метка нуля.
Энкодер был установлен на небольшой плате и полностью закрыт металлическим экраном, так что его маркировку определить не удалось. Однако, исходя из его размеров и распиновки, я решил, что это квадратурный энкодер HEDS-9040:
image
От платы энкодера к модулю интерфейсов шли четыре провода, но, как оказалось, из них использовались только три — два питания и сигнал.
Насколько я понял, на плате были установлены триггеры Шмитта и некая логика, объединяющая данные от каналов A, B, и индексного (сигнал нулевой метки).
Вот так выглядит сигнал, выдаваемый платой энкодера, и индексный сигнал, снимаемый прямо с энкодера.
image
Как видно, во время индексного сигнала, импульсы энкодера подавляются. Как оказалось, плата энкодера формировала 500 импульсов на оборот, но таймер контроллера T2, к которому подключена линия энкодера, способен срабатывать одновременно по обоим фронтам импульсов, что дает 1000 прерываний на оборот зеркала. Это значение соответствует заявленному угловому разрешению сканера в 0.36 градусов.
Я настроил таймер T2 в режим «Capture mode», который позволяет измерять время между прерываниями от энкодера. Полученное время используется для обнаружения «нулевого» положения зеркала, и стабилизации скорости вращения мотора. Одновременно идет подсчет числа прерываний, что позволяет определить положение зеркала.
После того, как энкодер заработал, и мне удалось запустить управление скоростью двигателя, можно было полностью собирать сканер. Из-за сложной формы плат и оптики конструкция получилась довольно вычурная:

image

image

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

При измерении точного расстояния до объектов важно желательно иметь некий «опорный» объект, расстояние до которого точно известно. Зная «время полета» до него, можно точно определить время, соответствующее нулевому расстоянию. Из-за изменения температуры компонентов сканера это время может меняться, так что это время нужно контролировать постоянно. Для решения этой задачи я установил в сканер специальную зачерненную пластинку:
image
Пластинка зачернена для того, чтобы отраженный от нее свет не «ослепил» фотоприемник. Судя по инструкции, в оригинальной конструкции сканера тоже были установлены темный и светлый отражающие элементы. Они использовались для контроля работы дальномерной части сканера, и скорее всего, так же использовались для калибровки.
На фотографии выше так же хорошо видно энкодер, установленный на плате. Как оказалось, энкодер должен быть очень точно установлен относительно диска, и с этим было много проблем — даже маленькое смещение энкодера приводило к пропаданию импульсов, особенно индексных. Вполне возможно, что сканер перестал работать после удара по корпусу именно из-за проблем с энкодером.

В результате удалось получить скорость сканирования до 20 оборотов в секунду. При напряжении питания APD в 135 В нормально идет определение расстояний до 10-15 м. При напряжении 145 В и с дополнительной фильтрацией сигнала можно измерять расстояния и до 30 м (хотя я и не уверен, что это безопасно для фотоприемника).
Стоит отметить, что максимальная скорость передачи в оригинальном сканере — 115200 bit/s, что позволяет передавать все данные только при скорости около 11 оборотов в секунду.
Как я упоминал, у себя в прошивке я передаю данные со скоростью 500 kbit/s, что позволяет значительно повысить число передаваемых сканов в секунду. Именно из-за ограничения по скорости UART я не увеличивал скорость сканирования до оригинальных 25 оборотов в секунду. Замечу, что в оригинальной конструкции сканера данные обрабатываются в самом сканере, так что низкая скорость передачи данных ни на что особо не влияет.
Так как сейчас сканер работает без корпуса, то удалось увеличить зону сканирования до 208 градусов против 190 в оригинальной конструкции.

Визуализация данных, получаемых от сканера:
image
Очевидно, что сканер должен выполнять какую-либо полезную функцию, так что я решил проверить его работу в ROS в SLAM, и сравнить результаты с результатами самодельного лазерного сканера. Для этого я установил его на Roomba, на которой ранее был установлен самодельный сканер.

Вид сканера Leuze, установленного на Roomba (зеркало вращается, так что оно вышло размытым):
image

В результате работы hector_slam удалось получить вот такую карту квартиры (желтым показаны стены):
image
Поскольку пылесос ездит на уровне пола, то он «видит» в основном мебель.

А вот такая карта получается, если пылесос просто носить в руках на уровне пояса:
image
В данном случае стены квартиры «видны» чаще.
Если сравнивать качество карт, то видно что у самодельного сканера линии более «шумные». Это связано с тем, что у самодельного сканера, использующего триангуляционный принцип работы, с ростом расстояния сильно падает точность.

К сожалению, несмотря на очень хорошее качество сканирования, этот сканер плохо подходит для автономного робота — у него слишком большие габариты и потребляемая мощность (около 7.2 Вт).
Куда еще можно применить такой сканер? Ранее, при обсуждениях самодельного сканера, меня часто спрашивали про возможность изготовления 3D сканера, и пора сделать именно его! Тут пригодится достаточно высокая скорость сканирования. Конечно, по разрешению такой сканер нельзя сравнить со сканерами, использующими триангуляционный принцип измерения расстояния (с лазерной линией или проектором (SLS)), зато им можно сканировать большие пространства — помещения, участки улиц.

Для того, чтобы переделать 2D сканер в 3D, нужно обеспечить ему возможность вращаться по еще одной оси. Свой сканер я решил сделать, используя такой же принцип развертки луча, как в сканере из этой статьи. Для этого сканер Leuze я расположил «лежа», так, чтобы его плоскость сканирования была перпендикулярна полу. Далее нужно было реализовать плавное медленное вращение всего сканера вокруг оси. Главная сложность — сканер должен вращаться без биений и перекосов, которые приведут к искажению сканов. Как оказалось, в домашних условиях сложно сделать подшипниковый узел, способный обеспечить такое точное вращение. Поэтому я решил использовать в качестве подшипникового узла головку от VHS магнитофона — она содержит два подшипника, сделана с очень высокой точностью и способна выдержать тяжесть сканера. Получившаяся конструкция приводится во вращение шаговым двигателем.

Выглядит собранный 3D сканер вот так:
image

Вид сканера, установленного на треноге:
image

Слева установлен 12 В аккумулятор, одновременно являющийся противовесом. Так как сканер Leuze требует 24 В для работы, мне пришлось установить на сканер повышающий DC/DC преобразователь, собранный на базе микросхемы XL6009. Шаговый двигатель сканера управляется при помощи модуля на A4988 и Arduino, которая обеспечивает вращение с заданной скоростью. И сканер Leuze (через переходник USB-UART) и Arduino подключены через USB-хаб проводом к компьютеру, который производит захват данных. В текущем виде вращение зеркала сканера и вращение всего сканера не синхронизированы — скорость вращения сканера выбрана такой, чтобы при его повороте на 0.36 градуса зеркало успевало сделать не менее трех оборотов. Так как синхронизации по скорости нет, мне пришлось передавать синхроинформацию о положении от Arduino к сканеру Leuze. Реализовано это достаточно просто — Arduino при повороте сканера на каждые 0.36 градуса изменяет уровень сигнала на одном из выводов. Этот сигнал передается на модуль процессора сканера (на неиспользуемый разъем датчика состояния защитного стекла). Информация о состоянии этого сигнала передается в начале каждой посылки сканера — таким образом самописная программа для ПК, управляющая сканером, получает информацию о движении сканера и определяет угол, на который он повернут.
Одиночный 3D скан, формируемый сканером, содержит около 350'000 точек. Конечно, это значительно меньше, чем у профессиональных сканеров, но все равно достаточно неплохо, особенно если склеить несколько сканов вместе.

Пример — одиночный скан комнаты:
image

Пример — скан комнаты, склеенный из нескольких:
image

Отсканированная часть подъезда:
image

Видео, в котором показаны результаты работы получившегося сканера:

Исходный код программы контроллера

Автор: iliasam

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js