Конструктор для embedded-разработчика
В статье я расскажу о своей попытке создать удобный и красивый модульный конструктив для настольного прототипирования микроконтроллерных устройств
Вступление
Я думаю, что многие читатели, так или иначе, использовали отладочные платы на базе микроконтроллеров для прототипирования разрабатываемых устройств и для того, чтобы начать отладку встраиваемого ПО на этапе, когда полноценная плата устройства еще не готова. К таким платам можно подключить проводами всю необходимую периферию и начать разработку прошивки. Но часто такие отладочные стенды жутко неудобны, они занимают много места на столе, они хлипкие и их не так просто перенести с места на место, а соединения между платами ненадежны.
В этом материале я расскажу, как я в свободное время пытаюсь решить эти проблемы разрабатывая свой собственный гибкий, компактный и красивый модульный конструктив для настольных прототипов.
Модули пока не изготавливались в железе, поэтому я подготовил несколько 3D-визуализаций чтобы разбавить ими текст статьи. Ну что ж, давайте приступим…
Конструктив
Я всегда хотел использовать модули небольших размеров. Настолько, насколько это возможно и разумно с точки зрения размещения на них компонентов законченного функционального узла. В идеале 50×50 мм или даже меньше.
Электрические соединения между модулями должны быть надежными, модули между собой должны надежно скрепляться, чтобы конструктив не разваливался от очередного неосторожного движения за столом и контакты не должны сбоить.
Как обеспечить соединения между модулями?
Ну, например, платы модулей можно подключать разъемами по бокам, укладывая их в одну плоскость. Но такая сборка займет много места и будет уязвима к изгибам. Соединения между модулями по 2 осям сделать тоже проблематично, а все разъемы для внешних подключений придется выводить вверх или вниз. Не очень хороший вариант.
Можно попробовать каскадировать платы модулей по вертикали, а разъемы межмодульных соединений можно вывести вверх/вниз. Распиновка разъемов снизу и сверху совпадает, получается, что все модули параллелятся на общей шине. Разъемы внешних подключений можно вывести в стороны. При этом можно механически скрепить модули, используя латунные стойки.
В результате я пришел вот к такому формату печатной платы модуля:
Формат модуля
Расширение сборки по вертикали это, конечно, хорошо. Но расширение в горизонтальной плоскости всё же тоже необходимо, иначе при большом количестве модулей мы получим узкую и неустойчивую стойку из модулей. Горизонтальное расширение тоже возможно, при помощи плат-хабов. Т.е. в один из ярусов ставится плата-хаб бóльшего размера, кратного размерам модуля (например 2×1, 1×2, 2×2, 3×2 и т.д.). Она имеет все те же межмодульные разъемы сверху и снизу и крепежные отверстия, что и у обычных модулей. Такие хабы позволяют запараллелить модули из нескольких стоек и связать их механически.
Модули HUB_2×1 и HUB_1×2
Очевидные минусы этого решения: плата хаба расходует 1 ярус в сборке, а механическая связь между стойками значительно ниже, чем в одной стойке без хабов.
Версия 1
Прежде чем я продолжу, хочу показать вам промежуточный вариант конструктива, для которого я даже сделал трассировку нескольких модулей.
Первый вариант модуля CPU с размерами 42×42 мм
В нем используются платы размером 42×42 мм. Для межмодульных соединений я использовал 4 разъема 1×11 (мама) сверху и 4 разъема 1×11 (папа) снизу. Шаг — 2.54 мм. Этот дизайн имел много проблем и я даже не знаю почему я их не учёл сразу. Например, мудрёные правила соединения модулей. Чтобы иметь возможность вывести разъемы внешних подключений сбоку, я планировал жертвовать 1 (из 4) межмодульным разъёмом (передний и задний разъемы дублируют друг друга). Такие 3-разъёмные модули используют только контакты переднего/заднего разъемов, поэтому модуль можно разворачивать на 180 градусов с сохранением работоспособности. Но это только всё запутывало.
1-рядные разъемы имели низкую прочность, а 1-рядные мамы с поверхностным монтажом найти вообще не удалось. В итоге предлагалось запаивать сначала верхний разъём, обрезать торчащие снизу штырьки «под корень» и после этого запаять разъём снизу. Но в этом случае качество пайки верхних разъемов будет плохим, примыкание нижних разъемов к плате — плохое, технологичность сборки модуля — плохая.
В целом — это очень плохой дизайн.
Версия 2
Это тот вариант, который мы с вами подробно рассматриваем сегодня. Особенности:
Размеры платы модуля — 40×40 мм. Углы платы скруглены радиусом 6 мм, что позволяет делать аналогичное скругление в корпусе девайса.
Для межмодульного соединения используются 2 разъема 2×10 c шагом 2.54 мм. Разъемы для поверхностного монтажа. Сверху — мамы, снизу — папы.
Межмодульные разъемы определяют расстояние между платами двух соседних ярусов — 12 мм. Латунные стойки такой высоты широко распространены и стоят недорого. При этом стойки не являются обязательными, потому что межмодульные разъемы скрепляют модули довольно хорошо.
Разъемы внешних подключений, а также средства управления и индикации могут выводиться спереди или сзади (бока перекрыты межмодульными разъемами).
Расстояние между контактами двух межмодульных разъемов кратно шагу 2.54 мм, поэтому нижний модуль можно вставить в макетную плату произвольного размера и запаять его туда. Или запаять на макетку 2-рядные разъемы и вставить нижний модуль в них. Это позволяет аккуратно расширять сборку модулей при помощи стандартных макетных плат:
Модуль, припаянный к макетной плате
Размещение в корпусе
Разъёмы внешних подключений располагаются с вылетом на 2 мм за пределы платы. Это нужно чтобы разъемы девайса не были утоплены в корпус и не торчали из него. Корпус со стенкой 1.6 мм может быть напечатан на 3D-принтере, оставшиеся 0.4 мм — зазор между платой и стенкой корпуса.
Латунные стойки, используемые для крепления модулей между собой, могут быть использованы и для крепления сборки модулей в корпусе. В открытом варианте крепления в стойку снаружи корпуса вкручивается винт М3. В скрытом варианте в корпус паяльником вплавляются специальные вплавляемые гайки М3:
дальше прикладывается модуль первого уровня, вкручиваются стойки первого уровня, прикладывается модуль второго уровня и т.д. В разрезе это выглядит так:
Распиновка межмодульных разъёмов
Задача выбора распиновки общей шины в модульном конструктиве — весьма нетривиальна. Если забыть распределить по пинам какие то важные сигналы, то в дальнейшем придётся либо с этим смириться, либо перепроектировать часть модулей (а то и все!).
Но давайте разбираться поэтапно…
Межмодульные разъемы расположены симметрично и механически ничего не мешает подключить очередной модуль, повернув его на 180 градусов. Это, на мой взгляд, скорее плохо, чем хорошо. Я пробовал задействовать эту возможность при проектировании модулей, но в большинстве случаев это приводит к путанице.
Тем не менее, при неправильном подключении точно ничего не должно сгореть. Поэтому пины, ответственные за подачу питания, располагаются так, чтобы при любой ориентации модуля питание подавалось правильно.
Также, как видно из распиновки, используется 2 напряжения питания 3.3V как основное и 5V, которое, в дальнейшем понадобится некоторым будущим модулям (но это не точно).
Остается еще 28 пинов, которые на иллюстрации выше отмечены синим и зеленым цветом. Синие могут использоваться как дискретные или аналоговые, зеленые — только как дискретные.
Я ориентируюсь на микроконтроллер ESP32-S3, названия пинов в распиновке взяты из документации на него, что вовсе не исключает использования в модулях CPU других микроконтроллеров.
ESP32-S3 — мощный и современный микроконтроллер, имеющий интересную особенность — подключение ножек GPIO чипа к цифровым сигналам внутренних периферийных модулей микроконтроллера может осуществляться через программно-конфигурируемую матрицу (GPIO matrix). То есть, например, сигналы CAN_TX и CAN_RX могут быть подключены внутри микроконтроллера к любым его внешним IO-пинам.
Но к аналоговым входам это не относится. 10 каналов ADC1 подключены к пинам IO1…IO10 и ни на какие другие пины микроконтроллера эти каналы повесить нельзя. Ещё 10 каналов ADC2 подключены к пинам IO11…IO20, но ADC2 я в расчёт не беру, потому что, если верить документации, оцифровка ADC2 может завершаться с ошибкой при включенном WiFi. Поэтому в итоге в качестве аналоговых входов могут использоваться пины IO1-IO10.
К сожалению, всё это никак не упрощает задачу распределения сигналов интерфейсов по 28 сигнальным пинам межмодульных разъемов.
Я выбрал следующий подход — я распределяю интерфейсы по пинам постепенно по мере разработки модулей.
Сейчас, например:
пины IO1…IO10 зарезервированы для аналоговых каналов (использование их для цифровых интерфейсов возможно, но может конфликтовать с аналоговыми модулями в сборке);
пины IO18 (SCL) и IO21 (SDA) зарезервированы за I2C, по которому предполагается подключать широкий спектр микросхем и сенсоров — это основной интерфейс для низкоскоростных узлов;
пины IO11 (SCLK), IO12 (MOSI), IO13 (MISO), IO14 (CS1), IO15 (CS2), IO16 (CS3/CE1), IO17 (CS4/CE) зарезервированы для подключения по SPI коммуникационных микросхем и радио-модулей;
пины IO38 (SCLK), IO39 (MOSI), IO40 (MISO), IO41 (DC), IO42 (CS) зарезервированы для подключения по SPI дисплеев.
Все остальные пины пока свободны.
Разработанные модули
Я должен предупредить, что модули ещё не изготавливались в железе. Поэтому всё это — пока наброски. Тем не менее, несколько интересных подробностей о них я могу поведать.
Разрабатывая их, я старался придерживаться нескольких правил, чтобы сборка из модулей была эстетичной и удобной:
Разъемы внешних подключений располагаются на передней или задней стороне модуля в соответствии с тем, где их расположение на устройстве наиболее удобно и логично. В тех редких случаях, когда нужна возможность разворачивать модуль на 180 градусов, эта возможность реализуется перемычками на плате модуля (либо, если противоположные пины не задействованы в собранной конфигурации, то можно перемычки не трогать и обойтись изменениями в ПО).
Разъёмы и индикаторы однотипных модулей (например, модулей PSU) размещаю в одинаковых местах.
Стараюсь не размещать компоненты на плате снизу. Во первых, это не позволит их запаивать автоматизированно при производстве. Во вторых, это увеличивает вероятность конфликтов расположения компонентов двух соседних ярусов.
Большинство чип-компонентов формата 0603. Они достаточно компактные, но ещё не слишком для ручного монтажа.
Модуль CPU_ESP32S3
Модуль CPU_ESP32S3
Модуль построен на микроконтроллере ESP32-S3 от Espressif, который был представлен в начале 2022 года. Это самый навороченный микроконтроллер в современной линейке Espressif, являющийся обновлением ESP32, который появился в 2016 году и более-менее известен разработчикам и распространён.
Если сравнить их, то можно отметить следующие улучшения в ESP32-S3:
Обновлены 2 основных ядра микроконтроллера (Xtensa LX7 вместо LX6). Тест CoreMark показывает прирост скорости в 18.8% по сравнению с ESP32 при одинаковой тактовой частоте. Появилась поддержка векторных инструкций.
При подключении SPI flash (память программ) и SPI PSRAM (внешнее псевдо-статическое ОЗУ) теперь поддерживается 8-битный Octal SPI, который должен дать почти 2-кратный прирост скорости работы с этими микросхемами по сравнению с 4-битным Quad SPI в ESP32.
Используется корпус QFN56 вместо QFN48. Количество GPIO формально увеличилось с 34 до 45, хотя упомянутый выше Octal SPI занимает дополнительные 4 GPIO. Наконец-то исчезли ограничения в некоторых GPIO (например, пины IO34…39 в ESP32 могли использоваться только как входы).
Добавлен 1 x USB Host/Device. USB PHY встроен в микроконтроллер. Device может работать только как USB serial или JTAG.
Добавлен LCD контроллер с аппаратной поддержкой параллельного интерфейса i8080/moto6800 и интерфейса RGB.
Добавлен параллельный DVP-интерфейс для подключения камер.
Bluetooth LE обновлен до 5 версии (был 4.2) + поддержка Bluetooth mesh.
Есть и ухудшения:
Интересно, что в чип ESP32-S3 может быть встроена Quad SPI флешка и Quad/Octal SPI ОЗУ PSRAM. На момент написания статьи Espressif предлагает следующие варианты:
Я не планирую запаивать чипы ESP32-S3 на плату модуля CPU_ESP32S3. Вместо этого будет запаиваться один из модулей, которые продает Espressif (со встроенной антенной или с антенным разъёмом):
Я планирую применять ESP32-S3-WROOM-1-N16R8 и ESP32-S3-WROOM-1U-N16R8. Это модули, на плате которых распаяна QuadSPI флешка объемом 16 Мб и чип ESP32-S3R8 (c 8 Мб Octal SPI ОЗУ внутри чипа).
Что еще есть на плате CPU_ESP32S3:
Разъем USB-C (в качестве USB-Device порта с возможностью внутрисхемной отладки по JTAG через него). Разъем направлен вверх, поэтому модуль в сборке должен располагаться в верхнем ярусе, если нужно обеспечить к нему подключение.
Через порт USB-C может быть запитана вся сборка модулей. 5V с разъема USB-C подаётся через диод Шоттки на шину 5V (падая до 4.8V). Напряжение 3.3V формируется линейным стабилизатором AMS1117-ADJ. Его выходное напряжение настроено на 3.5V, которое через диод Шоттки попадает в шину 3.3V. Диоды нужны чтобы сделать развязку источников питания сборки (которых может быть несколько).
4-пиновый разъём — для прошивки с помощью внешнего USB-UART.
2 кнопки: RESET и пользовательская.
Спереди расположены 5 управляемых RGB-светодиодов (Worldsemi WS2812B-4020) с боковым относительно плоскости платы направлением свечения.
Сзади справа LED-индикатор наличия питания 3.3V.
В следующей ревизии я планирую убрать 4-пиновый разъем и перенести стабилизатор 3.3V на верхнюю сторону платы (возможно, заменив AMS1117 на что-нибудь импульсное и более компактное).
Принципиальная схема CPU_ESP32S3
Модуль ETH_W5500
В ESP32-S3 нет Ethernet MAC, поэтому в модуле используется популярный TCP-IP контроллер WIZnet W5500 с интерфейсом SPI. Схема подключения обвязки — референсная.
В сборку можно включить до 2 таких модулей (запаяв перемычку J5 в разные положения у этих модулей).
В составе ESP-IDF (официальный SDK от Espressif) уже есть драйвер для W5500, который позволяет быстро получить готовый сетевой интерфейс. TCP-IP стек lwIP и ОСРВ FreeRTOS также уже встроены в ESP-IDF, что позволят быстро начать писать свои сетевые приложения с использованием сокетов (или перенести уже написанное для другой платформы ПО).
В модуле ETH_W5500 я использую специфический заниженный разъем RJ45 из-за ограничения по высоте. Такие разъемы не содержат внутри трансформаторов, поэтому применена отдельная сборка трансформаторов L1.
Модуль RTC_PCF8563
Зачем вообще нужен отдельный модуль часов реального времени, ведь RTC уже есть в ESP32-S3? Дело в том, что в официальных модулях WROOM-1 нет отдельного вывода для запитки RTC домена питания от батарейки. Нога VDD3P3_RTC микроконтроллера на плате модуля WROOM-1 подключена напрямую к VDD33.
Почему? Мне не известно. Предполагаю, что с внутренним RTC есть какие-то аппаратные проблемы.
Модуль построен на микросхеме PCF8563 с интерфейсом I2C. Чип RTC я в своё время выбирал по критерию доставабельности из RTC с напряжением питания 3.3V.
Помимо микросхемы часов, на плате размещена микросхема EEPROM объёмом 32 Кб с интерфейсом I2C. Просто на всякий случай.
В модуле применён слотовый держатель батарейки формата CR2032, поэтому батарейку можно поменять не разбирая сборку модулей. При разработке пришлось примерить много разных держателей батарейки, потому что большинство из них не помещается между выводами межмодульных разъёмов. Батарейка не выходит за габариты модуля, а округлая фрезеровка платы в районе батарейки помогает подлезть к ней для замены.
Модуль можно установить батарейкой вперёд или батарейкой назад. При развороте модуля на 180 градусов, нужно запаять перемычки J1 и J2 в соответствующее положение.
Модуль PSU_DC
Модуль обеспечивает запитку модулей от внешнего DC блока питания. Диапазон входных напряжений: 8…45V. Есть защита от переполюсовки диодом на входе.
Входное напряжение сначала понижается до 5V с помощью импульсного Step-Down LM2596, которое подаётся в шину 5V через диод Шоттки (падая до 4.8V). Напряжение 3.5V формируется линейным стабилизатором 1117-ADJ и через диод Шоттки подаётся в шину 3.3V. Диоды позволяют включить в сборку несколько источников питания, которые можно задействовать одновременно (для резервирования).
Сзади справа на модуле расположены 2 LED, сигнализирующих о наличии напряжения на шинах 5V и 3.3V.
Использован популярный среди блоков питания круглый разъем с внешним диаметром 5.5 мм.
Модуль PSU_AC
Модуль обеспечивает запитку модулей от переменного напряжения из розетки. Диапазон входных напряжений — 100…240V. Мощность до 3 Вт. На входе предусмотрен плавкий предохранитель в держателе.
Напряжение 5V формируется готовым AC-DC HiLink HLK-PM01, далее оно подаётся в шину 5V через диод Шоттки (падая до 4.8V). Напряжение 3.5V формируется линейным стабилизатором 1117-ADJ и через диод Шоттки подаётся в шину 3.3V.
AC-DC имеет высоту 15 мм и не помещается в пространство между 2 соседними модулями. Поэтому модуль PSU_AC должен ставиться внизу сборки. К тому же там для него в корпусе проще обеспечить охлаждение и можно попытаться обеспечить облегчённый доступ к предохранителю.
Сзади справа на модуле расположены 2 LED, сигнализирующих о наличии напряжения на шинах 5V и 3.3V.
Примеры сборок
Пока готовых модулей немного и сборок собрать можно тоже немного, но тем не менее, давайте взглянем…
1. CPU_ESP32S3 + PSU_DC
Устройство на базе мощного 2-ядерного микроконтроллера с ОЗУ 8 Мб, WiFi, Bluetooth LE, 5 RGB LED спереди, с USB-C (Device) портом и питанием от розетки.
Габариты: 40×40x43 мм
CPU_ESP32S3 + PSU_DC
2. CPU_ESP32S3 + ETH_W5500 + RTC_PCF8563 + PSU_DC + PSU_AC
Устройство на базе мощного 2-ядерного микроконтроллера с ОЗУ 8 Мб, WiFi, Bluetooth LE, 5 RGB LED спереди, с USB-C (Device) портом, 1 портом Ethernet, RTC, EEPROM 32 Кб и 2 вариантами запитки (для резервирования) — от розетки и от источника DC.
Габариты: 40×40x85 мм
CPU_ESP32S3 + ETH_W5500 + RTC_PCF8563 + PSU_DC + PSU_AC
3. CPU_ESP32S3 + 2xETH_W5500 + HUB_1×2 + RTC_PCF8563 + PSU_DC + PSU_AC
Устройство на базе мощного 2-ядерного микроконтроллера с ОЗУ 8 Мб, WiFi, Bluetooth LE, 5 RGB LED спереди, с USB-C (Device) портом, 2 портами Ethernet, RTC, EEPROM 32 Кб и 2 вариантами запитки (для резервирования) — от розетки и от источника DC.
Габариты: 81×40x71 мм
CPU_ESP32S3 + 2xETH_W5500 + HUB_1×2 + RTC_PCF8563 + PSU_DC + PSU_AC
Планируемые модули
Модуль PSU с аккумулятором формата 18650 (вертикально) и контроллером зарядки и возможностью чтения состояния по I2C.
Радио-модули: RF до 1 ГГц, NRF24, LoRa, GSM, GPS и т.д.
Модули с разнообразными сенсорами-измерителями.
Модули для вывода промышленных интерфейсов: CAN, RS232, RS485 и т.д.
Модули с дискретными входами/выходами.
Модули с аналоговыми входами/выходами по напряжению/току.
Модули с небольшими OLED и IPS дисплеями на передней стороне.
Модули с кнопками или джойстиком на передней стороне.
Хабы разных размеров.
Концовка
Я буду признателен за любое мнение и критику в комментариях.
Сейчас проект находится на этапе, когда еще не изготовлены первые платы, а разработка большинства модулей ещё впереди, поэтому почти любые ошибки ещё можно исправить, а решения — улучшить.