W tym artykule pokażemy jak można szybko wystartować z implementacją podstawowej komunikacji BLE, wykorzystując procesor nRF5340 firmy Nordic Semiconductor, na płytce deweloperskiej nRF5340-DK.
Przygotowanie projektu
Nasze przygodę zaczynamy od zestawienia środowiska z nRF Connect SDK i Visual Studio Code, korzystając z rozszerzenia od Nordic. Instrukcja uruchomienia dostępna jest w oficjalnym przewodniku startowym (Get Started). Projekt rozpoczniemy od klasycznego "mrugania diodą" przy użyciu przykładu Blinky. Możemy go pobrać bezpośrednio ze strony lub utworzyć klikając Create a new application w menu startowym rozszerzenia nRF Connect i wybierając Blinky Sample z listy.
Projekt Blinky idealnie nadaje się na początek naszej przygody, nie tylko dlatego, że zawiera kluczowe elementy potrzebne do startu, ale również umożliwia sprawdzenie, czy nasze środowisko programistyczne jest odpowiednio skonfigurowane i czy nasz hardware działa bez zarzutu.
Aby ruszyć z budową naszej aplikacji, musimy jeszcze ustawić konfigurację, określając, dla której płytki rozwijamy kod. Robimy to, wybierając opcję Create new build configuration z menu Applications i zaznaczając nrf5340dk_nrf5340_cpuapp na liście dostępnych płyt w sekcji Board. Resztę ustawień pozostawiamy bez zmian i finalizujemy proces, klikając Build Configuration.
Od tego momentu otwiera się przed nami droga do swobodnego edytowania kodu, kompilowania aplikacji oraz jej wgrywania bezpośrednio do mikrokontrolera. Wszystko to dzięki debuggerowi na płytce, który łączy się z naszym środowiskiem za pośrednictwem interfejsu USB.
Wybierając opcję Flash z menu Actions wgrywamy aplikację na płytkę, a następnie otwieramy terminal VCOM1, w którym wyświetlane będą wszystkie logi wysyłane funkcją printk
. Jeśli wszystko przebiegło zgodnie z naszymi oczekiwaniami, jedna z czterech dostępnych na płycie nRF5340-DK diod LED zacznie mrugać, co sekundę przełączając się między stanami.
Uruchomienie podstawowej komunikacji
Teraz wprowadzimy kilka zmian w kodzie, które pozwolą nam uruchomić rozgłaszanie domyślnych pakietów "rozgłoszeniowych" BLE. Zaczynamy od dodania poniższych linii do pliku prj.conf:
Opcje te staną się częścią konfiguracji Kconfig, na którym oparte jest budowanie systemu Zephyr.
- CONFIG_BT odblokowuje wsparcie dla komunikacji Bluetooth,
- CONFIG_BT_PERIPHERAL konfiguruje sprzęt do pracy w trybie urządzenia peryferyjnego (Peripheral Device),
- CONFIG_BT_DEVICE_NAME pozwala ustawić nazwę, która widoczna będzie podczas skanowania, wykoywanego przez urządzenia centralne (Central Device).
Przechodzimy teraz do main.c, gdzie w pierwszej kolejności dodajemy poniższe pliki nagłówkowe:
Następnie, nad funkcją int main(void)
, dodajemy dwie nowe struktury:
Pierwsza z nich, czyli tablica adv_data
, zawiera konfigurację pakietów rozgłoszeniowych (advertising). Z kolei conn_callbacks
przechowuje wskaźniki na funkcje wywoływanie w momencie nawiązania połączenia oraz tuż po jego zerwaniu.
Na koniec, wewnątrz funkcji int main(void)
, nad pętlą while
dodajemy:
Funkcja bt_enable
inicjalizuje ustawienia i uruchamia komunikację Bluetooth, a bt_le_adv_start
rozpoczyna rozsyłanie pakietów rozgłoszeniowych, zgodnie ze wskazanymi parametrami.
Test połączenia w aplikacji mobilnej
Po wgraniu aplikacji, nasz procesor powinien rozgłaszać swoją obecność dla innych urządzeń w pobliżu. Najłatwiej możemy to zweryfikować korzystając z telefonu wyposażonego w BLE i aplikacji nRF Connect.
Aplikacja dla systemów iOS wygląda zupełnie inaczej niż dla Androida, ale funkcjonalność jest dość zbliżona. W zakładce Scanner uruchamiamy skanowanie i po chwili powinniśmy na liście zobaczyć nasze urządzenie, z wcześniej zdefiniowaną nazwą. Po kliknięciu na przycisk Connect nawiązane zostanie połączenie i powinniśmy zobaczyć w aplikacji atrybuty Generic.
Dodajemy własną charakterystykę
W tej części dodamy własną charakterystykę, która pozwoli nam sterować drugą diodą dostępną na naszej płytce.
Ponownie zaczynamy od pliku prj.conf, gdzie dodajemy opcję, która umożliwia konfigurowanie urządzenia jako klienta GATT (Generic Attribute Profile):
Wracając do main.c, w pierwszej kolejności dodajemy dodatkowe pliku nagłówkowe:
Następnie duplikujemy kod odpowiedzialny za konfigurację diody LED0 i wykorzystujemy go do konfiguracji diody led1:
Sterowaine diodą będzie wymagało dwóch funkcji z charakterystycznymi nagłówkami, led_read
oraz led_write
:
W tym momencie powinniśmy zdefiniować uniwersalny niepowtarzalny numer identyfikacyjny (UUID) dla naszej charakterystyki oraz dla serwisu, do którego będzie ona przypisana. Na potrzeby testu możemy wpisać dowolny ciąg liczb, jednak na przyszłość polecamy korzystanie ze specjalnego generatora. UUID wpisujemy do naszego kodu z użyciem makr kodujących:
Pora na najważniejszą część prezentowanego kodu, czyli definicję naszej własnej charakterystyki. Tutaj również z pomocą przychodzą nam specjalne makra, dzięki którym w prosty sposób w jednym miejscu definiujemy wszystkie potrzebne parametry:
Ostatnim krokiem jest dodanie do wcześniej zdefiniowanej tablicy adv_data
dodatkowego elementu, który zagwarantuje widoczność naszego własnego serwisu (wraz z charakterystyką) dla innych urządzeń:
Test działania charakterystyki
Podobnie jak we wcześniejszym teście, łączymy się z przez aplikację na telefonie, jednak tym razem powinniśmy w widoku Client zobaczyć dodatkowy serwis i naszą charakterystykę:
Nie pozostaje nam nic innego jak sprawdzić sterowanie diodą. Klikając strzałkę w dół, znajdująca się po prawej stronie charakterystyki powinniśmy otrzymać w polu Value stan diody. Natomiast klikając na strzałkę w górę, mamy możliwość wysłania wartości unsigned int, gdzie wartość 1 powinna natychmiast załączyć diodę.
Podsumowanie
W artykule pokazaliśmy jak szybko można zacząć pracę z komunikacją BLE, jeśli zdecydujemy się skorzystać z platformy opartej na procesorze nRF5340 i narzędziach zawartych w nRF Connect SDK.
Referencje
#YourOwnCharacteristicInBLE #GoodByte