Навигация под рукой: 03 - Теоретическая глава
К слову, я пил красное вино с колой задолго до того, как Усачев напоил этим "коктейлем" Собчак. И да, если вино дешёвое или просто невкусное, кола его действительно спасёт. Как кетчуп спасает посредственный шашлык на трассе Томск-Мельниково. Впрочем, о чём это я...
Первое, с чем я сразу столкнулся - это понимание, что я ничего не знаю и ничего не умею. Нет, какой-то опыт программирования и готовность творить неизвестную дичь здесь и сейчас у меня, конечно, были = спасибо моей работе и физическому факультету соответственно. Но паять я не умел. Я и сейчас примерно представляю, как это работает, но каждый раз как в первый. Программировать Arduino мне тоже предстояло впервые. Да и вообще в разработке и реализации устройств уровня "ничего себе, это же геймпад" опыта не было никакого. совсем. И я засел читать и смотреть видеоролики. Вообще, у меня складывается ощущение, что сегодня при желании или из необходимости можно научиться вообще чему угодно. Кодить. Готовить телятину вителло тонато. Перебирать движок запорожца. Есть палочками. Заводить котят.
Я довольно быстро понял, что я хочу. Мне был нужен девайс. на котором были бы все кнопочки и контроллеры, необходимые для управления виртуальной навигационной системой, и никаких экранов. А ещё у меня была стойка с панелью автопилота от стороннего производителя (хорошая штука, но я бы его переделал теперь, когда я понимаю, как это делается; но чтобы его "починить" нужно сначала его сломать, а я не умею) и пустым слотом. Так я определился с размером и тем, что это будет по факту калька с панели GNS-430 (верхняя панель на следующей иллюстрации), но с кнопкой VNAV как у GNS-530 (нижняя панель). Крутилки громкости мне были не нужны, зато появилась необходимость в переключателе, который позволял бы переключаться между 530 и 430. Я знал, что переключатель нужен, но не знал, как его реализовать.
Передо мной стоял ряд задач, которые мне нужно было решить.
Программирование платы управления. Повторюсь, я был с ней не знаком, так что пришлось начинать с азов. Куда её подключать, что куда тыкать, какой там язык, какая логика, что на какие пины можно вешать, как её перезагрузить. Начинал я, конечно, не сразу со схемы на 23 триггера, а с эдакого Hello world для двух кнопок. медленно, но верно я разбирался и понимал, какие библиотеки мне нужны, чтобы операционная система считала, что это игровое устройство. Занятно ,что с этим этапом я разобрался довольно быстро, хотя там внутри не привычный мне python, а что-то типа урезанного С++.
Matrix has you. Уже на начальном этапе я понял, что мне не хватает пинов. Я насчитал 23 триггера, а контактов, пригодных для использования, на подвернувшейся под руку Arduino Micro оказалось 18 и "земля". И то 18 - это после того, как до мен дошло, что пины, отмеченые как аналоговые, можно использовать и как цифровые - всё определяется в коде в итоге. Но каждой кнопке всё равно нужно два контакта, так что даже если все триггеры "повесить" на "землю", то "ножек" мне всё равно не хватит. Большинство тех, кто паяет подобного рода девайсы, сразу берут огромную Arduino Mega или более компактную Mega Pro, но моё девелоперское чутьё подсказало, что должен быть другой путь. И другой путь, конечно, есть. Это матрица.
Как оказалось, кнопкам по большому счёту всё равно на чём висеть. Если правильно всё закодить, плате управления не очень важно, какие контакты кнопка будет замыкать, а потому их можно коммутировать в матрицу. Если на пальцах, то 16 кнопок можно забить в матрицу 4х4: 4 контакта будут "отвечать" за ряды, а ещё четыре - за "столбцы". И таким образом попарное замыкание этих контактов будет однозначно определять нажатую кнопку. Может, с картинкой будет понятно.
В итоге выходит, что 16 кнопок занимают всего 8 контактов. Экономия очевидна. Наверное, их можно было ещё сильнее уплотнить, но мне уже за счёт такого хода контактов хватило. Даже один остался. Можно будет расширить какой-нибудь кнопочкой, которую я забыл. А самое вкусное в том, что я не первый решаю подобную задачу, так что для такой вот матричной клавиатуры добрые люди уже написали библиотеку, так что не пришлось городить этот код с нуля, что отняло бы у меня кучу времени. В итоге нужно было только аккуратно прописать пины для матрицы - и готово. Красота.
Круговые энкодеры. Или поворотные энкодеры. Поворотные кодировщики. Датчики угла поворота. Преобразователи угол-код. Компоненты с тысячью имён. Кто-нибудь, подскажите, как они по-русски называются в итоге. Короче, крутилки. С ними тоже было интересно. Во-первых, они сами по себе не простые ребята. Мои были инкрементными. Ну, накапливающие. Которые с двумя импульсами. И под них тоже есть библиотеки, которые реализованы под разные задачи (и, похоже, под разные подтипы этих самых энкодеров) и с которыми пришлось повозиться. Разные имплементации как-то по своему считают эти самые импульсы, так что пришлось вводить какие-то дополнительные нормирующие множители... Мрак, короче. Но спойлер - я справился.
Кроме того, мои энкодеры были с кнопкой. Это, к слову, не было проблемой (скорее, так и было задумано), но эти встроенные в шафт кнопки требовали отдельной разводки в ту самую матрицу.
Но самое занятное в том, что эти конкретные "крутилки" двойные, а это значит у них очень много контактов. И дай инженерный бог здоровья тем, кто догадался поставлять их сразу с печатной платой, где все контакты подписаны, и гребёнкой, на которую так удобно коммутироваться таким неопытным монтажникам как я. Но они и стоят... Ну вы читали уже в прошлой главе. Почитайте если ещё не.
Монтаж. Монтаж на печатную плату бывает выводной, поверхностный и смешанный. Я назвал свой монтаж "навесной", потому что нет никакой печатной платы, Карл. У меня довольно крупные кнопки в сборе, ардуинка и ноль опыта в дизайне и производстве печатных плат. Так что я остановился на варианте, когда все элементы управления закрепляются на монтажной панели девайса, а потом нужные контакты просто соединяются проводами. Это звучало проще. Сильно проще. Единственна проблема крылась в том, что та самая аккуратная матрица 4х4 не оставалась квадратной, а нежно размазывалась по панели. И пришлось ещё до сборки прототипа пошевелить мозгами, чтобы аккуратно раскидать все провода и не превратить коммутацию в месиво. И на этапе прототипа, и в финальной сборке это тоже получилось. Я вообще почти доволен тем, как всё улеглось.
Отдельной задачей было оставить панель управления мобильной - чтобы её можно было извлечь, использовать для какого-то другого проекта (а они теперь точно будут после такого то опыта), а потом вернуть всё как было без вреда для самого устройства.
Код. Как я уже описал выше, я потратил довольно много времени на исследование. Я был далеко не первым ,кто собирал подобного рода игровой контроллер, так что почитать было что. Немного, не всегда подробно, но зато много где. И вот так по кусочкам всё и собралось. Библиотеки для клавиатуры и энкодеров, конечно, сильно меня выручили, но в целом пришлось много экспериментировать с маленькими кусочками кода и простыми конфигурациями из пары кнопок и одной крутилки, подбирать параметры. Понимать, как это работает и шаг за шагом проектировать своё устройтво, которое на тот момент вс ещё существовало в виде набросков на бумаге.
К слову, я пошёл по простому пути. Уже в процессе, когда я пытался подключить те самые две кнопки к авиасимулятору, стало понятно, что устройство типа "геймпад" в сыром его виде для виртуальных GNS-530/430 почти бесполезно. Что-то они там в ASOBO намудрили, так что большинство элементов управления нельзя назначить на кнопки игрового контроллера. Нельзя. Точка. И чтобы обойти это ограничение, нужно "общаться" с симулятором напрямую, посылая (и иногда принимая) определённые команды сразу туда, в тёмную зловещую глубину творения Microsoft. Благо, и от этой участи я был чудесным образом спасён. Само собой, кто-то столкнулся с этой проблемой до меня. И кто-то её решил. Как мог. Кто-то написал приложение, которое напрямую программирует Arduino так, чтобы она посылала те самые команды сразу в симулятор. Но, как водится, мне "повезло" - она не поддерживает Arduino Micro. Я бы мог использовать мою Pro Micro, но матричную клавиатуру, описанную выше, это приложение не поддерживает тоже. А переезжать на Mega прямо вот очень не хотелось. Это же всё переделывать. И куча проводов. И элегантно решение с матрицей - в печку. Другие решения тоже не подходили по разным причинам.
Но потом я набрёл-таки на приложение-прослойку, которое позволяет использовать игровой контроллер (коим мой девайс по сути и является и который, как оказалось, не так сложно создать) для отправки тех самых команд. Называется Axis and Ohs. Правда, мне пришлось отдать за него $28. Зато оно работает в фоне, его нужно один раз настроить - и всё работает. Да, это костыль, но мне так было гораздо проще. Помните, я ничего не знаю и почти ничего не умею.
Были ещё мелкие непонятки и проблемы дизайна, но это был момент, когда всё собралось. У меня были все кусочки паззла. Некоторые, правда, существовали только в виде идей и набросков, но и внешний вид, и принцип монтажа, и "начинка", и принцип работы нового девайса были определены. В теории. Определены и протестированы на примере двухкнопочной конфигурации.