poniedziałek, 11 czerwca 2018

SI4432 moduł RF firmy Silicon Labs - zajęcia praktyczne.


Wreszcie znalazłem chwilę czasu aby przetestować moduły radiowe RF oparte na chipsecie SI4432 firmy Silicon Labs. Pomimo , że chipset ten nie jest już rekomendowany przez producenta i zaleca się go zastąpić nowszymi wersjami takimi jak np SI446x to jest on nadal bardzo łatwo dostępny i tani. Kompletne moduły można nabyć poniżej 2 USD. Warto zauważyć , że inny popularny u nas moduł radiowy RFM22 firmy Hoperf został zbudowany na bazie  SI4432. Opinie o modułach SI4432 w necie są bardzo pozytywne, jako podstawowe zalety wymienia się niezawodność transmisji i duże zasięgi. No ale najlepszą metodą zweryfikowania opinii innych osób jest wyrobienie jej sobie samemu, najlepiej przez poznanie modułu w praktyce. Co niniejszym czynię.

Z tego co wyczytałem w necie ogólnie moduły radiowe RF sprawiają sporo różnego rodzaju kłopotów osobom , które pragną je poznać i używać. Myślę, że w 98 % problemy biorą się z błędnej lub niepełnej konfiguracji toru radiowego przez co drastycznie spada zasięg transmisji lub w ogóle jest problem aby nawiązać łączność z innym modułem RF. Dodatkowym utrudnieniem jest brak elementarnej wiedzy na temat parametrów transmisji radiowej , skoro nic na ten temat nie wiemy to jak mamy zajarzyć konfigurację toru radiowego ?? . Warto w tym kontekście zapoznać się z podstawowymi pojęciami takimi jak dewiacja, nośna, kanał radiowy, pasmo. Warto też mieć pojęcie do czego służy preambuła, whitening, kodowanie Manchester. Warto też wiedzieć jak jest modulowany sygnał, jakie zalety ma modulacja np. GFSK . Ponieważ jest to mój pierwszy moduł radiowy z jakim w  praktyce przyszło mi się zmierzyć dlatego w pierwszej kolejności szukałem dostępnych materiałów u producenta czyli firmy Silicon Labs. Materiały na których oparłem poznanie modułów są zawarte w linkach poniżej artykułu. Szczególnie wart polecenia jest dokument AN537 w którym opisano w przystępny sposób ważniejsze funkcjonalności modułu. A w dokumencie AN415 znajdziemy przykład , który można zaimplementować do pierwszej wymiany danych drogą radiową. W sumie trzeba przyznać , że Silicon Labs ma bardzo dobrą dokumentację i tyczy to praktycznie całego obszaru portfolio tej firmy w tym MCU z rdzeniem Cortex Mx

Testy przeprowadzam na moich płytkach developerskich dla MCU PIC32MM. Moduły Si4432 osadziłem na płytkach do gniazda PICbus :


Na rewersie płytki znajduje się cyfrowy czujnik temperatury MCP9808.
Połączenia jakie zastosowałem pomiędzy PIC32MM a Si4432 wyglądają następująco :

PIC32MM --> Si4432

RB3 --> SDI
RA9 --> SDO
RB8 --> SCLK
RC6 --> nSEL
RB9 --> nIRQ

A kompletny opis pinów modułu Si4432 który posiadam na obrazku poniżej :



O rozbudowanych możliwościach SI4432 niech świadczy ilość dostępnych rejestrów dokładnie 127. Ta ilość rejestrów może trochę na początku deprymować tym bardziej , że nie jest to mikrokontroler. Wszystko jest jednak kwestią obycia się z tym dobrodziejstwem i nocy nie przespanych z małżonką:). Na pewno przy takiej ilości rejestrów łatwo o błąd lub pominięcie czegoś istotnego w konfiguracji sam jestem ciekawy czy uda mi się za pierwszym podejściem uruchomić komunikację pomiędzy dwoma modułami.
Moduł generalnie mnie zafascynował swoimi możliwościami a z ciekawych opcji jakie można na szybko wymienić to m.in 255 kanałów transmisyjnych w ramach wybranego pasma,  4 bajtowy adres węzła dla którego jest przeznaczona wiadomość, oprócz nadania adresu węzła mamy dodatkowo możliwość filtrowania wiadomości wykorzystując do tego 4 bajty synchronizacyjne, CRC dla ramki. Kurcze trudno mi nawet ogarnąć jakie tu mamy olbrzymie możliwości w konfigurowaniu przepływu informacji. Aż mi dech zaparło :) Do pełni szczęścia brakuje jakiś sprzętowych potwierdzeń przesłanych informacji ale tutaj możemy sobie samemu wydumać jakiś mechanizm jeśli będzie taka potrzeba. Pierwszym skojarzeniem jakie się nasuwa na myśl jeśli chodzi o wykorzystanie modułów jest możliwość zbudowania radiowej implementacji RS485 .

Abstrahując od jakichkolwiek ustawień pierwszym kroczkiem jest zapoznanie się ze strukturą zapisu i odczytu do modułu a tu z pomocą przychodzi nam dokumentacja :






Z modułem "rozmawiamy" za pomocą SPI. Parametrem granicznym dla SCLK jest 10 MHz, warto to mieć na uwadze i nie podkręcać zbytnio zegara SPI po stronie MCU. Z powyższych timingów wynika w sumie prosta struktura ramki komunikacji z modułem, aby cokolwiek nadać lub odebrać z modułu musimy na linii nSEL ustawić stan niski potem wysyłamy pierwszy bajt , który na 7 bitach (A0..A6) zawiera adres rejestru do którego się odwołujemy a na 8-mym bicie (R/W) kodujemy informację czy chcemy odczytać dane z rejestru (R/W=0) czy zapisać dane do rejestru (R/W=1). Drugim przesyłanym bajtem jest dana, zapisywana do rejestru  lub odczytywana z niego .

Możemy w tym momencie zająć się zbudowaniem funkcji zapisującej i odczytującej do modułu. Tak abyśmy mogli zacząć jak najszybciej rozmawiać z modułem. Poniżej obraz z kodem tych funkcji.


Do obsługi SPI wykorzystałem funkcje automatycznie generowane przez MCC czyli najprościej i najszybciej jak się da. W sumie korzystam tylko z jednej funkcji SPI2_Exchange8bit, która potrafi wysłać bajt po SPI i odczytać bajt z bufora sprzętowego SPI. Uwaga !! standardowa konfiguracja SPI jaką otrzymamy dla Mastera z konfiguratora MCC ustawia w rejestrze SPIxCON bit SMP na 1. Aby poprawnie rozmawiać po SPI z modułem Si4432 ten bit musi być wyzerowany. Jeśli tego nie zrobimy otrzymamy przekłamane dane na linii SDI. Najszybszym testem czy dane są poprawnie odbierane to odczyt zawartości rejestrów 0x00 i 0x01 modułu Si4432 :

SI4432_REG_00_DEVICE_TYPE tutaj odczytamy wartość 8
SI4432_REG_01_VERSION_CODE tu odczytamy wartość 6.

Do rejestrów odwołujemy się w programie za pomocą przyjaznych nazw takich jak powyżej. Nazwy rejestrów znajdziemy w pliku si4432.h

Funkcje do rozmowy z modułem Si4432 są banalnie proste. W funkcji zapisującej do rejestru SpiWriteRegister() musimy pamiętać o ustawieniu najstarszego bitu (R/W=1) a robimy to przez dodanie do przekazanej do funkcji zmiennej reg reprezentującej adres rejestru , maski SI4432_WRITE_MASK (0x80)
W funkcji odczytującej zawartość rejestru SpiReadRegister() najpierw wysyłamy bajt reprezentujący adres rejestru z najstarszym bitem ustawionym na 0 (R/W=0), a potem wysyłamy pusty nieistotny bajt z wartością 0xFF, podczas wysyłania tego pustego bajtu pobieramy z bufora SPI daną reprezentującą zawartość odczytanego rejestru Si4432.

Mając sprawdzone funkcje zapisu i odczytu rejestru Si4432 możemy zmierzyć się z najtrudniejszym zagadnieniem w całej zabawie z modułami RF czyli z konfiguracją toru radiowego. Punktem wyjścia do wszelkich ustawień jest znajomość częstotliwości pracy modułu jaki kupiliśmy, dostępne są moduły 434 , 868, 915 MHz, warto tu jednak zauważyć, że sam chipset ma możliwość pracy w zakresie 240-930 MHz
Mój moduł pracuje na częstotliwości 433,92 MHz (tak podaje sprzedawca , więc wierzymy , że tak jest) czyli wchodzi w pulę pasma krótkofalarskiego 70 cm. Zaletą w tym przypadku jest mniejsze tłumienie sygnału przez przeszkody betonowe co skutkuje większym zasięgiem w budynku .
Znamy zatem podstawowy parametr naszego modułu i co dalej. Dalej to by była pupa blada gdyby nie  Kalkulator ustawień ,bez tego narzędzia skonfigurowanie toru radiowego a w szczególności zaawansowanych jego parametrów byłoby drogą przez mękę.

Uruchamiamy kalkulator i wpisujemy w szare pola dwa podstawowe parametry częstotliwość pracy modułu RX/TX Carrier Frequency [MHz] = 433,92 i prędkość transmisji Rb [kbps] = 20 (taką sobie wymyśliłem), maksymalna prędkość transmisji dla Si4432 bez aktywnej opcji Manchaster wynosi 256 kbps Dla ciekawości następca moduł z serii Si446x posiada aż 1 Mbps, czyli cztery razy większą prędkość maksymalną.
Moje ustawienia w sekcji górnej kalkulatora wyglądają następująco :



Następnie przepisujemy do funkcji inicjalizującej w programie wygenerowane wartości rejestrów , które znajdują się w czterech kolejnych sekcjach kalkulatora z prawej strony każdej sekcji w tabelce. Poniżej na zdjęciach cztery kolejne sekcje i ustawienia rejestrów w tabelkach :


Poniżej fragment kodu funkcji inicjalizującej , który ustawia rejestry na podstawie wartości z tabelki sekcji opisanej jako RX/TX Carrier Frequency Settings :




W tym momencie mamy optymalne ustawienia rejestrów dla toru radiowego. Wystarczy to przepisać do funkcji inicjalizującej moduł w programie i gitara gra.

Kolejnym krokiem jaki trzeba zrobić to konfiguracja funkcjonalności i opcji pracy modułu. Ale żeby to zrobić musimy mieć "wizję" tego co chcemy przesłać i co odebrać. Ja powołam się tutaj na przykład jaki został zawarty w dokumencie AN415 ,przykład nie wyczerpuje wszystkich opcji i możliwości modułu ale jest dobrym punktem zaczepienia dla pierwszych prób. Zatem powołując się na ten przykład z dokumentacji, na zdjęciu poniżej obrazek tego co chcemy z grubsza przesłać drogą radiową :



Poniżej natomiast pełny obraz funkcjonalności w ramce jaki mamy do dyspozycji ogólnie w module Si4432 :



Skupmy się jednak na przykładzie i dalszych krokach konfiguracyjnych z nim związanych.

Pierwszym elementem funkcjonalnym ramki jest Preambuła, jest to 4 bitowa sekwencja 0101 złączona do kupy w  kolejnych bajtach, w przykładzie 5 kolejnych bajtów. Preambuła ma na celu wstępną synchronizację nadajnika z odbiornikiem i razem ze słowem synchronizacyjnym Synchron Pattern stanowi konieczny element każdej ramki. Długość preambuły ustawiamy na 9 bitach w rejestrze 0x33 i 0x34 po resecie otrzymujemy wartość 0x8 czyli długość preambuły wynosi na starcie 8 x 4 bity = 32 bity i zajmuje 4 bajty. W przykładzie z dokumentacji mamy natomiast preambułę o długości 40 bitów = 5 bajtów = 10 sekwencji 4 bitowych 0101 i tu od razu widzimy błąd w dokumencie AN415 na stronie 12. Widzimy tam błędny zapis do rejestru nie zgodny z zamierzeniem
SpiWriteRegister(0x34, 0x09); //write 0x09 to the Preamble Length register
a powinno być
SpiWriteRegister(0x34, 0xA); //10 x 4 bity = 5 bajtów w preambule

Teraz pytanie skąd mamy wiedzieć jakiej długości preambułę ustawić ? wiemy tylko że na 9 bitach możemy zakodować 511 sekwencji 4 bitowych czyli 255,5 bajta. Z pomocą przychodzi nam tabelka z optymalnymi wartościami dla wybranego wariantu modulacji :


W tabelce widzimy różne tryby modulacji z opcją, tryb wybrany przeze mnie i skonfigurowany w kalkulatorze to (G)FSK AFC Disabled. Opcja Automatic Frequency Control (AFC) to taki mechanizm , który kompensuje odchyłki częstotliwości nośnej pomiędzy nadajnikiem a odbiornikiem wynikające np. z temperatury , tolerancji elementów pasywnych, odchyłki kwarca etc. Ja to wyłączam aby nie zaciemniać zbytnio i tak trochę rozbudowanej konfiguracji. Trzeba jednak pamiętać aby po opanowaniu Si4432 , ten tryb włączać do konfiguracji modułu.

W tabelce dla wybranego wiersza odczytujemy zalecaną długość preambuły ,w naszym przypadku mamy dwie możliwości 20 bitów lub 32 bity w zależności jak wybierzemy długość progu detekcji Detection Threshold. Ło matko a co to jest ten próg detekcji i gdzie się to ustawia ???? Uprzejmie informuję, że próg detekcji ustawiamy w rejestrze 0x35 na 5 bitach. Jeśli ustawimy próg detekcji np 0x5 to odbiornik uzna, że preambuła jest prawidłowo odebrana jeśli odbierze poprawnie 5 x 4 bitowe sekwencje preambuły  0101 i wtedy ustawi flagę poprawnie odebranej preambuły. Czyli próg detekcji jest minimalną ilością sekwencji 4 bitowych jakie trzeba rozpoznać na całej długości preambuły aby uznać ją za poprawny sygnał preambuły .

Z tabelki wybieram opcję długości preambuły 32 bity dla 20 bitowego progu czułości. Czyli jak 20 bitów preambuły zostanie poprawnie przez odbiornik rozpoznanych na długości 32 bitowej  to moduł ustawi nam w rejestrze statusu odpowiednią flagę, możemy z tej informacji skorzystać lub nie.
Zatem w przykładzie z dokumentacji gdzie długość preambuły ustawiono na 5 bajtów (40 bitów) zmienimy to na nasz wybór czyli 4 bajty  (32 bity), bo te ustawienie jest optymalne dla wybranej modulacji GFSK i wyłączonej opcji AFC.

Tu póki pamiętam mała dygresja, warto wiedzieć, że moduł Si4432 ma potężne narzędzia (opcje) do optymalizacji przesyłu danych tak aby transmisja była "pewna". Do takich opcji należą m.in AFC , kodowanie Manchester, Whitening.

Z powyższych dywagacji na temat preambuły do funkcji inicjalizacyjnej wrzucamy zapisy :


Kolejnym elementem wysyłanej ramki jest słowo synchronizacyjne Synchron Pattern o długości do 4 bajtów, w przykładzie z dokumentacji AN415 widzimy dwa bajty i tak też zostawiamy. Jeśli po stronie odbiornika zdefiniowana przez użytkownika wartość słowa synchronizacyjnego nie będzie zgodna z wartością w odebranej ramce to ramka będzie ignorowana i nie odczytamy jej zawartości. Tu nasuwa się od razu myśl na wykorzystanie tej funkcjonalności, mianowicie możemy za pomocą słowa synchro adresować wiadomość i odbiera ją tylko konkretny węzeł lub grupa węzłów reszta ignoruje i nie odbiera tej wiadomości.
Tu wspomnę , że mamy jeszcze do dyspozycji 4 bajtowy nagłówek , który stricte służy wyłącznie do adresowania, w przykładzie nagłówek jest wyłączony dla uproszczenia i tak też zostawiamy i my.
Słowo synchro w przykładzie ma dwa bajty długości i są to konkretne wartości 0x2D i 0xD4 .
Zapis do rejestru długości słowa synchro :

Wpisanie konkretnych wartości słów synchro :

Przed analizą kolejnego fragmentu ramki do wysłania, bazującej na przykładzie z dokumentu AN415, mała dygresja. Ogarnięcie dostępnych opcji  modułu Si4432 i ich skonfigurowanie nie jest trywialnym zadaniem i przyznaję jest czasochłonne, nie mniej mam nadzieję, że moduł odwdzięczy mi się poprawną i bezproblemową pracą. W dalszych planach apetyt mi rośnie na poznanie kolejnych nowocześniejszych modułów Si446x.

Kolejnym elementem ramki jest Payload length, tu podajemy długość elementów z pola DATA (Payload) do dyspozycji mamy jeden bajt czyli w jednej ramce możemy przesłać maksymalnie 255 bajtów danych. Ale bufor FIFO odbiorczy i nadawczy ma rozmiar 64 bajty, są mechanizmy w module , które umożliwiają wysyłanie poprzez bufor FIFO większej ilości danych niż 64 bajty. a nawet strumieniowanie danych ale nie będę tego wątku analizował bo by z tego artykułu wyszła zbyt obszerna powieść .
Ponieważ w przykładzie wysyłanych jest 8 bajtów danych do rejestru 0x3E wpisujemy taką właśnie cyfrę.

Po stronie odbiornika długość odebranej ostatnio ramki odczytamy w rejestrze 0x4B.
Przedostatnim elementem przykładowej ramki , którą spróbujemy wysłać jest pole DATA (Payload). W tym polu przesyłamy zakodowane w ASCII słowo BUTTON1 (42,75,74,74,6F,6E,31) i na końcu znak specjalny CR (0D). Generalnie wysyłanie za pomocą modułów RF danych w formacie ASCII a nie binarnych wydaje się być optymalnym podejściem. Dane ładujemy do bufora FIFO, którego adres w module to 0x7F. Bufor jest automatycznie inkrementowany za każdym nowym zapisem do rejestru. Zatem zapis naszych danych do przesłania w buforze FIFO będzie wyglądał  tak :

Aby szybko wyczyścić bufor FIFO TX lub RX zastosujemy poniższe funkcje :
 
Aby wysłać dane z bufora mamy do dyspozycji dwie opcje , manualna i automatyczna. Ja wybieram opcję manual i robimy to poniższym zapisem :


Opcja automatyczna polega na tym ,  że w chwili zapełnienia bufora FIFO, czyli zapisania do niego 64 bajtów danych, nastąpi automatyczna wysyłka tych danych. Tę opcję ustawimy w rejestrze 0x08 bit autotx.

Ostatnim elementem ramki jest suma kontrolna CRC, możemy ustawić tutaj tak aby dotyczyła ona tylko danych lub danych plus nagłówek Header/Adress i bajt Payload length. Ja wybieram opcję minimalistyczną czyli CRC niech moduł liczy tylko dla danych. Mamy różne metody wyliczania CRC, ja wybrałem CRC16-IBM. Ustawienia dotyczące obsługi CRC znajdziemy w rejestrze 0x30 a status tj. CRC Error w rejestrze 0x03


Słów kilka na temat przerwań. Moduł ma jedno wyjście nIRQ , które służy do generowania przerwań jak sama nazwa wskazuje. Ogólnie korzystamy z tego z grubsza tak , że po wystąpieniu przerwania sprawdzamy statusy w rejestrach 0x03 i 0x04 i stąd wiemy co odpaliło przerwanie. W rejestrach 0x05 i 0x06 
możemy dokładnie ustalić na co ma przerwanie reagować. Jeśli chcemy np. aby przerwanie było generowane tylko jeśli przyjdzie prawidłowa ramka danych to ustawimy to bitem enpkvalid w rejestrze 0x05

Po odczytaniu statusu w obsłudze przerwania , możemy odczytać bufor FIFO modułu lub przepisać go do bufora pomocniczego w programie i tam poddać dalszej analizie. Pin nIRQ modułu mamy podpięty do nóżki RB9 po stronie PIC32MM a tu mamy z koleji przerwanie INT2, które musimy skonfigurować w programie aby reagowało na zbocze opadające. W obsłudze tego przerwania będziemy odczytywać statusy modułu Si4432 i odpowiednio na nie reagować, ja docelowo będę reagował na status odebranej poprawnie ramki i status błędnego CRC. Uwaga flagi statusów kasują się dopiero po ich odczytaniu przez MCU.

Ta podróż przez rejestry modułu Si4432 przyznaję , że jest ekscytująca a odkrywanie  coraz to nowych i zaskakujących opcji fascynujące. Jeśli uda mi się poprawnie skomunikować te moduły to je normalnie polubię na maksa.

Jeszcze póki pamiętam to ustawienie mocy nadajnika czyli to co tygrysy lubią najbardziej, maksymalna moc +20dBm i jest to naprawdę jak na taki mały modulik bardzo dużo. Ja do pierwszych prób ustawię malutką moc a robię to tak :


Warto jeszcze cokolwiek mieć pojęcie o trybach pracy modułu. Informację na ten temat znajdziemy ładnie opisane w datasheet a wszystkie zebrane tryby znajdziemy w poniższej tabelce :

Po resecie modułu trybem domyślnym jest tryb Ready. Tryby aktywujemy w rejestrze 0x07. Po stronie modułu nadającego ramkę posłużymy się trybem TX a po stronie modułu odbierającego ustawimy tryb RX. Jeśli ramka zostanie nadana lub odebrana moduł wychodzi automatycznie z trybu TX lub RX i wraca do trybu domyślnego.

Pierwsze koty za płoty udało się wysłać ramkę z danymi w eter i potwierdzić to ustawioną flagą przez moduł. Czyli 50 % roboty za mną. Wydaje się , że wszystkie ustawienia zatrybiły prawidłowo co mnie cieszy.  W sumie jak na tak dużą ilość ustawień , przez które trzeba było się przegryźć ,bezproblemowe zadziałanie modułu można uznać za sukces .Teraz zabiorę się za przygotowanie kodu  dla części odbiorczej aby odebrać ramkę i się z tego faktu ucieszyć ogromnie :) . Im dłużej obcuje z modułem Si4432 i jego dokumentacją tym bardziej go lubię.

Poniżej główny motyw kodu testującego wysłanie ramki  :


Wysyłamy jedną ramkę za pomocą wpisu w rejestr 0x07. W pętli głównej czekamy, aż moduł po wysłaniu prawidłowym ramki ustawi flagę sprzętową i wygeneruje opadającym zboczem przerwanie na pinie nIRQ. Przerwanie to przyjmuje na klatę pin RB9 w PIC32MM, z pinem tym jest skorelowane przerwanie INT2.  Aby zminimalizować kod w przerwaniu INT2 ustawiam tam tylko flagę programową nIRQ_flag i w pętli głównej programu czekam aż się ona pojawi. Jeśli flaga programowa zostanie w przerwaniu INT2 ustawiona, wchodzimy do warunku w którym odczytujemy wszystkie statusy modułu a w następnym kroku sprawdzam selektywnie czy flaga modułu dotycząca prawidłowo wysłanej ramki została ustawiona, jeśli tak to wyświetlam napis "Send Packet". Ten prosty programik umożliwił mi uzyskanie informacji o tym , że ramka poszła w eter, nie mam analizatorów widma etc aby w inny sposób to stwierdzić. Takie sprzętowe oflagowanie modułu przez producenta kapitalnie ułatwia jego uruchomienie.
Kod przerwania INT2 :


Kurcze udało się odebrać pakiet na razie nie wiem jaki ale wiem że na 100 % pochodzi z mojego modułu nadającego :) testowałem tylko czy do odbiornika trafia poprawnie odebrany pakiet . Poniżej fragment testowego kodu po stronie modułu , który odbiera dane :



Moduł ustawiamy w tryb odbiornika RX odpowiednim zapisem do rejestru 0x07, po odebraniu ramki moduł przełącza się automatycznie w tryb READY celem ochrony prądu w baterii :). W pętli głównej czekamy na ustawienie w przerwaniu INT2 flagi programowej. Jeśli przerwanie odpali to znaczy , że jakies ważne wydarzenie w życiu modułu nastąpiło, my tylko sprawdzamy jakie i odpowiednio na nie reagujemy. W kodzie testowym sprawdzamy tylko czy nastąpiło wydarzenie odebrania poprawnej i kompletnej ramki. Jeśli tak to wyświetlamy komunikat "Receive OK" i obok wyświetlamy poziom sygnału w momencie odbioru RSSI.



W sumie jestem w szoku , że tak łatwo poszło i komunikacja zatrybiła od pierwszego kopa. A jedynym problemem  jaki miałem po drodze to gapcia ze mnie nie zainicjalizowałem w PIC32MM przerwania INT2 i się dziwiłem dlaczego nie widzę jego działania.

Anteny w modułach postawię w pozycji pionowej bo to nie jest transmisja kierunkowa lecz rozproszona :) to tak na marginesie.
No i masz babo placek tak ustawiałem anteny , że jedną urwałem :)
Pierwsze szybkie testy z ułomną anteną po jednej stronie, wykonałem przy mocy 11dBm (czyli grubo poniżej pełnej mocy), jedna kondygnacja nie robi wielkiego wrażania na sygnale, RSSI  jest na poziomie 70 ale mimo wszystko wydaje mi się , że jest to za mało. Muszę na spokojnie podumać nad zagadnieniem ,przyjrzeć się możliwością podrasowania (bez zwiększania mocy) , może na początek odblokuję AFC i zobaczę co to da lub coś ruszę w częstotliwości nośnej bo ciort wie czy chińczyk nie ściemnił z tym parametrem. Program testowy obecnie zmieniłem tak , że nadajnik cyklicznie co 1 sekundę nadaje to samo czyli tekst "BUTTON1"+CR, po odebraniu ramki zawartość bufora FIFO modułu przepisuję do bufora pomocniczego i zawartość bufora pomocniczego wyrzucam na ekran. W sumie wszystko ładnie śmiga i działa.

Znalazłem nazwijmy to anomalię w kalkulatorze do ustawień toru radiowego. I być może te moje odczucia co do niskiego RSSI mają tu swoją przyczynę. Wymyśliłem sobie prędkość transmisji 20kbps i tak wpisałem w ustawienia kalkulatora. I masz ci babo placek dla tej wartości kalkulator podaje w dwóch istotnych komórkach  #Value! czyli głupotę. Wystarczy wpisać np 30kbps aby wyliczenia w tych dwóch komórkach się pojawiły. Nie mam pojęcia  z czego wynika taki babol , być może arkusz kalkulatora musi być otwarty w Excelu a nie np . Libre Office etc.



Zmieniam zatem prędkość na 30kbps i przepisuję zmiany do funkcji inicjującej moduł.
Po zmianie wpisów w rejestry dla 30kbps RSSI podskoczyło z 70 do 85  czyli ok 20 % poprawy ale nadal to mnie nie satysfakcjonuje. W necie udało mi się wygrzebać wykres z analizatora widma dla modułu RFM22 915MHz i wygląda on tak :



Z wykresu powyższego możemy wysnuć spostrzeżenie , że optymalne parametry nadawania uzyskano dla częstotliwości 910 MHz czyli przesunięcie o 5MHz w stosunku do parametru podawanego przez sprzedawcę. RSSI w optymalnym punkcie przeliczając na nasze jednostki to ok. 150, czyli połowa więcej niż ja uzyskałem. Oczywiście brak danych jaka antena , jakie odległości , jakie otoczenie , jaka moc nadawania etc. Ale nie chodzi mi w tym przypadku o szczegóły. Uważam , że powinienem uzyskać RSSI powyżej 100. Na pewno warto przebadać poziom sygnału dla różnych odchyłek od deklarowanej nośnej. Moduł umożliwia nam taki manewr.

W międzyczasie odwiedziłem forum Silicon Labs i tam natknąłem się na wątek :
wątek na forum Silicon Labs z którego wynika, że odczyt poziomu RSSI powinien nastąpić po słowie synchronizującym a ja odczytuję ten poziom po przesłaniu całej ramki, trzeba ten wątek sprawdzić.

Wrzucam proste wzorki do wyliczenia jakości sygnału i to już jest coś na czym można oprzeć dywagacje czy RSSI jakie otrzymujemy jest dobre czy takie sobie czy gówniane :




Odczyt RSSI po wykryciu słowa synchro zgodnie z tym wątkiem na forum jest jak najbardziej trafiony. RSSI odczytane po słowie synchro  po przejściu przez jedną kondygnację wynosi 105. Jest zatem coraz lepiej jednak idąc tropem wątku z forum, gość oczekuje RSSI powyżej 200 jeśli moduły oddali o 30 cm i walnie pełną mocą. Ja przy takim teście otrzymuję RSSI = 170. Czyli jeszcze jest jakiś delikatny ból , który powstrzymuje moduły przed rozwinięciem pełnym skrzydeł. Cieszę się jednak, że małymi kroczkami udaje się coraz bardziej zbliżyć do ideału :). Poniżej fragment kodu testowego po stronie modułu odbierającego :


Na chwilę obecną przesunąłem nośną na 434 MHz , prędkość 30kbps, włączone AFC i z tego względu preambuła zwiększona do poziomu 40 bitów.
Osiągi w zakresie RSSI przy pełnej mocy modułu :

1 kondygnacja w budynku  / 113
30 cm / 173
6 cm / 201
1 cm / 230

Cały czas wzoruję się w moich rozważaniach na temat poziomu sygnału poniższym rysunkiem :



Zgodnie z rysunkiem kres możliwości  RSSI dla SI4432 to dokładnie 230
Niby taki poziom udało się uzyskać na odległości 1 cm. Czyżby jednak udało mi się na obecnych poziomach uzyskać granice możliwości RSSI dla modułu i 3 cm antenki spiralnej, nie wykluczone , że tak, nie mam jednak całkowitej pewności :).
Myślę, że te moje dociekania nie pójdą na marne i wykorzystam je przy okazji testowania innych tego typu modułów włącznie z modułami LORA.
Poniżej jeszcze znaleziony w necie wykres z analizatora widma tym razem dla modułu 434 MHz  czyli niby takiego jak mój, brak jednak danych jaka odległość, widziałem tylko obrazek anteny zrobionej z kabla w kształcie literki T ok 0,5 m długości.


Tutaj natomiast wydaje się wiarygodny post na temat zasięgów w terenie otwartym, wiemy jaka antena , jaka prędkość i moc post o zasięgu RFM22=SI4432

Ja na chwilę obecną uzyskuje pewną transmisję w budynku przez dwa stropy w pionie na 3 cm wypierdku antenie drucianej , wydaje się zatem , że jeśli dać lepszą antenę typu np : RF-ANT01R-433 to uda się przebić 4 stropy.
Nie udaje mi się natomiast przebić z sygnałem przez dwa skrajne miejsca w dużym budynku jednorodzinnym oddzielone jednym stropem z kilkoma ścianami po drodze. Na wyżej wymienionej antenie podejrzewam , że nie byłoby z tym problemu ale jeśli zależy nam na miniaturyzacji to nie tędy droga.

Jeszcze pokombinuję z długością preambuły , dam więcej czasu na synchronizację zobaczymy jak to pomoże. W sumie gdyby udało się pokryć te dwa skrajne punkty w budynku to byłbym całkowicie zadowolony  a na razie jestem zadowolony w 80 % :). Rozciągnąłem troszkę anteny wypierdki 3 cm, zyskałem kilka metrów poprawy . Zależy mi jednak na miniaturyzacji a nie stojące pały przy modułach. Coś mi się widzi, że bicie rekordów w zasięgach i przebijalności ścian modułami RF nie jest zbyt uniwersalnym rozwiązaniem jeśli chodzi o  budynek, tu się bardziej sprawdzą moduły o małych relatywnie mocach pracujące w sieciach typu Mesh . Zigbee to jest to co byłoby optymalne no ale cena takich modułów nie zachęca. Gdyby w modułach RF zaimplementować sieć Mesh lub coś podobnego to byłby strzał w 10-tkę.

Poniżej podaję optymalne długości dla anteny w postaci zwykłego drutu lub kabla dla 433 MHz :

1/4 ćwierć falowy - 16,63 cm
1/2 pół falowy - 33,26 cm
pełnofalowy - 66,51 cm.

Długości anteny wyliczone w/g wzoru : 300/f/(n*k) gdzie :

f - częstotliwość w MHz
n - n-ty podział fali
k - współczynnik skrócenia = 0,96

tylko uwaga na kolejność działań !!

Spróbuję zrobić test na zwykłym kabelku, w/g powyższych wyliczeń , dla ciekawości . Bo może ten wypierdek 3 cm , który dostałem z modułem jest jako antena do kitu i to co osiągam na nim to i tak jest giga super a ja  tylko marudzę i szukam dziury w całym :)

Łoł no teraz dopiero moduł pokazał pazur. Wywaliłem antenki zakupione z modułem do kosza a w ich miejsce dałem wyliczony w/g wzoru powyżej kawałek zwykłego kabelka z instalacji alarmowej. Kawałek o długości ok 33 cm czyli długość skojarzona z połową fali . No panie golonka teraz mam pokrycie piękne całego dużego domu (+20dBm) wszerz, wzdłuż i w poprzek. Nieuszkodzone ramki docierają mi do skrajnych miejsc w najbardziej odległych zakamarkach domu.
Sygnał musiał się przebić przez jeden strop i ok 5 ścian.
Teraz już jestem prawie zadowolony. 33 cm druciku cienkiego da się zminiaturyzować.
No ale apetyt rośnie w miarę jedzenia , spróbuję ramki wyemitować i odebrać na druciku ok 66 cm (pełna fala) przy czym zmniejszę moc do 14 dBm

Kluczem do sukcesu w modułach RF jest jak widać nie tylko dobra/poprawna konfiguracja toru radiowego ale i odpowiedni dobór anteny. Antena nie tylko musi spełniać dokładnie co do milimetra warunki długości ale ważne jest dopasowanie impedancyjne anteny do wejścia antenowego modułu. Z punktu widzenia impedancji byle drucik nie będzie do końca optymalnym wyborem ale akceptowalnym.

Na pełnofalowym druciku tj długości ok 66 cm i zmniejszeniu mocy z 20dBm do 14dBm nie uzyskałem pełnego pokrycia budynku, szkoda bo miałem na to nadzieję.

W sieci znalazłem bardzo ciekawą i kompletną bibliotekę , która ma zaimplementowaną sieć Mesh (rewelacja !!!) dla różnych modułów RF w tym dla RFM22 = SI4432. Biblioteka napisana w C++ i tu by trzeba by było zaprzyjaźnić się z tym językiem i kompilatorem XC32++ lub przeportować ją do C. Radio Head

Mając sieć Mesh dla SI4432 byłoby to genialne , małymi mocami moglibyśmy pokryć dowolny obszar i nie trzeba byłoby martwić się, że za mało pary mamy aby przebić n-tą ścianę czy strop. Wtedy byłaby to doskonała i tania alternatywa dla np. Zigbee.

W dokumentacji modułu natrafiłem na taką tabelkę :


w której pokazane jest dla jakich parametrów prędkości i dewiacji uzyskamy optymalną czułość odbiornika. Ustawiłem zatem zgodnie z danymi z tabelki  prędkość 2 kbps i dewiację 5 kHz i się zdziwiłem. Przy mocy 14dBm i druciku pół falowym ok.33 cm. sygnał pokrył mi cały budynek wszerz, wzdłuż i w poprzek no i zaczynam być bardziej zadowolony :)

Za bardzo ten artykuł zaczyna mi się rozwlekać dlatego czas na stop klatkę i jakieś delikatne podsumowanie :) No i oczywiście program.
Generalnie moduł SI4432 sprawił mi dużą radość w fazie poznawania i testów.
Dokumentacja jest przyjazna i nawet z przyjemnością ją czytałem. Początkowy stres związany z ilością rejestrów jakie mamy na pokładzie stosunkowo szybko minął wraz z przyswajaniem kolejnych działów dokumentacji. Ogromną pomocą w ujeżdżeniu modułu był dostarczany przez producenta firmę Silicon Labs , kalkulator. Bez niego byśmy byli trochę bez szans. Nie odkryłem wszystkich opcji transmisji takich jak np. strumieniowanie danych czy wogóle opcji modułu np. wewnętrzny czujnik temperatury, przetwornik ADC.

Jak na pierwsze moje starcie z modułami RF, uważam ,że poszło mi stosunkowo łatwo. Trochę podświadomie mam niedosyt w zakresie zasięgów szczególnie po tym co się czyta w necie, ale już wiem , że to co ludzie piszą o modułach RF trzeba dzielić minimum przez dwa. Na początku wyobrażałem sobie , że na antence , którą kupiłem w zestawie z modułami czyli 3 cm wypierdek w kształcie sprężynki  nawiąże łączność z inną galaktyką :)
Rzeczywistość okazała się trochę brutalniejsza.Nie robiłem testów na przestrzeni otwartej bo nie jest mi potrzebna obecnie taka wiedza. Bardziej mnie interesują właściwości modułu w budynku. A tutaj można powiedzieć , że moduł SI4432 spełnił ostatecznie moje oczekiwania i pokrył mi zasiegiem cały duży budynek jednorodzinny mocą +14dBm i antenką drucikiem 33 cm. Aby uzyskać pełne pokrycie budynku trzeba było zejść z prędkością transmisji do 2kbps. Jeśli   nie mamy potrzeby robić transmisji głosowej lub video a przesyłać jedynie dane z czujników etc to i tak świat i ludzie taka prędkość. Dodatkowo mając w perspektywie możliwość implementacji sieci Mesh bo taki soft znalazłem w necie , moduł SI4432 z mocą +20dBm może nam pokryć naprawdę spory kawałek przestrzeni zabudowanej np kilka domków jednorodzinnych etc. I to wszystko za niewielkie pieniądze. Dodatkowo ciekawą możliwością jest sterowanie modułem bezpośrednio z RasberyPI co umożliwia nam zbudowanie np. Gatewaya z dostępem do internetu etc. I nie wiem przypadkiem czy się nie szarpnę na taki projekt. Znając moduł SI4432 możemy płynnie przejść do jego następcy SI446x.

Na koniec w linkach pojawią się dwa projekty tworzące całość, dedykowane dla PIC32MM i środowiska MPLABX IDE . Projekty sciągamy z GitHuba do MPLAB X IDE za pomocą opcji Clone. Projekt testowy dla modułu nadającego konfiguruje moduł SI4432 i wysyła co 1 s, ramkę testową z napisem BUTTON1 + znak specjalny . Jeśli pakiet zostanie prawidłowo wysłany otrzymamy potwierdzenie na wyświetlaczu w postaci napisu "Send Packet" .
Projekt dla modułu odbierającego ma za zadanie utrzymać moduł w trybie odbioru RX i przyjąć nadesłane dane do bufora pomocniczego. Na wyświetlaczu odbiornika zobaczymy treść nadesłanej ramki czyli tekst BUTTON1 + znak specjalny (na wyświetlaczu to będzie kropka) obok poziom RSSI dla odebranej ramki. W pliku nagłówkowym  si4432.h w obu projektach znajdziemy przyjazne nazwy dla wszystkich rejestrów modułu RF.

Życzę powodzenia w przygodzie z modułami RF.

Pozdrawiam
picmajster.blog@gmail.com



Linki :

SI4432 - Datasheet
SI4432 - Register Descriptions
SI4432 - AN537
SI4432 - AN415 
SI4432 - Kalkulator do ustawień toru radiowego etc
Projekt GitHub - dla modułu nadającego
Projekt GiHub - dla modułu odbierającego 
Artykuł uzupełniający RFM22=SI4432 

12 komentarzy:

  1. Dla PIC32mm0256GPM pin RB3 jest też podłączony do TDI/JTAG w pliku MCC.c
    zmieniłem JTAG=ON na JTAG =OFF i zaczął pin działać normalnie

    // FICD
    #pragma config JTAGEN = OFF // JTAG Enable bit->JTAG is enabled
    #pragma config ICS = PGx1 // ICE/ICD Communication Channel Selection bits->Communicate on PGEC1/PGED1

    OdpowiedzUsuń
  2. W załączonych plikach na GitHub dla Si4432 , JTAG jest wyłączony. Warto sobie taki odruch nabyć jak korzystamy z MCC i nawet jak nie wykorzystujemy pinu RB3.
    Pozdrawiam
    PICmajster

    OdpowiedzUsuń
    Odpowiedzi
    1. robiłem od początku , dzięki temu teraz zdałem sobie sprawę jakie pułapki czekają ;-) . W PIC32mm064gpl28 nie było problemów z JTAG

      Usuń
  3. W MPLABX-IDE 4.15 i wtyczce MCC 3.45.1 w zwyż masz JTAG wyłączony standardowo więc jedna "pułapka" mniej :)

    Pozdrawiam
    PICmajster

    OdpowiedzUsuń
  4. Organoleptyka stosowana :)

    Pozdrawiam
    PICmajster

    OdpowiedzUsuń
  5. Bardzo fajny poradnik!
    Znalazłem jednak mały błąd:
    "11dBm (czyli połowa dostępnej mocy)". Połowa dostępnej mocy to 17dBm, 11dBm to raptem troszkę ponad 12mW. Skala decybelowa nie jest liniowa!

    OdpowiedzUsuń
  6. Dziękuję za słuszną uwagę już poprawiłem. Zapraszam również do przeczytania artykułu o SI4463, to ulepszona wersja m.in w torze radiowym.

    OdpowiedzUsuń
    Odpowiedzi
    1. :) Si4463 jest niedostępny w detalicznej sprzedaży, poza tym ogarnąłem 4432 w maksymalnej formie - z filtrowaniem nagłówka, tworzeniem podsieci - i przeportowałem na Cortexa stm32. Dodatkowo na plus jest fakt, że jest wersja 500mW - RFM23BP :)
      Gratuluję wiedzy i chęcią dzielenia się nią! Zajefajny blog!

      Usuń
  7. ooo ! to fajowo jak tak daleko zaszłeś w komitywie z modułem. Jest biblioteka sieciowa do tego modułu łącznie chyba z Mesh-em. Więc można tutaj robić nawet zaawansowane konfiguracje sieciowe pomimo, że moduł jest relatywnie prosty. Ja mam zamiar swoją dziergać pod Cortex M23 i PIC32MM ale dla SI4463, też mi się marzy sieć na modułach RF.

    OdpowiedzUsuń
  8. Wszystkie informacje bardzo pomocne

    OdpowiedzUsuń