Как разрабатываются электронные девайсы
Мы постоянно окружены огромным количеством электроники. Эти маленькие платы с электронными мозгами есть практически везде. Некоторые из них даже подключены к интернету шпионят за нами. Но как они создаются?
Эта статья для тех, кто не имеет опыта разработки электронных устройств, но хочет получить представление о процессе. В этой статье мы с нуля разработаем и изготовим несложное электронное устройство. А все исходники и данные, для самостоятельной сборки, традиционно в конце статьи.
Чтобы продемонстрировать различные технологии в одном устройстве, создадим беспроводную игрушку. Пускай это будет маленький руль, который можно по блютусу подключить к телефону или компу и наклоном управлять, например, машинками в гоночных играх.
Из чего такой девайс будет состоять?
Устройство должно быть автономным, так что у него должен быть аккумулятор. А раз есть аккумулятор, то его нужно заряжать. Так что добавим еще элементы, необходимые для зарядки и USB-С разъем, чтобы было куда воткнуть зарядный кабель.
Руль беспроводной, поэтому нужна блютус антенна. Еще нам нужно определять угол наклона этого руля, для этого необходимы акселерометр и гироскоп, такие же, как стоят во всех мобильных телефонах.
Также будет полезно добавить пару кнопок, чтобы управлять газом и тормозом и пару светодиодов для индикации включения устройства и блютус коннекта.
А теперь самое главное — мозги, которые будут считывать показания датчиков, обрабатывать их и отправлять пакеты данных через блютус антенну во внешний мир. Их роль будет выполнять микроконтроллер.
Вот такой вырисовывается состав:
Еще хочется, чтобы девайс был в форм-факторе брелка и имел минимальный размер. Поэтому будем стараться минимизировать количество и размеры комплектующих.
Все это будет выполнено в виде печатной платы с припаянными к ней компонентами и помещенной в пластиковый корпус. Проектирование платы — наш следующий шаг.
Начинается он с составления принципиальной схемы. Это такая схема, на которой подробно изображаются символы конкретных компонентов и всех электрических связей между ними.
Для составления принципиальных схем есть специальные программы. Я использую Altium designer, но есть множество альтернатив. Приступим.
Начнем с выбора основного компонента — микроконтроллера. Это такая микросхема, которая включает в себя вычислительное ядро, память, систему тактирования и много ножек, через которые она может взаимодействовать с другими устройствами. По сути, это почти полноценный программируемый компьютер, только маленький и потребляющий всего пол ватта мощности.
Их моделей существует огромное множество. От слабеньких 8-битных устройств, состоящих их миллиона транзисторов, до 3-гигагерцовых 64-битных монстров с внешней памятью и десятками миллиардов транзисторов внутри, на которых можно запустить полноценную операционную систему и выполнять триллионы операций с плавающей точкой в секунду. Такие стоят в современных мобильных телефонах, часах и одноплатных компьютерах.
Если бы вы показали такую мощь разработчикам времен первых персональных компьютеров, вас бы сожгли на костре. Однако, многие современные программисты умудряются писать код, который тормозит даже на таком сумасшедшем железе.
Ну, а для нашей простой задачи никаких требований к производительности нет, поэтому подойдет даже самый немощный кусок кремния. Я выберу модель nrf52832 от компании nordic semiconductors. Он гораздо более функционален, чем нужно, но удобен тем, что у него встроенная поддержка работы с протоколом Bluetooth Low Energy, который подойдет для нашей задачи и еще тем, что он у меня уже есть. Остался с одного из старых проектов. Вот он:
Как вообще работает микроконтроллер?
Если снять с него крышку и посмотреть под микроскопом, то мы увидим рисунок из множества блоков, состоящих из десятков миллионов микроскопических транзисторов.
Тут есть область постоянной флэш памяти, в которую мы потом зальем нашу прошивку, вычислительное ядро, выполняющее математические и логические операции, оперативная память, различная периферия для взаимодействия с внешними устройствами, таймеры, область тактирования и питания.
С питания и тактирования и начинается вся магия. Как только мы подали питание на чип, у него запускается тактовый генератор. Он просто генерирует периодические прямоугольные импульсы напряжения, которые нужны для тактирования и синхронизации работы всех блоков.
Но этот встроенный генератор не идеален. Частота повторения импульсов из-за влияния температуры или других условий может немного плавать, а нас такая нестабильность не устраивает, потому что для работы bluetooth критически важна очень высокая точность тактирования. Поэтому нам нужно будет добавить кварцевый резонатор.
По сути это просто кусок кварца определенного размера и формы, с подключенными к его концам двумя пинами. Кварц является пьезоэлектриком, поэтому когда мы подаем на пины напряжение, он немного деформируется, что порождает ответное напряжение.
Кварцевый резонатор без корпуса
Форма кварца на заводе спецаильно сделано такой, чтобы резонансная частота его механических колебаний была заданной — в нашем случе 32 МГц, т.е. 32 миллиона колебаний в секунду. Если подать на него электрический импульс, он будет колебаться ровно на резонансной частоте, как если бы вы механически ударили по камертону.
У контроллера есть специальные контакты, к которым можно подключить такой резонатор и тогда он встроится в цепь генератора тактовых импульсов и будет поддерживать их частоту с очень высокой точностью, независимо от темпаратуры и других условий. Итоговые импульсы распространяются по всем блокам микросхемы и синхронизируют их работу. Грубо говоря, с каждым импульсом ядро контроллера считывает следующую инструкцию из памяти и выполняет ее. Это может быть, например, сложение двух чисел с записью результата в оперативную память или измерение напряжения на одном из контактов чипа или передача сигнала на внешнее устройство.
Все эти инструкции хранятся в памяти в виде бинарного кода или, в простонародии, прошивки. Прошивку мы будем писать на языке С++, превратим в бинарный код, и зальем в память микроконтроллера через программатор.
Для взаимодействия с внешним миром, контроллер может подавать на свои контакты бинарные сигналы в виде последовательностей высокого и низкого напряжения или наоборот считывать уровень напряжения. Например, если мы хотим управлять светодиодом, то подключаем его к одному из контактов и подаем на него высокое напряжение. Тогда он загорится. А если хотим реагировать на нажатие кнопки, то подключаем кнопку и считываем состояние контакта. Если кнопка нажата, то на нем будет низкое напряжение, а если нет, то высокое.
Ну, а для передачи данных между разными цифровыми устройствами, мы можем генерировать или считывать сложные последовательности высоких и низких напряжений.
Чтобы поместить компонент на принципиальную схему, нужно создать его схематичное изображение. У этого контроллера 48 контактов и все они должны быть нарисованы.
Чтобы понять назначение каждой ноги идем на сайт nordic semiconductors и открываем инструкцию на этот конкретный чип. Она содержит 600 страниц, но читать мы их, конечно, не будем. Откроем сразу страницу с назначениями контактов.
Некоторые пины тут отвечают за питание, некоторые за тактирование, некоторые за загрузку прошивки и другие служебные функции, но бОльшая часть — пины общего назначения, к которым мы будем подключать другие компоненты. Также тут есть готовое схематическое ихображение с подписанными контактами.
Открываем редактор компонентов, создаем наш чип под названием nrf52832 и рисуем его изображение с пинами. Для простоты нарисуем его точно таким же, как в документации и подпишем каждую ногу в соответствии с ее обозначением.
Схематическое изображение контроллера в Альтиуме
Готово. Но еще контроллер нужно обеспечить питанием. Для этого потрубуется аккумулятор. Полностью заряженный аккумулятор выдает напряжение 4.2 Вольта. Но микроконтроллеру для питания нужно ровно 3.3В. Если подать больше — он просто сгорит. Поэтому нам нужно каким-то образом напряжение с аккумулятора понизить.
Самое простое решение — использовать специальные микросхемы понижения напряжения. Им на вход подается любое напряжение выше заданного, а на выходе мы получаем стабильное заданное напряжение. В нашем случае — 3.3В. Принцип ее работы заключается в том, что чем больше напряжение на входе, тем большее сопротивление она добавляет в цепь, чтобы понизить напряжение на выходе до нужного уровня. При этом она просто рассеивает часть мощности в виде тепла.
Линейный понижатор напряжения
Типичный корпус маломощного понижатора напряжения. 3 ноги: плюс входа, плюс выхода и общий минус.
Ставим такую микросхему и подключаем ее к аккумулятору. От этой нее мы уже можем запитать наш микроконтроллер, а также другие компоненты, поэтому, чтобы не рисовать много проводов питания, мы просто поставим иконки 3V3 и GND, и будет считаться, что одинаковые иконки соединены друг с другом.
Заодно я сразу подключил светодиод для индикации работы устройства. Если мы его подключим так, то при наличии питания, через светодиод пойдет ток от анода к катоду и он загорится. Синий зигзаг тут — это резистор. Он нужен чтобы ограничивать ток, идущий через светодиод. Без него диод сгорит (падение напряжения на диоде сильно меньше, чем 3.3В).
И еще один светодиод повесил на ногу контроллера, чтобы мы он зажигался по условию, которое мы пропишем в прошивке. Пускай он будет синенький.
Перейдем к датчикам наклона. Акселерометр.
Акселерометр — это датчик ускорения. Упрощенно он выглядит так: внутри него расположен микроскопический грузик на пружинке. Он может отклоняться при наклоне датчика под действием силы тяжести или при ускорении. Встроенная электронная схема подает высокочастотное переменное напряжение между грузиком и стенкой и измеряет ток, который пойдет под действием этого напряжения. А величина тока зависит от расстояния между грузиком и стенкой, таким образом, датчик может вычислить насколько сместился этот грузик. А по смещению можно вычислить и наклон.
Изготавливают их в виде микроскопических чипов. Вот так он выглядит под микроскопом:
Внутренности акселерометра под микроскопом
Две микроскопические подпружиненные гребенки из проводника формируют конденсатор, емкость которого увеличивается при вхождении одной в другую, что измеряется специальным высокочастотным датчиком.
Но все это перестает работать если мы будет трясти девайс в стороны. Грузик смещается, а наклона нет. Так что одного акселерометра нам будет недостаточно. Но есть еще другой тип датчиков — гироскопы.
Гироскоп
Гироскоп измеряет свою угловую скорость, т.е. на сколько градусов в секунду он в данный момент вращается. Иногда для этого используют большие механические установки с тяжелыми маховиками, раскрученными до огромных скоростей.
Но в современной компактной электронике существуют микроэлектромеханические гироскопы размером порядка одного кубического миллиметра. Его принцип действия более интересный. Внутри находится микроскопическое кольцо, которое вибрирует под действием пьезоэлемента и электрической цепи-генератора.
Лиинейные ускорения на него никак не действуют. Но когда мы начинаем его вращать, ось колебаний засчет силы Кориолиса поворачивается на величину, пропорциональную угловой скорости. Этот поворот детектируется встроенной электроникой.
Но гироскоп тоже не дает нам нужной информации, ведь нам нужен угол наклона устройства, а не скорость его изменения. Зато мы можем использовать его для решения проблемы акселерометра. Теперь если мы будем трясти акселерометр, гироскоп будет показывать ноль, что позвоит отличить тряску от наклона и получить чистые данные об угле наклона устройства.
Так что, нам понадобятся и акселерометр и гироскоп. Часто производители датчиков производят в одном корпусе сразу и то и другое. Вот один из таких датчиков от фирмы Bosh. В нем сразу три акселерометра и три гироскопа, расположенные в трех перпендикулярных плоскостях, что позволяет отслеживать вращения по всем трем осям.
Bosh BNO055
Добавим его на нашу схему и подключим питание. Еще мы хотим чтобы на руле были кнопки газа и тормоза. Возьмем простые маленькие кнопки, которые продаются в любом радиомагазине и подключим к микроконтроллеру, чтобы наша прошивка смогла определять их состояния и использовать в своей логике.
Я взял две удобные ноги контроллера и подключил их через резисторы к напряжению питания (3V3) и через кнопки к нулю (GND). Если прошивка будет считывать состояние такой ноги, то получит единицу (высокое напряжение). А когда кнопка будет нажата, она напрямую соединит ногу контроллера с минусом питания и тогда прошивка будет видеть ноль. Таким образом, мы сможем детектировать нажатие кнопки.
Теперь нужно подключить акселерометр с гироскопом к контроллеру, чтобы он мог получать с них данные. Как вообще микросхемы обмениваются информацией друг с другом?
Для этого используются разные цифровые протоколы передачи данных. Один из популярных протоколов называется I2C. Он включает в себя два контакта — по одному передается двоичный код с идентификатором устройства и полезными данными, а по второму — идут синхронизирующие импульсы. На приемной стороне микросхема по каждому импульсу на синхронизационной линии считывает уровень напряжения на линии данных. При этом информация может передаваться в обе стороны.
Кстати, на I2C шину можно повесить более двух устройств. Главное чтобы у них были разные идентификаторы, тогда главный контроллер сможет их опрашивать по очереди.
Наш контроллер и датчики как раз поддерживают этот протокол и для него у них есть специальные контакты. Так что нам ничего не стоит соединить их друг с другом. Чтобы не тянуть линии, можно просто поставить ярлычки для соединения контактов.
Вернемся к аккумулятору. Его нужно как-то заряжать. Зарядка будет происходить через USB, поэтому добавим разъем на схему. Но подключить его напрямую к аккумулятору нельзя, потому что на USB интерфейсе напряжение 5В, а для зарядки аккумулятору нужно 4.2, причем с ограничением величины тока. К счатью, для этого есть специальные микросхемы, которые выполняют такое преобразование. Нам подойдет самая простая, одну из таких и добавим на схему. И светодиодик, чтобы он горел когда идет зарядка.
Переходим к последнему из важнейших компонентов схемы — системе беспроводной передачи данных по bluetooth.
Как я уже говорил, наш контроллер имеет поддержку bluetooth. Это значит, что у него внутри есть почти все необходимое для синтеза высокочастотного сигнала, который будет передаваться в воздух через антенну. Нам нужно только добавить эту антенну и пару согласующих компонентов. И заодно добавим кварцевый резонатор, схему отключения питания для экономии батарейки и различные вспомогательные компоненты, которые нужны для сглаживания пульсаций, управления питанием и разъем для заливки прошивки через программатор.
Итак, принципиальная схема готова. Теперь мы точно знаем какие на плате будут компоненты и как они будут соединены. Пол дела сделано, осталось спроектировать само физическое воплощение платы.
Печатная плата
Печатная плата — это плоский кусок диэлектрика с контактами для припаивания компонентов и медными дорожками, которые соединяют контакты друг с другом. Эти дорожки обычно располагаются не только с обеих сторон платы, но и внутри слоями с множеством переходов, через которые проводник может нырять с одного слоя на другой. Иногда, когда соединений очень много, количество этих слоев исчисляется десятками. Но в нашем случае достаточно будет двухслойной платы.
Первым делом нужно нарисовать посадочные места для припаивания каждого компонента.
Посадочное место микросхемы на плате
Берем документацию на каждый компонент и в точности перерисовываем контактные площадки с соблюдением всех размеров. Дополнительно можно привязать 3Д модель компонента, чтобы потом красиво повертеть плату в 3Д.
Создание посадочное места контроллера в Altium
Все посадочные места рисуются примерно по одному принципу, но отдельного внимания заслуживает антенна.
Часто в портативных устройствах используют покупные антенны вроде таких:
Но мы поступим проще. Нам достаточно эту антенну просто нарисовать.
Фактически антенна — это просто проводник определенной формы и размера, зависящего от частоты излучаемой радиоволны. И мы можем такой проводник выполнить в виде дорожки на печатной плате. Не придется даже ничего покупать и припаивать.
Отрисовка антенны медной дорожкой на плате
После отрисовки всех посадочных мест приступаем к созданию самой платы.
Нажимаем на кнопку и Альтиум берет все посадочные места, которые мы нарисовали, и переносит их на изображение платы. Теперь наша задача правильно расположить их и соединить дорожками.
Альтиум использует принципиальную схему, которые мы составили ранее, чтобы подсказывать какие пины нужно соединить друг с другом дорожками.
Для начала нарисуем примерный контур платы. Он может быть каким угодно, на заводе его будет вырезать автоматический фрезерный станок. Я выбрал прямоугольник размером 20 на 30 мм по размеру типового компактного аккумулятора.
И примерно расположим крупные элементы: кнопки, юсб разъем, антенну, контроллер, разъем для прошивки и т.д. Высокие я расположу на задней стороне платы, а низкие — на передней, потому что на них потом будет лежать плоский аккумулятор.
Ну, а теперь можно расположить все остальные компоненты и приступать к созданию дорожек для их соединения. Дорожки приходится рисовать вручную. Вообще, для этого существуют автотрассировщики, но они пока что работают очень плохо. При разводке нужно учитывать множество нюансов: величины и частоты протекающих токов, паразитные емкости и индуктивности, излучение и поглощение электромагнитных волн, что особенно важно для высокочастотных устройств.
Еще нужно стараться располагать компоненты так, чтобы минимизировать количество пересечений дорожек.
А там, где пересечений не избежать, ставим переходные отверстия на задний слой и продолжаем вести дорожку на другой стороне платы.
Красным цветом помечены дорожки на верхнем слое, синим — на нижнем.
Желтый — шелкография, которая будет нанесена на плату краской.
Наконец, трассировка готова.
Итоговая разводка платы.
А теперь включим режим 3Д визуализации и посмотрим как будет выглядеть наша плата.
Какая красота!
Добавил еще название ютуб канала на слой шелкографии. Эта 3Д модель нам пригодится для проектирования корпуса и 3д печати.
Плата готова, можно отправлять ее на завод для изготовления. Стоит это примерно 30 долларов за 20 штук. Меньше делать нет смысла, потому что это все равно будет стоить 30 долларов. А пока она изготавливается смоделируем красивый корпус.
Корпус
Я попросил нейросеть сгенерить несколько эскизов корпусов. Получилось не совсем то, что я хотел, но думаю, этого достаточно чтобы начать.
Варианты дизайнов корпусов от нейросети
Для 3D моделирования я использую Solidworks. Корпус будет состоять из 4 деталей: основания, крышки и двух кнопок. Важно не забыть сделать отверстия под usb разъем, светодиоды и саморезы.
Детали в Solidworks
Поместим все это вместе с моделькой платы на единую сборку и убедимся, что все нормально стыкуется.
Сборка вместе с платой
Можно приступать к печати.
Печать
Просто скормить эти модельки 3д принтеру нельзя. Нужно сначала нарезать их на слои и превратить в конкретные инструкции для управления моторами и нагревателями принтера.
Это делается очень просто. Загружаем модельки в специальную программу-слайсер, указываем миллиард разных настроек и параметров и нажимаем кнопку «slice». На выходе получаем вот такую визуализацию слоев пластика и g-code, который уже можно скормить принтеру.
Слайсинг моделей
Запускаем печать!
Два часа спустя:
Напечатанные детали
Еще две недели спустя:
Наконец, пришла долгожданная посылка с платами. Посмотрим, что тут.
Изготовленные платы
Можно приступать к пайке компонентов.
Пайка
Обычно для этого используют трафареты, специальные расстановщики и паяльные печи, но для нашей самоделки это было бы слишком жирно. Поэтому просто сделаем все вручную. Наносим паяльную пасту. Затем расставляем компоненты пинцетом и нагреваем паяльным феном до температуры 300 градусов.
Паста плавится и компоненты за счет сил поверхностного натяжения ровно встают на свои места (видео в ютуб ролике в конце статьи).
Плата готова. Первое, что нужно сделать с новой платой — это помигать светодиодом. Для этого нужно написать код и залить прошивку в память микроконтроллера.
Прошивка
Открываем редактор (я для этого использую Visual studio code) и пишем алгоритм мигания светодиодом.
Код мигания светодиодом
Светодиод у нас подклчен к 13 ноге контроллера, поэтому нужно инициализировать эту ногу как логический выход.
Затем запускаем бесконечный цикл, в котором на эту ногу подается высокое напряжение, потом 200 миллисекунд ожидание, подаем низкое напряжение и снова ждем 200 миллисекунд. Вот и весь код.
Контроллер будет раз в 200 миллисекунд менять уровень напряжения на 13-ом выводе.
Подключаем аккумулятор, компилируем код и загружаем прошивку в память контроллера через программатор.
Мигает
Есть! Светодиод начал мигать. Доказательство можно увидеть в видео на канале в конце статьи.
Это значит, что все работает как надо. Теперь можно писать полноценную прошивку. В детали углубляться не буду, просто опишу из каких блоков состоит код.
Первая из многих страниц кода
Тут настройка выводов и периферии, инициализация блютус протокола, создание hid дескрипторов, чтобы девайс воспринимался всеми как геймпад, настройка инерциальных датчиков и кнопок, получение данных с датчиков и отправки хосту и т.д. Проверяем.
Подключение к устройству
Телефон видит Science rock устройство, подключаемся и запускаем приложение для тестирования геймпадов.
Приложение для тестирования геймпадов
Все работает!
Теперь можно поместить плату в корпус и запустить какую-нибудь игру.
Игра Beach buggy racing
Все отлично работает! (видео в ютуб ролике в конце статьи). Но хочется чего-то более осязаемого. У меня как раз завалялось много всякого электронного хлама, из которого можно собрать материальную машинку.
Хлам из сусеков
Готовая машинка
Я запрограммировал ее как хост, к которому можно подключить беспроводной геймпад. Она может ездить в любом направлении, а к кнопкам я привязал вращение.
Видео, в котором подробно описаны все явления и процессы, описанные в статье, и финальный результат:
Исходники платы, кода и 3д моделей на гитхабе.
Спасибо за внимание! Если вам понравилось, подписывайтесь сюда и на ютуб канал, буду рассказывать и о других интересных вещах.