Płytka STM32 NUCLEO-WB15CC to jeden z tańszych sposobów na wejście w świat Bluetooth Low Energy z mikrokontrolerami STM32. Kupiłem ją z myślą o projekcie, który od dawna chodził mi po głowie: czujnik obecności BLE zintegrowany z Home Assistant, który nie opiera się na ruchu, ale naprawdę wie, czy ktoś jest w pomieszczeniu. Połączenie STM32WB15CC z Home Assistant okazało się zaskakująco proste — i bardzo niezawodne.
Czym jest STM32 NUCLEO-WB15CC i dlaczego wybrałem właśnie tę płytkę
NUCLEO-WB15CC to płytka Nucleo-64 oparta na mikrokontrolerze STM32WB15CC. W środku pracują dwa rdzenie: ARM Cortex-M4 taktowany do 64 MHz (rdzeń aplikacyjny) oraz ARM Cortex-M0+ (rdzeń sieciowy obsługujący stos BLE). Oba rdzenie działają niezależnie — Cortex-M0+ zarządza komunikacją Bluetooth 5.0, podczas gdy M4 wykonuje logikę aplikacji.
Z punktu widzenia projektu IoT to istotne: nie tracę cykli CPU na obsługę BLE i mam pełną kontrolę nad logiką czujnika po stronie M4.
Parametry, które miały znaczenie przy wyborze:
- Bluetooth 5.0 LE z obsługą trybu skanowania pasywnego
- 320 KB Flash + 48 KB RAM — wystarczająco na stos BLE i własny kod
- Niski pobór prądu — tryby Stop i Standby z aktywnym budzikiem RTC
- Zgodność z Arduino Uno — piny kompatybilne, łatwy montaż modułów
- Wbudowany ST-Link/V3 — programowanie i debugowanie bez dodatkowego sprzętu
- Cena — znacznie poniżej płytek z Wi-Fi + BLE
Jak działa czujnik obecności BLE
Standardowe czujniki PIR wykrywają ruch. Jeśli siedzisz nieruchomo przez kilkanaście minut — dla PIR jesteś niewidoczny. To generuje fałszywe „opuszczenia” pokoju i niepotrzebne wyłączanie świateł czy ogrzewania.
Czujnik obecności BLE oparty na NUCLEO-WB15CC działa inaczej. Smartfony i inne urządzenia BLE co kilkaset milisekund rozgłaszają pakiety advertisingu — nawet gdy ekran jest wygaszony i telefon leży w kieszeni. STM32WB15CC skanuje te pakiety pasywnie, identyfikuje znane urządzenia po adresie MAC i na tej podstawie wnioskuje, czy domownik jest w zasięgu.
Zaletą jest to, że obecność jest wykrywana stale, bez konieczności ruchu. Wadą — zasięg BLE obejmuje całe mieszkanie, więc dokładna lokalizacja (który pokój) wymaga kilku węzłów lub użycia RSSI do szacowania odległości.
Schemat projektu STM32WB15CC i Home Assistant
[Smartfon / zegarek / tag BLE]
│ BLE advertising
▼
[NUCLEO-WB15CC]
Cortex-M0+: skanowanie BLE
Cortex-M4: logika obecności + UART
│ UART/USB
▼
[Raspberry Pi / serwer lokalny]
MQTT broker (Mosquitto)
│ MQTT
▼
[Home Assistant]
binary_sensor: presence
Płytka łączy się z Raspberry Pi przez USB (UART wirtualny). Pi pełni rolę pośrednika: odbiera dane z NUCLEO, publikuje je do brokera MQTT, a Home Assistant subskrybuje i podejmuje automatyzacje.
Konfiguracja środowiska
Do pracy z STM32WB15CC potrzebujesz:
- STM32CubeMX — generowanie konfiguracji projektu i inicjalizacja stosu BLE (WPAN middleware)
- STM32CubeIDE lub VS Code + CMake + arm-none-eabi-gcc — kompilacja
- STM32CubeProgrammer — wgrywanie firmware stosu BLE (tzw. FUS + wireless stack)
Ważny krok, który często pomijają tutoriale: przed pierwszym programowaniem musisz wgrać najnowszy Firmware Upgrade Service (FUS) oraz BLE wireless stack przez STM32CubeProgrammer. Bez tego rdzeń M0+ nie uruchomi BLE. Pliki znajdziesz w pakiecie STM32CubeWB.
Implementacja skanowania BLE
Po wygenerowaniu projektu w CubeMX z włączonym middleware STM32WPAN i wybranym przykładem BLE_Scan, główna logika skanowania wygląda następująco:
Rdzeń M4 inicjalizuje stos przez SHCI_C2_BLE_Init(), następnie wywołuje aci_gap_set_scan_parameters() z trybem pasywnym (LE_SCAN_PASSIVE). Skanowanie pasywne oznacza, że płytka nasłuchuje pakietów advertisingu, ale sama nie wysyła żadnych zapytań — to ważne dla niskiego poboru prądu.
Gdy pojawi się pakiet od śledzonego urządzenia, callback hci_le_advertising_report_event() dostarcza adres MAC i poziom sygnału RSSI. Na tej podstawie M4 aktualizuje stan obecności i wysyła przez UART komunikat JSON:
{"device":"phone_rudner","rssi":-62,"present":true,"ts":1710000000}
Próg RSSI przyjąłem na poziomie -85 dBm — przy słabszym sygnale uznajemy urządzenie za poza zasięgiem (wyszło z domu lub zasięg budynku).
Filtrowanie i debouncowanie
Samo RSSI zmienia się dynamicznie. Żeby uniknąć migotania stanu „obecny/nieobecny”, implementuję prosty licznik:
- Urządzenie uznajemy za obecne, gdy przez ostatnie 30 sekund odebraliśmy co najmniej 3 pakiety z RSSI powyżej progu
- Urządzenie uznajemy za nieobecne, gdy przez 5 minut nie odebraliśmy żadnego pakietu z RSSI powyżej progu
Histereza czasowa eliminuje fałszywe alarmy, gdy ktoś wychodzi na chwilę pod drzwi.
Integracja STM32WB15CC z Home Assistant przez MQTT
Na Raspberry Pi działa Mosquitto. Integracja MQTT w Home Assistant subskrybuje temat home/presence/nucleo i mapuje dane na encję binary_sensor:
# configuration.yaml
mqtt:
binary_sensor:
- name: "Obecność w domu"
state_topic: "home/presence/nucleo"
value_template: "{{ value_json.present }}"
payload_on: "true"
payload_off: "false"
device_class: presence
off_delay: 300
off_delay: 300 to dodatkowe 5 minut opóźnienia po stronie HA — zabezpieczenie na wypadek chwilowej przerwy w BLE. Po zapisaniu konfiguracji czujnik obecności BLE pojawia się w Home Assistant natychmiast i jest gotowy do użycia w automatyzacjach.
Pobór prądu i zasilanie
W trybie ciągłego skanowania płytka pobiera około 8–12 mA (rdzeń M0+ aktywny, M4 w trybie Sleep między callbackami). To pozwala zasilać projekt z dowolnej ładowarki USB lub powerbanku.
Jeśli zależy Ci na baterii, możesz zaimplementować skanowanie z interwałem (np. 10 sekund skanowania, 50 sekund uśpienia) — pobór spada do ok. 1–2 mA średnio, ale czas reakcji na wykrycie obecności wzrasta.
Co dalej — możliwe rozszerzenia
Projekt STM32WB15CC z Home Assistant działa stabilnie od kilku tygodni. Kilka kierunków, które planuję sprawdzić:
- Triangulacja RSSI z kilku węzłów — dwa lub trzy NUCLEO rozmieszczone w mieszkaniu pozwoliłyby określić, w którym pomieszczeniu jest dana osoba
- Obsługa tagów BLE — zamiast polegać na smartfonie (który może wyłączyć BLE), można użyć małego tagu przypiętego do kluczy
- Hybrydowy czujnik obecności BLE + PIR — BLE do długoterminowej obecności, PIR do natychmiastowej reakcji na ruch
- OTA przez BLE — STM32WB15CC obsługuje aktualizacje firmware over-the-air, co przy kilku węzłach w mieszkaniu znacznie ułatwia utrzymanie
FAQ
Czy NUCLEO-WB15CC obsługuje Wi-Fi? Nie. STM32WB15CC ma tylko Bluetooth 5.0 LE. Do komunikacji z Home Assistant potrzebny jest pośrednik — Raspberry Pi, ESP32 lub inny serwer lokalny z MQTT.
Czy można wykrywać obecność bez znanych adresów MAC? Tak, ale z ograniczeniami. Można zliczać wszystkie unikalne urządzenia BLE w zasięgu, ale nowoczesne smartfony rotują adresy MAC co kilkanaście minut (MAC randomization), co utrudnia identyfikację. Najlepiej działa lista zaufanych adresów lub sparowane tagi BLE.
Jakie jest maksymalne opóźnienie wykrycia w Home Assistant? Przy interwale skanowania 100 ms pierwsze pakiety są odbierane w ciągu 1–3 sekund. Debouncowanie po stronie firmware dodaje kilka sekund, a off_delay w Home Assistant — do 5 minut przy wyjeździe.
Czy projekt działa z Apple Watch lub AirTagami? Apple Watch rozgłasza BLE — jest wykrywalny przez czujnik obecności BLE. AirTagi używają protokołu FindMy, który nie jest standardowym BLE advertisingiem i nie będzie widoczny bez reverse-engineeringu protokołu Apple.
