От команды к замыканию контакта
Что именно подтверждает релейный узел?
Проектирование выхода начинается с нагрузки, допустимых состояний и отказов. Из этих условий выводится контракт команды, включая ограничения на применение `toggle()`.
Есть три разных события: программа приняла команду, микроконтроллер изменил выход, лампа действительно засветилась. Между ними возможны обрыв провода, неисправный контакт или неправильное подключение нагрузки.
Начнём с готового низковольтного релейного модуля и отдельной кнопки. Затем рассмотрим собственный драйвер катушки и измерение результата. Это позволяет изучить ту же архитектуру управления, не начиная с открытых цепей 230 В.
Первый Actuator переключает готовую 12-вольтовую лампу. На столе используются ESP32-C6, готовый релейный модуль с документированным управляющим входом и отдельный источник нагрузки. После проверки можно заменить модуль собственной схемой драйвера или MOSFET-ключом — это разные решения с разными свойствами.
Реле или полупроводник#
| Решение | Плюсы | Ограничения | Подходящий первый опыт |
|---|---|---|---|
| Механическое реле | Сухие контакты; понятное размыкание цепи | Щелчок, ресурс контактов, дуга, ток катушки | Включение/выключение лампы |
| MOSFET | Быстрое переключение; PWM для совместимой нагрузки | Нет механического разрыва; потери и выбросы | Низковольтная лента, вентилятор |
| Готовый SSR | Удобный модуль под определённую нагрузку | Ток утечки, нагрев; AC и DC не взаимозаменяемы | Только после проверки точного типа |
| Бистабильное реле | Не требует постоянного тока удержания | Сложнее знать физическое состояние после сбоя | Поздний энергосберегающий узел |
Маркировка тока контактов для AC не переносится автоматически на DC. Светодиодный драйвер может иметь пусковой ток значительно выше установившегося. Поэтому выбранный модуль проверяется по типу нагрузки, а не по самой крупной цифре на корпусе.
Готовый релейный модуль#
STEMMA Non-Latching Mini Relay — пример документированного модуля с входом управления, питанием и контактами. Он позволяет проверить архитектуру без немедленного монтажа транзистора и защитного диода. У неизвестной платы с надписью «opto isolated» нужно изучить реальные связи земли и перемычки: наличие оптопары ещё не гарантирует гальваническую развязку всей сборки. [24][25]
COM соединяется с защищённым плюсом источника 12 В DC, NO — с плюсом лампы, минус лампы — с минусом источника. NC не используется. В E0 допускается только документированный активный HIGH-модуль, совместимый с 3,3 В. Неизвестный 5-вольтовый active-LOW-модуль запрещён до проверки схемы: его подтяжка может подать 5 В на GPIO, а уровень 3,3 В не гарантирует выключение.
Собственный драйвер катушки#
Для малой 5-вольтовой катушки можно исследовать низкобоковой N-MOSFET. Исток соединён с GND, сток — с нижним выводом катушки, верхний вывод — с +5 В. Диод параллельно катушке установлен катодом к плюсу. Резистор затвора ограничивает резкие токи переключения; pull-down удерживает выключение при неопределённом GPIO.
AO3400A интересен тем, что его паспорт нормирует сопротивление открытого канала и при VGS = 2,5 В: это существенно полезнее для 3,3-вольтового MCU, чем одно пороговое напряжение VGS(th). Порог означает начало проводимости при малом токе, а не гарантированное открывание силового ключа. [80]
При условном токе катушки 80 мА и сопротивлении канала 0,048 Ω проводниковые потери составляют около 0,00031 Вт. Этот расчёт показывает, что для такой катушки тепловая проблема ключа мала; он не разрешает применять тот же корпус к многоамперной нагрузке. Сопротивление растёт с температурой, а импульсные режимы и плата влияют на допустимый ток.
Обычный обратный диод замедляет спад тока катушки. Если требуется быстрое отпускание, исследуют ограничение выброса TVS/стабилитроном и проверяют допустимое напряжение ключа. Это изменение влияет на механику контактов и не вводится «для ускорения» без измерения.
Ток как обратная связь#
INA226 измеряет ток через шунт; диапазон его шунтового входа составляет около ±81,92 мВ. При 0,1 Ом и 0,5 А получаются 50 мВ и 25 мВт. При 2 А — уже 200 мВ: АЦП насыщен, даже если резистор выдерживает 0,4 Вт. Для учебного диапазона до 2 А шунт 0,02 Ом даёт 40 мВ и 0,08 Вт; номинальная мощность, допуск, температурный коэффициент и импульсный запас выбираются отдельно. Крупный пусковой ток может выйти за измерительный диапазон. [156]
Измерительные линии шунта прокладываются отдельно от силового падения на дорожках, когда создаётся собственная плата. Калибровка выполняется с известной нагрузкой. Нулевой ток при команде ON вызывает «действие не подтверждено», но ненулевой ток ещё не гарантирует свет на столе.
Кнопка, старт и отключение связи#
GPIO переводится в безопасное состояние до подключения к сети. Физическая кнопка обрабатывается локально с подавлением дребезга; её действие отправляется станции как событие и новая версия состояния. Сервер не имеет права незаметно отменять нажатие сразу после переподключения сохранённым ранее состоянием.
В профиле E0 при потере только Wi-Fi исправная прошивка сохраняет выход и локальное управление. При reset или потере питания обычное небистабильное реле может отпустить. После загрузки E0 начинает с OFF и BOOT_INHIBIT: автоматическое восстановление ON запрещено до явного освобождения режима. Это не обещание непрерывного света во время reset. Для такой гарантии нужен другой аппаратный профиль и отдельное испытание.
Приёмка Actuator#
Проверить включение и выключение, перезапуск MCU, потерю Wi-Fi, повтор одинакового command_id, удержание кнопки, обрыв нагрузки и восстановление питания. Осциллографом или анализатором убедиться, что на старте нет короткого нежелательного импульса управления.
Контракт выхода E0#
| Событие | Выход и кнопка | Возврат автоматики |
|---|---|---|
| Только Wi-Fi пропал | Текущий уровень сохраняется; кнопка работает локально | После snapshot и проверки ручного режима |
| Core перезапущен | MCU продолжает работать | Старый outbox не восстанавливает желание |
| Reset MCU / WDT / brownout | Допускается отпускание; после старта OFF | BOOT_INHIBIT до явного разрешения |
| Потеря питания MCU | OFF у небистабильного реле | Старые команды другой загрузки отклоняются |
| OTA: приём/запись | Только в согласованном режиме обслуживания | Кнопка доступна до reboot по проверке |
| OTA: reboot/rollback | Есть измеряемое окно недоступности кнопки | OFF + BOOT_INHIBIT, затем явное разрешение |
| Контакт сварился | GPIO и кнопка не размыкают цепь | Физическое снятие питания и ремонт |
gpio_hold_en — возможная оптимизация конкретного reset-профиля, не гарантия на все сбросы и потерю питания. Её не включаем как условие безопасности E0. Нужны осциллограмма, reset reason и проверка ранней загрузки/освобождения hold. Бистабильное реле или отдельный аппаратный latch меняют отказную модель и требуют обратной связи по контакту. [153]
Ручной режим живёт на исполнительном узле#
Короткое нажатие физической кнопки меняет выход и включает MANUAL_HOLD без автоматического истечения в E0. В приложении явное «выключить вручную» продлевает намерение даже при уже OFF. Состояние ManualOverride содержит режим, значение, источник, manual_revision и правило освобождения. Повторный автоматический план после нового snapshot также отклоняется, пока режим действует.
Освобождение выполняется отдельным действием «Вернуть автоматику» либо назначенной длинной кнопкой, отличной от provisioning/reset. Оно меняет manual_revision, но само не исполняет старый ON: Core строит новое решение на свежих данных. При перезапуске MCU E0 использует BOOT_INHIBIT; при ошибке сохранения ручного режима автоматизация остаётся запрещённой. Защитное аппаратное отключение имеет более высокий приоритет, чем любой ручной режим.
Для E1 временный ручной режим можно добавить с видимым сроком: «свет выключен до 19:00, затем автоматика вернётся». При неизвестном времени или перезапуске временный запрет не снимается молча. Истечение во время UNKNOWN не создаёт действие: сначала нужны свежие входы. Режим E0 без таймера выбран ради однозначности, не потому, что временные режимы запрещены архитектурой.