Хабрахабр

Я у мамы не инженер

intro

Я уже сбился со счёта часов, которые я потратил на то, чтобы сделать “небольшую коробочку” и вдруг я поймал себя на мысли, что я очень зауважал инженеров — людей, который умеют и могут проектировать и создавать новые вещи. В голове сразу нахлынули воспоминания об устройствах, который я разбирал в детстве (да и не только). Эти забавные ситуации, когда при откручивании последнего болтика, как чёрт из табакерки, вылетало несколько мелких пружинок и деталек, которые было совершенно невозможно упаковать обратно.

Тогда я ещё и подумать не мог, сколько же времени потребуется, чтобы все эти мелочи собрались в одно целое…
Меня всегда привлекала идея создания чего-то нового — что-то такого, чего не так часто получается делать в повседневной суете. Однажды я решил сделать небольшое устройство (“Security Access Tuner” из игры Alien: Isolation) — контроллер, экран, пара элементов управления, да упаковать это всё в небольшой корпус, который планировалось напечатать на 3d принтере. Не знаю, что именно послужило толчком к созданию именно этого устройства, но в один из дней я так и подумал: “А почему бы не сделать security access tuner из игры Alien: Isolation”.

Это устройство вводит в игру механику мини игр. В игре есть некое устройство для “взлома электронных замков”. Не стану утомлять вас подробностями игрового процесса, т.к. Тут уж выбирайте мемасик себе по вкусу, но это что-то между “Мы добавили игр в твою игру, чтобы ты мог играть в игры, играя в игру” и “We need to go deeper!”. Просто условимся, что есть некоторое карманное устройство с играми, которое я решил реализовать. каждый желающий может узнать о том, что это за “зверь” в деталях, написав название в любимом поисковике.

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

AccessTuner

Скриншот из игры, устройство находится в руках персонажа.

В первой (та, что на картинке сверху) нужно за отведённое время выбрать символы в том порядке, в котором они отображены на экране. Итак, нужно сделать небольшое устройство с играми и этих самых “мини игр” — две. Вторая игра на реакцию и нужно просто вовремя нажимать на кнопку (не стану заострять не ней внимание, т.к. Игра не сложная, если привыкнуть, но поначалу заставляет задуматься. Помимо игр есть ещё несколько экранов состояние, переходов между играми и просто «Please wait...». ничего особенного в ней нет).

И вот в один из дней, вдохновение напало на человека с наличием свободного времени и для этой парочки (платы и экрана) нашлось применение… По удачному стечению обстоятельств, у меня без дела лежала плата от Texas Instruments — Tiva C (аналог Arduino) и экран для неё же.

Разработка

Я сразу решил для себя, что “вишенкой на торте” в этой задумке будет не программная часть, а именно инженерная. Я хотел сделать и собрать устройство так, чтобы всё было компактно, функционально, логично и удобно (спойлер: всё оказалось не так просто).

Поэтому, для того, чтобы воплотить идею в жизнь, я начал с того, что мне ближе всего — с программной части. Программирование — это то, чем я зарабатываю на хлеб и я понимал, что серьёзных “вызовов” программная часть предоставить не сможет.

Хоть сколько интересной частью программной реализации был вывод графики на экран. Обработка событий от кнопок и поворотного энкодера (rotary encoder) совершенно банальны и я не вижу смысла что либо рассказывать об этом. В основном, “проблемными” частями были: Точнее даже не сам вывод, а скорее совокупность действий, которые были необходимы, чтобы на экране появилось то, чего я хотел.

  1. Память устройства ограничена и много картинок (спрайтов) в память устройства сложить не получится.
  2. Экран работает с цветами в формате 565 (два байта на цвет), т.е. для всей графики, нужно делать конвертацию в конечный формат, но ввиду ограничения памяти, в памяти устройства не получится хранить все необходимые изображения в таком формате.
  3. Экран обновляется с ошеломительной частотой ~1 кадр в секунду, если необходимо перерисовывать весь экран.

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

На основе этих самых спрайтов была реализована вся графика (в том числе и текст), если не считать пару исключений:

  • Логотип вымышленной компании производителя (Seegson), который использует палитру из 16-и цветов (т.е. 2 пикселя в одном байте). Мне захотелось чуть больше красоты при включении устройства и я добавил его уже в самом конце разработки, т.к. оставалось ещё немного памяти.
  • Были реализованы функции для рисования графических примитивов (например, прямоугольников, а в интерфейсе, который я пытался повторить, их много).

Проблему частоты обновления экрана, программно было решить не так уж и просто. Особенно для мест, где нужно обновлять данные на экране достаточно часто.

“чем меньше, тем лучше”. К счастью, проблема была не в самом экране, а в медленной шине данных (SPI шина), поэтому нужно было просто поберечь штаны и не шагать так широко — рисовать только то, что реально необходимо, т.е.

Прорисовка интерфейса была разбита на три части, чтобы решить проблему частоты обновления:

  • Начальная прорисовка (тут рисуется всё то, что остаётся неизменным — фон и статичные элементы интерфейса). Этот этап занимает почти секунду, но происходит только при смене экранов и эта секунда не так и заметна.
  • Анимации, которые не зависят от действий пользователя (состояние таймера обратного отсчёта, помехи и прочее). Обычно это небольшие изменения — не более 15% экрана, что даже в таком случае позволяет обновить экран не реже 6 раз в секунду (на деле частота обновления значительно выше и задержки незаменты). Исключением был лишь экран с помехами — о нём я расскажу чуть ниже.
  • Анимации, которые зависят от действий пользователя (положение ползунков или рамка вокруг выбранного символа). Эти события происходят не так часто, т.к. при всём желании, пользователь не сможет нажимать на кнопки быстрее, чем состояние способен перерисовывать экран.

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

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

Рисование начинается сверху. Экран делится на две части (левая и правая сторона).

  1. Случайным образом выбирается часть экрана (левая или правая сторона).
  2. В рамках этой части рисуется полоска случайных чёрно-белых точек. Этот экран имеет две базовые операции для работы с ним (если не считать операции инициализации) — операция записи в буфер экрана и операция перемещения указателя в рамках этого самого экранного буфера. Причём, по непонятной мне причине, операция перемещения указателя работает ощутимо медленнее, чем операция записи. Таким образом, для этого экрана, последовательная запись в буфер экрана позволяет закрасить весь экран примерно за 0.75 секунд, а выполняя закрашивание каждого пикселя отдельно, потребуется почти за вдвое большее время (1.4 секунд). Именно из-за этой особенности рисуются полоски чёрно-белых точек, а не просто случайные пиксели.
  3. Переходим к следующей вертикальной полоске на экране и повторяем действия описанные в 1 пункте.

Когда все вертикальные строки нарисованы, то прорисовка продолжается заново сверху. В результате наложения одних чёрно-белых точек на другие, совершенно не заметно то, что экран по сути “закрашивается полосками” вот так (первые 20 случайных прорисовок):

Рисование шума

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

Для того, чтобы было проще представить, можем считать, что у нас в руках аналог радиоприёмника. В интерфейсе был нужен ещё один довольно любопытный элемент — индикатор выбранной радио частоты. На экране рисуется индикатор этой самой частоты, который может обойти полный круг по экрану и вернуться обратно в начальное положение. Есть колёсико настройки, которое можно крутить по кругу, чтобы найти (выбрать) нужную частоту. Индикатор в интерфейсе представляет собой треугольник (на деле это не совсем так, но для простоты отображения, условимся, что это треугольник), который вращается вокруг одной из вершин, расположенной в центре экрана:

Индикатор - треугольник

Серым цветом на картинке отмечены границы экрана.

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

Индикатор

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

Поэтому рисовались только отдельные фрагменты индикатора (две скошенные границы и прямоугольник, что соединяет их), а предыдущее состояние индикатора “стиралось” (красный цвет на картинке) перед прорисовкой: Задача сама по себе не сложная, просто её решение “в лоб” с перерисовкой всего экрана снова недопустима.

Индикатор - прорисовка

для этого самого индикатора была добавлена функция рисования прямоугольника, который разделён по диагонали и закрашен двумя цветами (один цвет с одной стороны относительно диагонали и другой цвет со второй стороны). Т.е. Индикатор представлял собой два таких элемента (отмечены цифрой 1 на картинке) и прямоугольники соединяющие их (отмечены цифрой 2):

image

Ширину (или высоту) этого элемента определяет смещение относительно центра экрана. Так, когда индикатор находится в самом центре экрана, рисуется только прямоугольник (2), а при смещении индикатора ближе к краю экрана ширина элементов (1) увеличивается. Когда индикатор находится у краёв экрана, то при прорисовке добавляется ещё один прямоугольник:

image

Пожалуй на этом и заканчиваются все “интересности” программной части и я могу перейти к тому, что же заставило меня так сильно зауважать инженеров…

Не инженер

Несмотря на то, что в университетском дипломе у меня написано, что я “инженер компьютерных наук”, на деле я осознал, что я “всё что угодно компьютерных наук”, но не инженер. Я понимаю, что у слова “инженер” довольно широкое определение и в наше время вообще очень часто получается, что тот, кто не менеджер, тот инженер.

И в моём понимании, я не совсем инженер. Говоря “инженер”, я имею ввиду людей, которые умеют и могут планировать, проектировать, конструировать и разрабатывать. Инженерные задачи (речь идёт о корпусе устройства и основных его компонентах), которые я оценил, как вполне себе простые, заняли такое количество часов, которое я и предположить не мог. В этом вопросе я любитель — мне нравится придумывать и реализовывать что-то, но нельзя сказать, что у меня это всегда получается. Я не знаю точного времени, но решил считать, что люди не придумали чисел, которыми можно было бы описать столь огромные величины.

Тогда я до конца не понимал зачем он это говорил так часто, но именно в процессе создания этого устройства я понял, как же важно отмерить семь раз перед тем, как принять решение в пользу одного или другого варианта. В детстве, отец часто повторял мне поговорку “Семь раз отмерь, один раз отрежь”. Если бы я слушал папу, то не пришлось бы делать так много проб и ошибок.

Я решил, что полноценное колесо прокрутки я делать не буду, т.к. Итак, у устройства, с левой стороны должно быть колёсико прокрутки, которое можно вращать вверх (или вперёд), чтобы выбрать следующий символ на экране или вращать вниз (назад), чтобы выбрать предыдущий символ. для поворотного энкодера (rotary encoder) или чего-то похожего потребовалось бы куда больше места в корпусе, да и для перехода “вперёд” / “назад”, более логичным решением показались именно кнопки.

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

Идея рычага

Идея казалась мне до безумия простой, но вместе с ней появилась масса вопросов (на которые люди, занимающиеся проектированием устройств, скорее всего бы имели готовые ответы) на которые у меня не было ответов. А вопросы были следующие:

  • На чём и как крепить кнопки? На картинке сверху ведь они просто “болтаются в воздухе” и в конечном устройстве так быть не может.
  • Нужно ли думать о механизме для возврата рычага на центр? Нужны ли пружины или хватит упругости кнопок?.
  • Как вставить рычаг в корпус так, чтобы отверстие в корпусе было максимально незаметным? Будет ли рычаг одной деталью или несколькими?
  • Как будет крепиться ось? Будет ли ось частью корпуса или отдельной деталью?
  • Как убедиться, что то, что “работает на бумаге”, будет работать после печати на 3d принтере?

И я уверен, что есть куча готовых решений, а у китайцев скорее всего можно заказать что-то вроде «Модуль рычага кнопки мода инженерное запах женщины» в красивой коробочке. Я знаю и о готовых инструментов (редакторов) для создания подобных решений, но ради спортивного интереса, я решил “изобретать колесо”, придумывать всё сам и обойтись только базовыми инструментами, которые “были под рукой”.

Проверял прочность разных размеров оси, соединений и стенок, проверял возможность создания рычага из нескольких частей (чтобы упростить размещение рычага в корпусе). Я придумывал прототипы разных вариантов этого рычага и проверял их в деле. Думал над тем, как это всё ляжет в корпус.

Меня не покидало ощущение того, что я «котёнок на ламинате» — пока вокруг, в каждом чайнике, всё так элегантно и удобно, а все мои прототипы были какими-то корявыми и «недодуманными». Каждый раз, собирая очередной прототип, я вспоминал про все эти включатели / кнопочки и рычажки, которые окружают нас в повседневной жизни. казалось всё было бы отлично собралось, если бы размеры были чуть побольше, но приходилось придумывать решение в рамках того места, которое было доступно в корпусе. Каждый мой прототип собирался “еле-еле” (если собирался вообще), т.е. Это и был тот момент, который я упоминал в самом начале:

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

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

  • В корпусе будет отдельное место под кнопки, кнопки снизу будет удерживать дополнительная деталь.
  • Рычаг в центр будет возвращаться за счёт упругости кнопок (благо ход у рычага очень маленький и его смещение относительно центра не особо и заметно). К тому же у рычага очень маленький вес, что позволяет не беспокоиться о том, что под весом рычага кнопка будет нажата.
  • Рычаг будет одной деталью (т.е. не будет собираться из нескольких частей) и вставляться он будет сверху. Отверстие будет такого размера, чтобы свободно проходила одна из “ног” рычага, после этого рычаг будет сдвигаться, чтобы “просунуть вторую ногу”.

    Вставляем рычаг

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

Блок рычага собирался следующим образом (оранжевый — рычаг, полупрозрачная стенка и серая деталь — части большого корпуса, а зелёная — дополнительная деталь для фиксации кнопок и осью рычага):

Сборка блока рычага

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

Отверстие под рычаг

Я догадываюсь, что это далеко не самое элегантное инженерное решение в мире, но в данном решении, для мне всё было “вымерено” до миллиметра. Будь ширина детали чуть меньше и не хватило бы прочности — появлялся бы люфт (да и я серьёзно сомневаюсь, что работать в ещё меньшем масштабе было бы удобно). Если оставить чуть больше места “для манёвров” или сделать стенки детали чуть толще и на своё законное место не влезет экран.

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

Прототипы

Когда я рассказываю кому-либо похожие истории, люди не воспринимают меня всерьёз. Основным ответом на моё заявление о моей “пониженной инженерности” было: “Ну что ты рассказываешь сказки? — Ведь всё ведь работает, да и смотрится не хуже фабричного производства!”.

Для 3d моделирования я использовал online редактор, который не стану называть вслух (чтобы пост не сочли за рекламный). Итак, я уже говорил, что использовал лишь инструменты, которые были под рукой. с ним я был знаком и мог начать работать сразу. Этот самый редактор не слишком хорошо подходит для моделирования сложных объектов, но меня он полностью устраивал, т.к. В этом редакторе нет возможности напрямую работать с вершинами или нормалями — только со всем объектом целиком. Если мне нужно было бы описать его функционал, то я бы сказал, что это такой MS Paint из мира 3d моделирования — только базовые операции, только хардкор.

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

Модель для печати

Но дьявол кроется в деталях, поэтому, давайте взглянем на все те “шрамы”, которые оставил человек с “неинженерной костью” на несложном корпусе устройства:

Модель вблизи

На изображении показано место расположения того самого рычага о котором я говорил чуть выше.

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

это смещения / несоответствия в масштабе меньше 0. Конечно, на конечном устройстве это никак не сказалось, т.к. 1мм и точность 3d печати не так высока, чтобы это было заметно.

Вот ещё одно место, где в корпусе делался “паз” под экран:

Паз под экран

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

Этот элемент нужен для того, чтобы экран не болтался в корпусе. Экран должен заходить в это углубление и оставаться там. В общем, нужно было слушать папу и семь раз отмерить перед тем, как рисовать паз и не пришлось бы его несколько раз переделывать. В идеале, тут должно было быть отверстие (паз) в форме точно вымеренного параллелепипеда, но видно, что что-то пошло не так и форма углубления менялась несколько раз. И я знаю, что можно было бы всё это привести в порядок, но средствами того самого редактора — это боль.

Для этого в корпусе я предусмотрел место под гайки: Ну и наконец, крышка корпуса… Крышка крепится к корпусу четырьмя болтами M3.

Место под гайки

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

Знающие люди сразу заметят, что нужно было думать о том, с какой стороны будет удобнее вставлять гайку… В результате я потратил немало времени на то, чтобы самым противоестественным образом (и дело тут не в моих странных предпочтениях, а в глупом расположении отверстий), пинцетом “всунуть” гайки в отверстия. Добавляя эти самые отверстия, я исходил из мысли “как было бы удобнее всего сделать отверстия в модели”.

И тут во мне проснулся художник

Настал день X, когда все подготовительные работы подошли к концу и пришло время распечатать детали, собрать всё вместе и покрасить.

image
Самый первый этап — печать корпуса и отрывание поддержек (supports).

Как видно по фото (а я надеюсь, что видно), качество печати недостаточно высоко, чтобы было можно просто покрасить корпус, поэтому следующим шагом было так любимое мной “доработать напильником до нужной формы”:

image
По мере шлифования корпуса, я отмечал “проблемные места” крестиками.

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

image
Остались непрокрашенные участки в углублениях, но они закрасятся позже.

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

image
Тут появилось и защитное стёклышко для экрана — оргстекло со сточенными краями.

Помимо самого корпуса, было необходимо распечатать россыпь мелких декоративных деталей, которые должны были дополнить конечный вид устройства:

image
Экран заработал пару царапин, пока валялся вместе с остальными деталями, поэтому был “упакован” в полиэтилен до лучших времён.

Некоторые детали нужно было склеить между собой и покрасить, чем я и занялся:

image

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

image

image

image

image

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

Ну и пара картинок “в работе”:

image

image

image

image

Ну и работает это всё примерно вот так:

image

Послесловие

В целом, как и обычно, то, что я хотел бы сказать этой историей — это то, что не стоит бояться делать что-то своими руками, не стоит бояться придумывать что-то новое (читать, как “костыли и велосипеды”). И даже если у вас «неинженерная кость», вы сможете узнать много нового и просто забавно провести время.

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

Спасибо всем, кто дочитал до конца.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть