В первой части мы описали процесс разработки тестового варианта модуля подводного дальномера. Пришло время поделиться информацией о второй версии модуля, поскольку заявленные в первой статье предполагаемые изменения мы реализовали.
Изменение №1: Временная автоматическая регулировка усиления (ВАРУ).
В процессе тестирования первой версии модуля чётко вырисовывалась проблема зашкаливания отражённого сигнала от препятствий, находящихся близко к излучателю. Некоторые комментаторы к предыдущей заметке рекомендовали ВАРУ. Да, применение ВАРУ оказалось очень уместным. Теперь, в первые мгновения после посылки зондирующего импульса, есть возможность сделать коэффициент усиления минимальным и увеличивать его с течением времени.
Реализация ВАРУ показана на схеме №1.
ЦАП микроконтроллера генерирует напряжение, подающееся на затвор транзистора Q4.
Для применённого транзистора экспериментально получена характеристика вносимого затухания, в зависимости от напряжения на затворе. На основе этой характеристики, и указанной пользователем параметров среды, рассчитывается таблица значений, которая посредством DMA отправляется в ЦАП микроконтроллера.
Фактически, транзистор, работая в линейном режиме, частично замыкает полезный сигнал с выхода первого каскада усилителя на «землю», тем самым регулируя амплитуду сигнала, идущего в последующие каскады усилителя.
Изменение №2: Повышающий преобразователь для питания выходного каскада.
Схема №2. Тут всё просто. Повышающий преобразователь позволяет сделать наш излучатель чуть «громче». Можно регулировать напряжение питания выходного каскада с 5 до 16 Вольт. Полезная штука для дальних измерений.
Изменение №3: MEMS гироскоп/акселерометр.
Схема №3. Встроили микросхему ICM20602. Это позволит получать не только информацию об уровнях отражения от объектов на пути луча, но и направление (угол) куда в этот момент смотрит модуль. Сделав простейшую развёртку модуля (хоть покрутив модуль рукой) можно получить реалистичную картинку объекта сканирования по принципу формирования изображения лидаром.
К изменениям стоит ещё отнести применение более дешёвого, но не худшего усилителя MCP669-E/ML. Драйверы затворов тоже выбраны самые дешёвые из доступных TPS51604DSGR.
Форма печатных плат сделана круглой, для более рационального размещения внутри металлического корпуса.
Для компактности и постоянства характеристик от экземпляра к экземпляру, трансформатор изготавливается по планарной технологии.
Железо готово. Что дальше? Наступает звёздный час программистов!
Хоть основной низкоуровневый функционал уже проверен в работе (управление драйвером, работа с АЦП, ЦАП и т.п.), необходимо ещё реализовать удобное взаимодействие с хостом, создать и подробно описать API, дающий доступ ко всем возможностям модуля. Напомню, в качестве физического интерфейса для этих целей мы выбрали UART. И тут стоит упомянуть, что в команде появилось разногласие, на каком виде протокола стоит пока остановиться: на текстовом, или бинарном. С одной стороны, бинарный протокол – это быстродействие, простота обработки на стороне хоста. С другой стороны, текстовый протокол позволяет проще анализировать обмен данными (даже в «Гипертерминале»), и использовать осмысленные команды/ответы модуля. Вот небольшой пример взаимодействия с модулем используя текстовые команды в терминале Putty:
По нажатию клавиши TAB выводится список всех команд.
Приведён пример использования команды YPR, которая возвращает текущее значение направления модуля по трём осям (углы Эйлера).
Команда CHART возвращает значение отражённого сигнала от объектов на пути зондирующего импульса. Можно задать дискретность измерения (пока в сантиметрах) и количество измерений.
Конечно, идеальный случай – поддержка обоих вариантов протокола, и текстового и бинарного. Но мы, к сожалению, во времени ограничены, и хотелось бы сразу направить усилия на более приемлемый для пользователей вариант. Отсюда скромная просьба: отметьте в голосовалке вариант, который был бы вам более удобен.
К следующей статье попытаемся задействовать весь функционал модуля, чтобы иметь возможность сканировать подводные объекты и получать картинку с очертаниями этих объектов.
Сухость текста разбавлю немного фотками, которые делались в процессе изготовления второй версии модуля.
Сборка излучателей
Обработанные металлические корпуса
Корпуса с нанесённой лазером маркировкой
Сборка плат модулей
Комментарии (38)
FGV
12.04.2019 15:15Лучше реализовать оба протокола — и текстовый и бинарный, с возможностью переключения.
technomancer
12.04.2019 15:51Назовите же сумму!
MShekunov Автор
12.04.2019 17:29Себестоимость материалов для изготовления одного модуля перевалила отметку $40
x893
12.04.2019 15:56Конечно два протокола удобнее. А если бы ещё и за разумные деньги купить устройство — всё пошло бы быстрее.
Andy_Big
12.04.2019 16:13+2После того как я начал работать с GSM-модемами, я понял, что текстовые протоколы в автоматической обработке — полный отстой :) Нет, я и раньше это подозревал, но вот тут прочувствовал в полной мере :) Так что я за бинарный :)
Но в дополнение к нему можно внести и текстовый, потом когда появится время.vassabi
12.04.2019 16:24а что не понравилось?
мне казалось, что минималистичный текстовый автоматизируется\разбирается\передается ненамного хуже бинарного, зато гораздо удобнее «смотрится вручную».Andy_Big
12.04.2019 16:35а что не понравилось?
Громоздкость его обработки. Получив структурированный бинарный пакет можно просто наложить на него указатель соответствующей структуры — и все данные как на ладони. А текст приходится парсить, определять тип сообщения строковыми сравнениями, преобразовывать числовые величины из строк в числа и т.д. Особенное зло — асинхронные сообщения, вываливаемые в канал связи :)vassabi
12.04.2019 17:03ну, понятно, что я не про JSON\yaml, а про что-то уровня CSV (и форматирования а-ля дат\времен\координат).
Если к вам в середину одного бинарного пакета асинхронно «приедет» другой бинарный пакет — тоже ничего хорошего.
Единственные два минуса текстового — это преобразования чисел из строк и бОльший размер (опять же — из-за символьного представления). Но это не настолько уж и критичные минусы ИМХО.Andy_Big
12.04.2019 17:11я не про JSON\yaml, а про что-то уровня CSV (и форматирования а-ля дат\времен\координат).
Так и я про простые на первый взгляд протоколы типа системы AT-команд :)
Если к вам в середину одного бинарного пакета асинхронно «приедет» другой бинарный пакет — тоже ничего хорошего.
Во-первых, такого просто не может случиться при прямом канале данных, а во-вторых в бинарных протоколах обычно предусматривается контроль целостности данных :)vassabi
12.04.2019 17:39так а что мешает добавить контроль целостности (base64\hex-поле) в текстовой?
при неизменной длинне сообщений (например при выравнивании нулями) можно также ориентироваться на служебные символы (те же разделители), т.к. их отсутствие\смещение — признак «порчи пакета»Andy_Big
12.04.2019 17:53Да можно, конечно, кто же спорит. Я ведь и не утверждаю, что текстовые протоколы неработоспособны, я говорю лишь о том, что для автоматической обработки они подходят гораздо хуже бинарных. Особенно в микроконтроллерных системах.
Текстовые протоколы имеет смысл делать для отладки или взаимодействия с человеком, но как рабочие при взаимодействии с микроконтроллерами — это отстой :)olartamonov
12.04.2019 19:05В микроконтроллерных системах вообще любые подобные протоколы подходят плохо.
Там хорошо подходит модель с прерываниями и регистрами, по которой подавляющее большинство современных чипов и работает: дёрнулась ножка — проверил регистр статуса — прочитал регистр состояния.Andy_Big
12.04.2019 21:07Ну почему, работа в формате «запрос/команда-ответ/подтверждение» вполне неплохо работают и на микроконтроллерах. По крайней мере у меня было несколько реализованных проектов с подобными протоколами общения между модулями, все очень неплохо ложилось в линейную программу без всяких RTOS. Естественно, с использованием прерывания на том интерфейсе, который отвечал за канал данных.
Сейчас вот делаю девайс, который должен время от времени отправлять данные на сервер через модем и принимать от него запросы, команды, обновление прошивки и т.п. Тоже набросал типовой бинарный протокол с фиксированными заголовками, данными переменной длины и гарантированной доставкой пакетов. Все отлично работает, не напрягая микроконтроллер функциями типа strstr() и scanf() :)
По поводу «дернул ножкой» — да, я хотел написать, что этому измерителю не помешал бы выход прерывания, но не стал расписывать. Например, микроконтроллер дал ему команду измерить и занялся дальше своими делами, а модуль притянул этот свой выход к земле («занято»). Как только измерение закончено, модуль отключает притягивание этого выхода к земле («свободно»), запуская в микроконтроллере прерывание. Ну или микроконтроллер сам время от времени проверяет уровень этого выхода модуля и если обнаруживает что там единица, запрашивает у модуля готовые данные. Распространенное решение :)
alexzeed
12.04.2019 17:17наложить на него указатель соответствующей структуры — ну это пока там нет полей переменной длины: строк, массивов и т.п
Andy_Big
12.04.2019 17:55Само собой. Но в бинарных данных все это решается гораздо проще, чем в текстовых.
AVI-crak
12.04.2019 20:37+1habr.com/ru/users/alexzeed
Откуда в простой железяке появятся случайные данные? Это-же не радиомодуль, это девайс с жёсткими фиксированными таймингами. Есть окно на отправку импульса, есть окно на приём. Мешать их нельзя, всю служебную информацию можно оправлять в каждом пакете с данными — там времени и места вагон.
Другое дело что ультразвуковой дальномер с одним излучателем/приёмником — это как-бы вчерашний день. Да, комплектующие свежие, точность чуть выше, но результат как у 100500 аналогичных устройств.
Имея два приёмника можно обнаруживать несколько объектов на линии горизонта — несколько самых громких и ближних. А если три приёмника — то уже в плоскости.
А три приёмника + три излучателя — возможность просвечивать интересующие вас участки пространства. На этом этапе однотоновая посылка становится мало информативной. А разбор ответа требует современных быстрых мк.
В этом случае заголовок бинарного пакета определяет его свойства — можно обрабатывать на лету.
olartamonov
12.04.2019 16:33У модема проблема не в текстовости, а в полной асинхронности — когда у тебя ответ на запрос приходит через неизвестный промежуток времени, а иногда вместо него вообще приходит какой-нибудь RING.
Andy_Big
12.04.2019 16:41Да, и я так и не придумал как малой кровью на 100% побороть это :) Когда, например, принимаемые бинарные данные обрываются текстовым сообщением «CLOSED» :)
Немало крови попило и то, о чем Вы пишете — когда ответ на запрос приходит не в виде:
<ответ>
OK
а в виде:
OK
(прошло какое-то время)
<ответ>
Или вообще:
OK
(прошло какое-то время)
<какое-то левое асинхронное сообщение>
<ответ>
DenisHW
12.04.2019 16:19Для применённого транзистора экспериментально получена характеристика вносимого затухания, в зависимости от напряжения на затворе. На основе этой характеристики, и указанной пользователем параметров среды, рассчитывается таблица значений, которая посредством DMA отправляется в ЦАП микроконтроллера.
Вы как-то учитывали разброс параметров транзистора и зависимость от температуры?MShekunov Автор
12.04.2019 16:35Спасибо за вопрос. Сейчас температура не учитывается вообще никак. Она, действительно, ощутимо влияет на параметры транзистора на границе открытия. К счастью, это всё можно учесть в прошивке. Темодатчики встроены в корпуса микроконтроллера и гироскопа/акселерометра.
DenisHW
12.04.2019 16:42+1Да, но есть еще производственный разброс. Надеюсь вы проверили на нескольких экземплярах. Лучше было бы завести управление через real time обратную связь на МК как то, что бы вообще не зависеть от параметров транзистора. Вдруг текущий снимут с производства.
MShekunov Автор
12.04.2019 22:05Вы описали идеальный случай. Я мог бы сказать, что у нас не осталось свободных каналов АЦП и т.д. и т.п. Но в реальности, высокая точность регулировки усиления не сильно тут важна, и мы не заботимся об этом сознательно, упрощая и ускоряя процесс разработки. Достаточно преодолеть порог открытия транзистора, и работать в пределах его линейного режима с небольшой погрешностью в итоговом коэффициенте усиления.
olartamonov
12.04.2019 16:45+1Некоторые комментаторы к предыдущей заметке рекомендовали ВАРУ. Да, применение ВАРУ оказалось очень уместным. Теперь, в первые мгновения после посылки зондирующего импульса, есть возможность сделать коэффициент усиления минимальным и увеличивать его с течением времени.
Есть другой вариант — менять мощность выхлопа в ультразвук. Мы в дальномере с диапазоном 300...6000 мм, например, подаём на излучатель 5 импульсов, смотрим зону до 2000 мм, если там ничего нет — подаём 15 импульсов, смотрим 2000...4000 мм, потом 25 и 4000...6000.
И это помогает не столько с зашкаливанием на отражении от близких объектов, сколько с уменьшением собственного звона излучателя.
Повышающий преобразователь позволяет сделать наш излучатель чуть «громче». Можно регулировать напряжение питания выходного каскада с 5 до 16 Вольт
Можно проще — LC-контур из излучателя и индуктивности, возбуждаемый драйвером, вполне себе сам себе повышающий преобразователь, на котором можно развить 10-15 В. Очень дёшево и практично, минус — с температурой ёмкость излучателя меняется.ngl4ngl
12.04.2019 17:11+1LC-контур из излучателя и индуктивности это не очень хорошее решение, поскольку сделать так, чтобы его частота совпадала с частотой резонанса излучателя почти невозможно (в частности из-за температурных уходов). А излучатель, даже специально задемпфированный, это довольно добротная штука.
MShekunov Автор
12.04.2019 22:21Есть другой вариант — менять мощность выхлопа в ультразвук. Мы в дальномере с диапазоном 300...6000 мм, например, подаём на излучатель 5 импульсов, смотрим зону до 2000 мм, если там ничего нет — подаём 15 импульсов, смотрим 2000...4000 мм, потом 25 и 4000...6000.
Этот метод рабочий, но, к сожалению, понижает полезную частоту обновления данных на выходе. Более того, большое количество импульсов в пачке снижает разрешение (детализацию). Например, было проверено, что два импульса в пачке при сканировании обычной стеклянной бутылки на расстоянии 40см дают отчётливую картину отражения сигнала от передней и задней стенок бутылки. Если увеличить количество импульсов до, примерно, десяти, то эти два отражения сливаются в одно.
Думаю, что увеличение именно мощности излучения позволит не терять в разрешении на более дальних дистанциях. Хотя понимаю, что бесконечно повышать мощность нельзя. Наступит момент, когда излишняя мощность будет просто съедаться кавитацией.
Про добротность хотел добавить.
Добротность нашего излучателя в воде, к счастью, никакая ))) Излучатель согласован неплохо, звон практически отсутствует. Большая часть энергии уходит в воду.olartamonov
13.04.2019 12:35Да, с водой вам хорошо. На воздухе у обычного парктроника от пяти импульсов по 15 В звон на несколько миллисекунд, активным демпфированием его удаётся задавить до ~1,5 мс — и это будет слепая зона (нахождение в которой объекта у многих дальномеров даёт ложные показания).
MShekunov Автор
13.04.2019 13:25активным демпфированием
Это вы в противофазе сигнал даёте?olartamonov
14.04.2019 11:39Нет, неверно выразился — демпфирование само по себе пассивное (нагружаем на RL), активность только в том, что оно подключается на короткое время, а не висит на излучателе непрерывно.
MShekunov Автор
12.04.2019 22:26Можно проще — LC-контур из излучателя и индуктивности, возбуждаемый драйвером, вполне себе сам себе повышающий преобразователь, на котором можно развить 10-15 В.
Как я заметил ранее, добротность излучателя крайне мала, так что резонансная система вряд ли будет эффективной.
Ну и когда я заявлял о диапазоне 5-16 Вольт, то речь шла о напряжении питания драйвера первичной обмотки повышающего трансформатора. На самом пьезоэлементе (подключен ко вторичке транса) амплитуда превышает 500 Вольт.
starDestroyer
13.04.2019 13:47А Wake протокол не рассматривали? Вроде достаточно простой.
p.s. Не совсем по теме, но ни у кого не завалялся код асинхронного чтения com порта на Си и winapi(да, пока нужны свои велосипеды для понимания)? Застрял на этом месте, нет стабильного приёма.
alex-open-plc
13.04.2019 13:47-1В протоколе, использующем UART:
— передача текста использует XON/XOFF (0x11;0x13)
— для передачи бинарных данных потребуется еще два провода/сигнала RTx;CTx, либо конвертировать bin<->hexAndy_Big
15.04.2019 04:31Не мешайте в кучу логический и протокольный уровни. UART может передавать и принимать все что угодно без дополнительных линий и по любой логике, которую опишет программист.
Winny63
13.04.2019 22:12Когда в прошлой жизни в моей конторе делали усилитель с ВАРУ (назывался ЛУВР — линейный усилитель с временной регулировкой), то в нем в обратную связь был включен ЦАП, который, в свою очередь, управлялся данными с ППЗУ с выборкой по временному регистру. Точность была очень высокой.
newpavlov
Лично я предпочёл бы хорошо описанный бинарный протокол с дополнительной библиотекой на Питоне для «поиграться» (туда же можно будет сразу добавить простеньких визуализаций входящих данных). Кроме того, думаю, будет полезным в дополнение к протоколу «запрос-ответ» добавить ещё режим работы «постоянная посылка измерений», можете, например, ознакомиться с протоколом RPLIDAR. Ну и про контрольные суммы сообщений разумеется не забудьте.
MShekunov Автор
Уверен, многие согласятся, что качественно описать и оформить протокол (с навигацией по разделам и с примерами) — это труд не сильно легче самой реализации протокола.
Если создание качественного описания мы воспринимаем как неизбежное, то с примерами сложнее.
О питонах известно лишь, что они обитают в тропических лесах восточного полушария… И зачем им ультразвук?
А если серьёзно, то мы бы не отказались от помощи в создании примеров работы с модулем используя разные средства. Хоть Питон, хоть Ардуино, хоть МикроПаскаль.