Problem
Chciałem sterować istniejącym napędem ABUS FCA4100 zdalnie i w ramach automatyzacji domu, bez ingerencji w oryginalną elektronikę producenta i bez ryzyka uszkodzenia mechanizmu przy błędach sterowania.
Kontekst
Projekt prywatny (home automation). Napęd nie ma natywnej integracji z Home Assistant, a bezpośrednie sterowanie silnikiem wymaga zabezpieczeń: układ musi być odporny na zawieszenie firmware’u i na próbę jazdy poza zakres.
Wymagania
- Zdalne sterowanie z Home Assistant (przez WiFi).
- Brak blokowania pętli sterującej (responsywność, obsługa krańcówek w czasie rzeczywistym).
- Zabezpieczenia fail-safe: krańcówki i watchdog.
- Konfigurowalny czas impulsu sterującego (push-time).
- Rozdział logiki sterowania (Arduino) od łączności (ESP).
Rola
Zaprojektowałem i zbudowałem całość: elektronikę (zasilanie, level shifting, sterownik), firmware Arduino oraz mostek WiFi na ESP8266, a także integrację z Home Assistant.
Architektura
Rozdzieliłem odpowiedzialności: Arduino Uno pełni rolę deterministycznego kontrolera silnika i krańcówek, a ESP8266 zapewnia łączność WiFi i most do Home Assistant. Komunikacja między nimi po UART z dopasowaniem poziomów napięć (5V ↔ 3.3V).
Technologie
Arduino Uno (C++) — logika sterowania; ESP8266 — WiFi i most do Home Assistant; sterownik/mostek H do napędu; level shifting 5V/3.3V dla linii UART; krańcówki jako wejścia zabezpieczające.
Decyzje projektowe
- Podział Uno + ESP: deterministyka sterowania oddzielona od zmiennej w czasie łączności sieciowej.
- Nieblokująca pętla: sterowanie oparte o czas (millis), bez
delay(), aby krańcówki i komendy były obsługiwane natychmiast. - Konfigurowalny push-time: czas impulsu jako parametr, a nie „na sztywno“.
Trade-offy
- Dwa mikrokontrolery = więcej okablowania i level shifting, ale znacznie prostsza i bezpieczniejsza logika na każdym z nich.
- Sterowanie „impulsowe“ (emulacja) zamiast pełnej integracji z elektroniką producenta — mniej inwazyjne, kosztem braku pełnej telemetrii z napędu.
Problemy techniczne
- Różnica poziomów logicznych 5V (Uno) i 3.3V (ESP) groziła uszkodzeniem ESP.
delay()w pętli blokowałby obsługę krańcówek i komend.- Zawieszenie firmware’u mogło zostawić napęd w ruchu.
Rozwiązania
- Level shifting na linii UART między Uno a ESP.
- Nieblokująca maszyna stanów oparta o
millis()— krańcówki i komendy obsługiwane w każdej iteracji. - Watchdog resetujący kontroler przy zawieszeniu oraz krańcówki twardo zatrzymujące ruch (fail-safe).
Rezultat
Napęd ABUS działa jako element automatyki domowej sterowany z Home Assistant, przy zachowaniu bezpieczeństwa mechanizmu (krańcówki + watchdog) i responsywności (logika nieblokująca). Dane sieciowe (SSID, hasła, adresy) trzymane są w osobnym pliku poza repozytorium.
Lessons learned
- W embedded „nieblokująco“ to nie styl, a wymóg bezpieczeństwa —
delay()potrafi ukryć realne ryzyko. - Rozdział sterowania i łączności upraszcza debugowanie i ogranicza skutki awarii jednej warstwy.
What I’d do differently today
- Dodałbym MQTT z potwierdzeniami stanu i wykrywaniem utraty łączności.
- Rozważyłbym pomiar prądu silnika jako dodatkowe zabezpieczenie (wykrycie blokady).
Interview talking points
- Dlaczego rozdzieliłem sterowanie (Uno) od łączności (ESP).
- Jak watchdog + krańcówki tworzą warstwę fail-safe.
- Dlaczego logika nieblokująca jest krytyczna przy sterowaniu napędem.