Микроконтроллеры для начинающих: как устроена embedded-разработка

Микроконтроллер (МК) — это не просто «маленький компьютер», а специализированный чип, в котором на одном кристалле уже собраны процессор, память и набор периферийных блоков. В типичном случае внутри есть CPU, Flash для хранения прошивки, RAM для рабочих данных, таймеры, интерфейсы вроде UART/I2C/SPI, АЦП и GPIO. В отличие от обычного ПК, микроконтроллер изначально рассчитан на работу с реальным железом: датчиками, кнопками, реле, моторами, дисплеями, линиями связи. И чаще всего — без привычной настольной ОС вроде Windows или Linux.

Именно поэтому embedded-разработка ощущается иначе, чем прикладное программирование на десктопе. Здесь вы работаете в условиях ограниченных ресурсов и напрямую отвечаете за поведение устройства. Для типичных МК это может быть 32–256 КБ Flash, 2–64 КБ RAM и частота 8–200 МГц. На таком железе уже нельзя бездумно тащить тяжелые абстракции, бесконечно логировать всё подряд или разбрасываться динамической памятью. Каждое решение — от структуры данных до способа опроса датчика — влияет на стабильность.

Почему это важно на практике? Потому что в IoT, промышленной автоматике, робототехнике, носимой электронике и автономных устройствах микроконтроллер — это основа системы. Даже если сверху у вас Raspberry Pi, Linux и модель компьютерного зрения, нижний уровень обычно всё равно держится на МК: он следит за питанием, опрашивает сенсоры, управляет исполнительными механизмами и обеспечивает предсказуемую реакцию в реальном времени. Без этого никакой edge AI не будет по-настоящему надежным, особенно если устройство должно жить на батарейке, переживать помехи и работать в полевых условиях.

Я сам начинал со STM32 в задачах сбора данных с акселерометров. Очень быстро становится понятно, что в embedded каждый байт и каждый тайминг имеют значение. На ПК можно компенсировать слабую архитектуру ресурсами, а на микроконтроллере приходится думать вперед: где хранить буфер, как часто читать датчик, не заблокирует ли одна функция всю программу и что произойдет, если придет прерывание в неудобный момент.

Ключевые плюсы МК для новичков:

  • Низкая цена (от 50 руб. за ATmega).
  • Простота старта: подключи USB, пиши код.
  • Масштаб: от лампочки до edge AI с TinyML.

На старте это особенно удобно: можно быстро собрать первый рабочий проект, а затем постепенно переходить от «мигалки» к системному мышлению — таймерам, прерываниям, обмену по шинам, энергоэффективности и, если нужно, запуску небольших ML-моделей на устройстве.

Популярные микроконтроллеры: сравнение для первого выбора

Выбор первого микроконтроллера почти всегда зависит не только от характеристик, но и от экосистемы вокруг него. Для новичка это критично. Хорошая документация, живое сообщество, адекватные библиотеки и понятный способ прошивки экономят больше времени, чем лишние 20 МГц или пара десятков килобайт памяти. Поэтому для старта разумно смотреть в сторону Arduino-совместимых плат, ESP32 или STM32.

Если говорить по-инженерному, выбирать МК стоит не «по популярности», а по классу задач: нужен ли Wi-Fi, требуется ли точное управление таймингами, насколько важны энергопотребление, USB, количество GPIO, скорость АЦП, наличие DMA и удобство отладки. Но для первого проекта лучше не усложнять и взять платформу, на которой можно быстро пройти полный цикл: написал код → прошил → увидел результат → отладил.

Микроконтроллер Архитектура Память (Flash/RAM) Цена (руб.) Когда выбрать Пример проекта
Arduino Uno (ATmega328) AVR 8-bit 32 КБ / 2 КБ 500–1000 Обучение, прототипы Светодиодный мигалка, датчик температуры
ESP32 Xtensa 32-bit dual-core 520 КБ / 320 КБ + PSRAM 300–600 Wi-Fi, Bluetooth, IoT Умный термостат с веб-интерфейсом
STM32F103 (Blue Pill) ARM Cortex-M3 32-bit 64–128 КБ / 20 КБ 200–400 Реальные задачи, скорость Управление сервоприводом, UART с ПК
Raspberry Pi Pico (RP2040) ARM Cortex-M0+ dual-core 2 МБ / 264 КБ 400–700 GPIO, USB, низкое потребление MIDI-клавиатура или сенсорный экран

Если кратко по ощущениям из практики:

  • Arduino Uno хорош, чтобы понять саму механику embedded: пины, задержки, кнопки, простые датчики. Но 2 КБ RAM быстро заканчиваются, особенно если добавить строки, дисплей и пару библиотек.
  • ESP32 очень удобен, когда нужен быстрый результат в IoT: Wi-Fi и Bluetooth уже на борту, есть приличный запас ресурсов, можно поднимать веб-интерфейс, API-клиент или отправку телеметрии в облако.
  • STM32F103 — отличный вход в более «настоящую» embedded-разработку. Здесь уже чувствуется работа с тактированием, регистрами, периферией и отладкой не на уровне «скетча», а ближе к промышленному подходу.
  • RP2040 интересен своей гибкостью, хорошим набором GPIO и удобством для USB-проектов. Отдельный плюс — PIO, который помогает реализовывать нестандартные интерфейсы, хотя новичку это не всегда нужно сразу.

Совет от практика: Начните с ESP32 — там Wi-Fi из коробки, можно сразу слать данные в облако для ИИ-анализа. Я использовал его в проектах с камерой OV2640: не для тяжелого инференса на устройстве, а как для захвата данных, предобработки и передачи кадров или признаков дальше по пайплайну. Это хороший пример того, как embedded и прикладной ИИ встречаются в реальных системах.

Но если ваша цель — глубже понять именно микроконтроллерную архитектуру, таймеры, прерывания и периферию, STM32 часто оказывается полезнее, чем Arduino-подобный слой абстракции. В идеале путь выглядит так: быстро стартуете на Arduino/ESP32, а затем переходите на более низкий уровень и начинаете осознанно управлять железом.

Среда разработки: инструменты без лишней головной боли

Embedded-разработка начинается не с пайки и даже не с покупки платы, а с нормального toolchain. Если среда настроена плохо, вы будете тратить время не на код и отладку логики, а на борьбу с загрузчиком, драйверами, путями к компилятору и непонятными ошибками линковки. Поэтому лучше сразу собрать минимально удобный стек инструментов.

Здесь важно понимать разницу между «код написал» и «проект сопровождаем». Для учебного примера Arduino IDE хватает. Но как только появляются несколько файлов, сторонние библиотеки, Git, разные конфигурации сборки и необходимость воспроизводить проект на другой машине, становится заметно, что удобная среда — не роскошь, а часть инженерной дисциплины.

Рекомендуемые инструменты

  • Arduino IDE/PlatformIO: Для новичков. Устанавливаете, выбираете плату, пишете sketch. PlatformIO в VS Code — топ для Git и библиотек.
  • STM32CubeIDE: Бесплатно от ST. Генерирует код для периферии (TIMER, ADC).
  • Keil uVision или IAR: Профи-уровень, но пиратят. Для open-source — GCC ARM.
  • Отладка: ST-Link (100 руб.) или J-Link. Подключаете к SWD/JTAG, смотрите регистры в реал-тайм.

На практике я бы добавил такой комментарий. Arduino IDE хороша, чтобы не утонуть в деталях на старте, но для более серьезной работы PlatformIO заметно удобнее: нормальная структура проекта, управление зависимостями, интеграция с VS Code, понятные конфигурации окружений и возможность автоматизировать сборку. Когда проект начинает жить в Git и его нужно передавать другому разработчику, это окупается очень быстро.

STM32CubeIDE полезен тем, что помогает быстро поднять периферию без ручного копания в регистрах: выставили тактирование, настроили UART, таймер или ADC, сгенерировали заготовку кода и пошли дальше. Да, к автогенерации кода у опытных embedded-разработчиков отношение бывает осторожное, и не без причин. Но для старта это хороший способ увидеть систему целиком: clock tree, пины, DMA, NVIC, таймеры и прерывания в одном месте.

Отладчик — вообще один из самых недооцененных инструментов у новичков. Когда вы можете поставить breakpoint, посмотреть стек вызовов, значения регистров и понять, в какой момент программа ушла не туда, качество разработки меняется кардинально. Логирование по UART полезно, но оно не заменяет полноценную отладку по SWD/JTAG.

Шаги установки для ESP32:

  1. Установите PlatformIO в VS Code.
  2. Создайте проект: platformio init --board esp32dev.
  3. В platformio.ini добавьте lib_deps = ArduinoJson.
  4. Загрузите: pio run --target upload.

После установки обязательно сделайте самый простой тест: помигайте встроенным LED на пине 2. Это кажется банальностью, но такой тест сразу проверяет несколько вещей: корректно ли определяется плата, работает ли загрузка прошивки, верно ли настроен COM-порт и нет ли проблем с питанием. В embedded всегда полезно валидировать систему по слоям — от минимального рабочего примера к более сложной логике.

Если работает LED, следующим шагом обычно стоит проверить UART-логирование. Как только вы получили стабильный вывод в Serial, жизнь становится проще: можно печатать значения датчиков, коды ошибок, результаты инициализации и быстро локализовать, на каком этапе прошивка ломается.

Как устроена прошивка: от кода к железу

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

После старта микроконтроллер выполняет код инициализации: настраивается тактирование, память, таблица векторов, периферия, пины, иногда watchdog, DMA и базовые драйверы. Затем управление переходит в основной цикл. В простых проектах это бесконечный while(1), внутри которого выполняются периодические задачи. Если происходит внешнее событие — например, пришел байт по UART, сработал таймер или изменилась линия на входе — управление может временно перейти в обработчик прерывания.

Базовый цикл embedded

Классическая схема выглядит так:

  • init — настройка тактирования, GPIO, интерфейсов, таймеров, АЦП и прочей периферии;
  • main loop — основной цикл, где выполняется прикладная логика;
  • interrupt handlers — реакция на асинхронные события.

В простом проекте это может быть опрос кнопки и мигание светодиодом. В более реальном — чтение данных с датчика по I2C, фильтрация измерений, управление PWM на моторе и отправка телеметрии по UART или Wi-Fi. Снаружи всё выглядит линейно, но важно помнить: микроконтроллер живет во времени. Если одна функция неожиданно блокирует CPU на 200 мс, это уже может сломать обмен по интерфейсу, пропустить событие или испортить управление.

Пример на C для STM32 (HAL):

Обычно такой код включает вызовы вроде HAL_Init(), настройки системного тактирования, инициализации GPIO и затем бесконечный цикл с вызовами HAL_GPIO_TogglePin() и HAL_Delay(). Это хороший стартовый шаблон, чтобы понять последовательность выполнения: сначала железо приводится в рабочее состояние, затем запускается логика приложения.

Но в реальных прошивках очень быстро приходится отходить от задержек в стиле HAL_Delay(). Они удобны для первого теста, но плохо масштабируются. Как только нужно одновременно читать датчик, обслуживать интерфейс и управлять выходами, блокирующие задержки начинают мешать. Поэтому дальше обычно переходят к таймерам, флагам событий, state machine или RTOS, если задача того требует.

Почему прерывания важны? Без них МК тратит CPU на постоянный опрос. В реальном проекте (датчик + мотор) — используйте TIM для PWM, EXTI для кнопок.

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

  • таймер формирует точный период измерений;
  • UART RX interrupt принимает данные без постоянного polling;
  • EXTI реагирует на кнопку или внешний сигнал сразу, а не когда цикл дойдет до очередной проверки.

Из практики: начинающие часто перегружают обработчики прерываний и пытаются выполнять в них половину бизнес-логики. Это плохая идея. Обработчик должен быть коротким: зафиксировать событие, сохранить байт в буфер, поднять флаг. Основную обработку лучше уносить в main loop или отдельную задачу. Иначе получаются трудноуловимые ошибки по таймингам и приоритетам.

Память и оптимизация

  • Flash: Код + константы.
  • RAM: Стек, куча, буферы. Следите за freeHeap() в ESP.
  • Совет: Профилируйте с sizeof(), избегайте malloc — утечки убивают.

Тема памяти в embedded критична. На настольной машине вы редко думаете, сколько реально занимает буфер под строку логов. На микроконтроллере это может решить судьбу всей прошивки. Чаще всего проблемы возникают в трех местах:

  • стек — когда локальные массивы слишком большие или функции слишком глубоко вложены;
  • куча — когда есть фрагментация памяти из-за частых malloc/free;
  • глобальные буферы — когда «на всякий случай» выделяют слишком много RAM.

Поэтому совет избегать malloc в прошивке не просто консерватизм. Во многих устройствах действительно лучше заранее выделить статические буферы фиксированного размера и жить с ними. Это повышает предсказуемость. Особенно важно в long-running системах, которые должны работать неделями и месяцами без перезагрузки.

Еще один практический нюанс: смотрите не только на общий объем RAM, но и на то, как он используется конкретными библиотеками. Некоторые сетевые стеки, JSON-библиотеки или драйверы дисплеев потребляют память намного активнее, чем кажется по описанию. В проектах на ESP32 это особенно заметно, когда одновременно используются Wi-Fi, веб-сервер, JSON и буферы под данные с датчиков.

Периферия: GPIO, UART, I2C, SPI — подключаем датчики

Микроконтроллер раскрывается именно через периферию. Сам по себе CPU без интерфейсов малоинтересен: вся практическая ценность МК в том, что он умеет взаимодействовать с внешним миром. Кнопки, светодиоды, датчики температуры, инерциальные модули, дисплеи, карты памяти, драйверы моторов — всё это подключается через GPIO и стандартные шины обмена.

Для новичка здесь главное не пытаться запомнить все интерфейсы сразу, а понять их роль. GPIO нужен для простых цифровых сигналов, UART — для отладки и связи, I2C — для недорогих модулей и датчиков на общей шине, SPI — когда нужна скорость, а ADC — когда источник данных аналоговый. Дальше всё уже сводится к тому, чтобы научиться читать даташиты и аккуратно соединять аппаратную часть с кодом.

Таблица протоколов:

Протокол Описание Скорость Пример использования
GPIO Цифровой I/O Кнопки, LED
UART Последовательный 9600–115200 бод Отладка, связь с ПК
I2C Шина (2 провода) 100–400 кГц OLED-дисплей, MPU6050
SPI Шина (4 провода) До 50 МГц SD-карта, TFT-экран
ADC Аналого-цифровой 12 бит Температура, свет

Несколько практических замечаний к этой таблице:

  • GPIO — это база. С него обычно начинают, но даже тут есть нюансы: pull-up/pull-down, дребезг кнопок, допустимый ток на пин и корректные уровни логики.
  • UART — лучший друг при отладке. Если у вас нет логов, отладка встроенного устройства становится на порядок сложнее.
  • I2C удобен, когда нужно повесить несколько датчиков на одну шину, но он чувствителен к подтяжкам, длине проводов и качеству соединений.
  • SPI быстрее I2C и отлично подходит для дисплеев, Flash-памяти и SD-карт, но требует больше линий и аккуратности с chip select.
  • ADC в теории прост, а на практике быстро упирается в шумы, опорное напряжение, фильтрацию и разводку питания.

Практика: DHT22 по I2C на ESP32.
Библиотека DHT-sensor-library. Код проверяет температуру каждые 2 сек, выводит в Serial.

Здесь стоит отметить инженерный нюанс: в реальных проектах при работе с датчиками важно не только «получить значение», но и понять качество этого значения. Датчики могут шуметь, зависать, возвращать NaN, отвечать с задержкой или вообще ломать шину при плохом питании. Поэтому полезно сразу закладывать:

  • проверку валидности измерений;
  • повторные попытки чтения;
  • таймауты на операции;
  • простую фильтрацию, например скользящее среднее.

В реальных задачах комбинируйте: ADC → UART → ПК для ML-обучения.

Это очень практичный путь. Часто микроконтроллер используется не только как исполнитель, но и как устройство сбора данных. Например, вы читаете аналоговый датчик, оцифровываете сигнал, отправляете выборки по UART или USB на ПК, а дальше уже используете Python для анализа, фильтрации, разметки и подготовки датасета для ML-модели. Такой pipeline встречается чаще, чем кажется: embedded отвечает за надежный сбор и первичную обработку, а обучение и аналитика живут на более мощной машине.

Если смотреть шире, именно в этой точке и появляется мост между классическим embedded и прикладным ИИ. Хорошая модель начинается не с выбора архитектуры нейросети, а с качественно собранных данных с понятной частотой дискретизации, метками и контролем шумов.

Отладка и типичные ошибки новичков

Если говорить честно, embedded — это не только написание кода, но и постоянная отладка на стыке схемы, питания, таймингов, драйверов и логики. На практике очень часто 80% времени уходит не на разработку новой функциональности, а на выяснение, почему устройство ведет себя не так, как ожидалось. Это нормально. Более того, умение методично дебажить здесь важнее, чем умение быстро писать код.

Мои топ-ошибки:

  • Забыт pull-up на I2C: SDA/SCL висят — таймауты.
  • Неправильный clock: STM32 по умолчанию HSI 8 МГц, настройте HSE.
  • Stack overflow: Увеличьте в linker script.
  • Brown-out reset: Добавьте конденсатор 100 нФ.

Эти ошибки действительно встречаются постоянно, но за ними полезно видеть причины:

  • I2C без подтяжек почти гарантированно даст нестабильную шину. Модуль может «как будто работать» один раз из десяти, и это особенно раздражает новичков, потому что ошибка выглядит случайной.
  • Неправильное тактирование ломает всё сразу: UART выдает мусор, таймеры считают не так, задержки перестают соответствовать ожиданиям.
  • Stack overflow часто маскируется под «странные зависания». Особенно если в локальной переменной внезапно выделили большой буфер или в проект добавили библиотеку с глубокими вызовами.
  • Brown-out — типичная история при Wi-Fi, моторах, сервоприводах и любых скачках тока. На столе по USB всё вроде стабильно, а в реальном питании устройство начинает перезагружаться.

Инструменты:

  • Serial Monitor для логов.
  • Oscilloscope (DSO Nano, 2к руб.) для сигналов.
  • Logic analyzer (Saleae clone) для протоколов.

Из всего этого набора logic analyzer для новичка часто оказывается самым полезным по соотношению цены и пользы. Когда можно посмотреть, что реально происходит на I2C, SPI или UART, многие «магические» баги сразу становятся понятными. Осциллограф тоже важен, особенно если дело касается питания, PWM и аналоговых сигналов, но для цифровых протоколов логический анализатор — почти обязательный инструмент.

Еще один важный принцип: меняйте в системе только одну вещь за раз. Если одновременно перепаять провод, сменить библиотеку, переделать схему питания и обновить код, потом невозможно понять, что именно всё починило или сломало. В embedded дисциплина эксперимента очень помогает.

Проверяйте: соберите схему на breadboard, фото ниже (описание: ESP32 + DHT22 + резистор 4.7к).

Breadboard удобен для первых шагов, но у него есть ограничения. Контакты могут быть нестабильными, особенно с дешевыми проводами и после нескольких пересборок. Поэтому если проект начинает вести себя «то работает, то нет», всегда стоит проверить не только код, но и банальную механику соединений. За годы разработки я видел немало случаев, когда проблема была не в прошивке, а в плохом контакте на макетной плате или в слишком длинном проводе на шине I2C.

Переход к реальным проектам: от мигания к edge AI

После того как вы освоили базовые вещи — GPIO, UART, простые датчики и структуру прошивки, — важно не застрять на учебных примерах. Настоящее понимание приходит в проектах, где нужно собрать несколько подсистем вместе: сенсоры, обмен данными, обработку сигналов, управление состояниями, питание и, возможно, сетевое взаимодействие. Именно здесь embedded перестает быть набором отдельных приемов и становится инженерной системой.

Мой кейс: STM32 + TensorFlow Lite Micro для классификации жестов.

Такие проекты хорошо показывают границу между «теоретически можно» и «реально работает на устройстве». Когда запускаешь TinyML на микроконтроллере, быстро выясняется, что задача — не просто сконвертировать модель в C-массив. Нужно уложиться в память, подготовить входные данные, обеспечить стабильную частоту чтения сенсора, не сломать основную логику прошивки и при этом сохранить приемлемое энергопотребление. Именно по этой причине strong base в embedded оказывается не менее важной, чем знание ML-фреймворков.

Дорожная карта для новичка:

  1. Мигалка + кнопка (1 день).
  2. UART-логгер датчика (3 дня).
  3. Wi-Fi дашборд на ESP (неделя).
  4. TinyML: модель на Edge Impulse → C-код на МК.

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

  • на первом вы понимаете GPIO и базовый цикл;
  • на втором осваиваете сбор данных и отладку через логирование;
  • на третьем сталкиваетесь с сетевым стеком, асинхронностью и структурой проекта;
  • на четвертом переходите к ресурсоограниченному ML и оптимизации всего пайплайна.

Связь с ИИ: embedded — база для edge AI. Без прошивок ваши нейронки не полетят на дрон.

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

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

  • FreeRTOS для multitask.
  • lwIP для сетей.
  • Git: ветки dev/main, CI с PlatformIO.

Для продвинутых проектов это действительно полезный набор. FreeRTOS помогает, когда у вас уже несколько независимых задач: чтение сенсоров, связь, управление интерфейсом, сетевой обмен. Но вводить RTOS стоит не слишком рано. Если не понимать, как устроен простой суперцикл и работа с прерываниями, многозадачность только усложнит отладку.

lwIP полезен там, где нужен более контролируемый сетевой стек. А вот Git + CI — это то, что стоит внедрять раньше, чем кажется. Даже в маленьком embedded-проекте удобно иметь понятную историю изменений, отдельные ветки под эксперименты и автоматическую сборку. Когда прошивка начинает жить дольше недели, это уже не «лишняя бюрократия», а нормальная инженерная практика.

FAQ: частые вопросы по микроконтроллерам и embedded

Что лучше: Arduino или чистый C?
Arduino — для старта, скрывает HAL. Чистый C — контроль, скорость. Переходите через 2–3 проекта.

Если чуть расширить ответ: Arduino хорош тем, что снимает лишний порог входа. Но в какой-то момент абстракции начинают мешать понимать, что реально происходит с железом. Поэтому оптимальный путь не в том, чтобы противопоставлять одно другому, а в том, чтобы использовать Arduino как входную ступень, а затем постепенно переходить к более низкому уровню.

Сколько стоит начать?
МК + breadboard + USB = 500 руб. Multimeter — +300.

И мультиметр здесь почти обязательный. Даже самый простой сильно экономит время: проверить питание, прозвонить соединение, убедиться, что на пине вообще есть нужный уровень — это базовая диагностика, без которой embedded быстро превращается в гадание.

Как питать?
3.3V или 5V (проверьте даташит). USB или LiPo с TP4056.

Главное правило: не доверяйте предположениям, доверяйте даташиту. Ошибка по уровню питания — один из самых быстрых способов испортить модуль или получить нестабильную работу. Особенно осторожно надо смешивать 5V-датчики и 3.3V-микроконтроллеры.

МК для ИИ?
ESP32-S3 с AI-акселератором или STM32H7. Тестируйте TensorFlow Lite Micro.

Но важно заранее оценивать ожидания. На микроконтроллере реально запускать компактные модели: простую классификацию сигналов, ключевые слова, несложное CV с маленьким входом. Полноценный «большой ИИ» туда не помещается, и это нормально. Edge AI на МК — это в первую очередь про оптимизацию и четко ограниченный сценарий.

Где купить железо?
AliExpress, ChipDip, Amperka. Берите с документацией.

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

Общие проблемы с питанием?
Шумы от моторов — ferrite bead + кондеры.

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

Эта база позволит вам собрать работающее устройство за неделю. Дальше — читайте про STM32 HAL или TinyML на edge. Практикуйтесь, кодьте — embedded действительно затягивает, особенно когда устройство начинает не просто мигать светодиодом, а решать реальную инженерную задачу.