LoRa na STM32 i SX1276 – jaki jest realny zasięg transmisji?
Firma Semtech opracowała standard transmisji radiowej dalekiego zasięgu w pasmach ISM o nazwie LoRa. Wykorzystując nowy w ofercie STMicroelectronics zestaw startowy B-L072Z-LRWAN1 postanowiliśmy sprawdzić w praktyce na jakie odległości można przesłać dane w różnych warunkach terenowych. Wyniki testów udokumentowaliśmy za pomocą filmów oraz przedstawiliśmy w artykule.
Zaczniemy od krótkiego wstępu teoretycznego, który pozwoli zorientować się czytelnikom w rozwiązaniach technicznych wykorzystywanych przez standard LoRa.
LoRa jest interfejsem radiowym działającym m.in. w pasmach ISM 434 MHZ i 868 MHz (obowiązuje w UE) umożliwiającym komunikację o dużym zasięgu przy niewielkim poborze mocy. Dzięki temu świetnie nadaje się między innymi do budowy sieci zasilanych bateryjnie czujników rozproszonych na dużych obszarach. Odległości pomiędzy komunikującymi się ze sobą urządzeniami mogą być liczone w kilometrach – w zależności od ukształtowania i typu terenu. Osiągnięcie takiego zasięgu wiąże się jednak z ceną, którą jest maksymalny transfer danych, który może wahać się, w zależności od konfiguracji modemu od kilobajtów, do pojedynczych bajtów na sekundę.
Przepustowość kanału informacyjnego, pasmo oraz stosunek sygnału do szumu są ze sobą związane zależnością zwaną twierdzeniem Shannona-Hartleya:
C = B * log2(1+S/N),
gdzie
C – przepustowość kanału w bitach na sekundę,
B – pasmo sygnału w hercach,
S/N – stosunek mocy sygnału do mocy szumów.
Z twierdzenia tego można wyciągnąć następujące wnioski:
- zwiększenie pasma sygnału umożliwia zwiększenie transferu przy stałym stosunku mocy sygnału do szumu,
- spadek stosunku mocy sygnału do szumu (np. na skutek zwiększenia odległości między nadajnikiem, a odbiornikiem) wymaga zwiększenia pasma przy zachowanej przepustowości łącza.
Na powyższych założeniach oparta jest m.in. modulacja CSS (Chirp Spread Spectrum), w której strumień danych modulowany jest sygnałem o liniowo wzrastającej częstotliwości. Na tej technice bazuje modulacja LoRa.
Sposób w jaki przebiega modulacja sygnału jest zależny od trzech głównych parametrów:
- BW (modulation bandwidth) – opisuje w jakim zakresie zmienia się częstotliwość modulująca,
- SF (spread factor) – określa jak szybko zmienia się częstotliwość modulująca,
- CR (code rate) – wprowadza redundancję zapewniając jednocześnie korekcję błędów powstałych podczas transmisji.
Parametry te wpływają na maksymalny zasięg oraz przepustowość łącza która jest wyrażona zależnością:
Parametry mogą przyjmować następujące wartości:
- BW {7.8 kHz, 10.4 kHz, 15.6 kHz, 20.8kHz, 31.25 kHz, 41.7 kHz, 62.5 kHz, 125 kHz,
250 kHz, 500 kHz}
- SF {6, 7, 8, 9, 10, 11, 12}
- CR {4/5, 4/6, 4/7, 4/8}
Łatwo więc policzyć, że maksymalny transfer wynosi 37,5 kb/s, natomiast minimalny zaledwie ok. 11,5 b/s. Należy jednak pamiętać, że w pakiecie danych radiowych znajdują są także preambuła oraz opcjonalny nagłówek, które dodatkowo zmniejszają transfer danych użytecznych.
W testach przedstawionych w artykule użyto zestawu B-L072Z-LRWAN1 (fotografia 1) z modułem CMWX1ZZABZ-091 (jego schemat blokowy pokazano na rysunku 2), w którym zastosowano transceiver SX1276 oraz mikrokontroler STM32L072CZ.
Przykład programu testowego został przygotowany dla zestawu deweloperskiego B-L072Z-LRWAN1 firmy STMicroelectronics i wykorzystuje bibliotekę STM32Cube z rozszerzeniem LRWAN.
Biblioteka podstawowa STM32Cube dostarcza sterowników do peryferiów mikrokontrolera STM32L072CZ i jest używana przez wyższe warstwy oprogramowania oraz rozszerzenie I-CUBE-LRWAN, które zawiera sterownik do modemu SX1276 oraz stos LoRaWAN.
Biblioteka podstawowa jest dostępna na stronie st.com lub za pośrednictwem środowiska SW4STM32, na którym będzie uruchamiany przykład. Rozszerzenie I-CUBE-LRWAN należy pobrać ze strony http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-expansion-software/i-cube-lrwan.html.
Pracę zaczynamy od utworzenia nowego projektu dla zestawu B-L072Z-LRWAN1 – kolejne kroki z wymaganymi opcjami zostały przedstawione na rysunku 3. W ostatnim z przedstawionych okien należy pobrać bibliotekę STM32Cube i dodać ją do źródeł projektu. W projekcie potrzebne też będą elementy rozszerzenia I-CUBE-LRWAN:
- Middlewares/Third_Party/Lora/Phy
- Middlewares/Third_Party/Lora/Utilities
- Drivers/BSP/MLM32L07X01
- Drivers/BSP/B-L072Z-LRWAN1
Powyższe moduły wymagają dostarczenia funkcji obsługi takich peryferiów jak GPIO, RTC i SPI. Znajdują się one w przykładach aplikacji dołączonych do B-L072Z-LRWAN1. Do opisywanego przykładu zostały dołączone pliki z aplikacji Projects/Multi/Applications/LoRa/PingPong:
- debug.c
- debug.h
- hw.h
- hw_conf.h
- hw_msp.h
- hw_gpio.c
- hw_gpio.h
- hw_rtc.c
- hw_rtc.h
- hw_spi.c
- hw_spi.h
- mlm3210xx_hal_msp.c
- mlm3210xx_hw.c
- mlm3210xx_hw_conf.h
- mlm3210xx_it.c
- vcom.c
- vcom.h
W pliku mlm32l0xx_it.c znajdują się definicje wszystkich potrzebnych funkcji obsługi przerwań, dlatego można usunąć automatycznie utworzony plik stm32l0xx_it.c. Wszystkie używane przerwania wymagają także umieszczenia ich w tablicy znajdującej się w pliku startup_stm32.s. Można dopisać brakujące elementy wraz z deklaracjami typu .weak, lub zamienić istniejący plik na Projects/Multi/Applications/LoRa/PingPong/SW4STM32/B-L072Z-LRWAN1/startup_stm32l072xx.s.
Po dodaniu wszystkich źródeł trzeba uzupełnić ścieżki w projekcie. Można to zrobić w ustawieniach projektu: C/C++ General → Paths and Symbols. W zakładce Includes należy dodać ścieżki do nagłówków, a w zakładce Source Location ścieżki do plików źródłowych. Przy dodawaniu ścieżek warto zaznaczyć opcje dodania ich do wszystkich konfiguracji. Rozszerzenie I-CUBE-LRWAN potrzebuje do poprawnego działania także odpowiednich symboli – podobnie jak w przypadku ścieżek warto dodać je do wszystkich języków i konfiguracji. Wszystkie ustawienia zostały przedstawione na rysunku 4.
Próba kompilacji tak skonfigurowanego projektu zakończy się błędem z powodu wielokrotnej definicji funkcji HAL_MspInit. Problem ten można rozwiązać usuwając plik HAL_Driver/Src/stm32l0xx_hal_msp_template.c dostarczający pustych definicji funkcji konfiguracyjnych.
Po pomyślnym skonfigurowaniu projektu z biblioteką I-CUBE-LRWAN można przystąpić do implementacji prostej komunikacji radiowej pomiędzy dwoma węzłami, których rolę pełnią dwa zestawy B-L072Z-LRWAN1.
Na listingu 1 umieszczono funkcję main, w której znajduje się pełna konfiguracja radia.
List. 1. Funkcja main
#include <stdbool.h> #include "stm32l0xx.h" #include "hw_gpio.h" #include "hw_msp.h" #include "radio.h" #include "vcom.h" #include "timeServer.h" static TimerEvent_t ledTimer; static uint8_t* buffer = "Hello LoRa"; #define LORA_FREQUENCY 868000000 #define LORA_TX_POWER 14 #define LORA_BANDWIDTH 2//0 #define LORA_DATARATE 7//10 #define LORA_CODERATE 1 #define LORA_PREAMBLE_LEN 8 <………> int main(void) { HAL_Init(); SystemClock_Config(); HW_Init(); RadioEvents_t radioEvents; radioEvents.TxDone = txDoneEventCallback; radioEvents.RxDone = rxDoneEventCallback; Radio.Init(&radioEvents); Radio.SetChannel(LORA_FREQUENCY); Radio.SetTxConfig(MODEM_LORA, LORA_TX_POWER, 0, LORA_BANDWIDTH, LORA_DATARATE, LORA_CODERATE, LORA_PREAMBLE_LEN, false, true, false, 0, 0, 3000000); Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_DATARATE, LORA_CODERATE, 0, LORA_PREAMBLE_LEN, 1000, false, 0, true, false, 0, false, true); Radio.Rx(0); TimerInit(&ledTimer, ledTimerCallback); TimerSetValue(&ledTimer, 500); HW_GPIO_SetIrq(GPIOB, GPIO_PIN_2, 0, gpioCallback); BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI); for(;;); }
Pierwsze trzy funkcje są odpowiedzialne za inicjalizację biblioteki STM32Cube (HAL_Init), zegara systemowego (SystemClock_Config, wygenerowana przy tworzeniu projektu), sterownika radia i biblioteki I-CUBE-LRWAN (HW_Init).