Modulacja FSK
z angielskiego FSK - frequency shift keying - czyli kluczowanie poprzez przesunięcie częstotliwości. I od razu wrzucę kilka podstawowych pojęć jakimi będę się posługiwać.
częstotliwość dewiacji
maksymalna odchyłka częstotliwości od fali nośnej / częstotliwości referencyjnej.
bitrate
prędkość przesyłu danych wyrażana w bitach na jednostkę czasu.
symbol
najmniejsza jednostka sygnału modulowanego, która niesie określoną liczbę bitów informacji
baudrate
prędkość transmisji wyrażana w symbolach na jednostkę czasu
uproszczony schemat nadajnika FSK
I tu od razu uwaga. Implementacje modulatora mogą być różne, liczy się efekt końcowy, czyli fala o konkretnej częstotliwości bądz konkretnym przesunięciu częstotliwości na wyjsciu reprezentująca dany symbol. Może być implementacja sprzętowa, gdzie modulatorem będzie VCO a sygnał modulującym będzie napięcie sterujące - wyższe napięcie - większa częstotliwość na wyjsciu VCO. Może też to być implementacja softowa, gdzie generujemy sygnał z użyciem funkcji sinus (i cosinus jesli działamy na próbkach I i Q).
Fala nośna - żeby też się nie pomieszało - ona nie występuje w sygnale wyjsciowym, modulator fsk ingeruje w falę nośna, zmieniając jej częstotliwość. W ten sposób uzyskujemy zmodulowaną falę nośną (o przesuniętej częstotliwości).
W przypadku implementacji softowej - może być ciężko sobie wyobrazić fale nośną. Myślę, że można ją smiało porównać do częstotliwości referencyjnej (f0) względem której będziemy wyznaczać względne przesunięcia częstotliwości. Tak więc na wyjsciu takiego modulatora w rzeczywistości nie będzie ona występować, natomiast będzie zmienną w sofcie definiującą częstotliwość referencyjną, używaną jako część argumentu funkcji sinus / cosinus podczas generowania sygnału. taki pseudokod:
for (unsigned int i = 0; i < sampleBuffSize; ++i)
{
symbol = // pobrany z danych w zaleznosci od kodowania.
// wybor czestotliwosci reprezentujacej konkretny symbol, względem f0
freq = f0 - fDeviation + 2 * fDeviation * symbol / (symbolSize - 1);
phase += (2 * PI / sampleRate) * freq;
I[i] = cos(phase);
Q[i] = sin(phase);
}
Dlatego myślę, że powyższy schemat najlogiczniej opisuje działanie modulatora fsk niezależnie od implementacji.
Sygnał modulujący
Jest to sygnał, który chcemy zmodulować, nadać, a następnie odtworzyć w odbiorniku. W przypadku standardowej modulacji FM sygnałem modulującym będzie dźwięk zebrany przez mikrofon, a następnie w postaci sygnału elektrycznego przekazany do modulatora bądź konwertera ADC, celem przekształcenia go na sygnał cyfrowy. Oczywiście między mikrofonem a samym modulatorem mogą znajdować się jeszcze inne elementy, np. wzmacniacz.
Tak więc sygnałem modulującym w przypadku przesyłu dźwięku będzie sygnał analogowy bądź dyskretny (próbkowany), gdzie jeden symbol - wartość sygnału w danym momencie - może przyjąć dużą liczbę stanów.
W przypadku przesyłu danych wartość sygnału modulującego może przyjąć 2 stany - w przypadku modulacji 2FSK. W takiej sytuacji dane są modulowane bit po bicie.
Przykład dwu stanowego symbolu (2FSK)
chcemy przesłać tekst:
“test” -> binarnie -> 0’1’1’1’0’1’0’0’0’1’1’0’0’1’0’1’0’1’1’1’0’0’1’1’0’1’1’1’0’1’0’0

a po zmodulowaniu sygnału nośnego

Przykład cztero stanowego symbolu (4FSK)
Natomiast nic nie stoi na przeszkodzie żeby jeden symbol przyjmował więcej niż 2 stany. Przykładowo możemy przesyłać dane po dwa bity:
“test” -> binarnie -> 01110100011001010111001101110100 -> po dwa bity -> 01’11’01’00’01’10’01’01’01’11’00’11’01’11’01’00 -> finalna wartość sygnału modulującego -> 1’3’1’0’1’2’1’1’1’3’0’3’1’3’1’0

zmodulowana fala nośna:

Kodowanie sygnału modulującego
W poprzednich przykładach i wykresach zostało to trochę uproszczone - bezpośrednio zamienialiśmy dane binarne na wartości sygnału modulującego. Natomiast takie kodowanie, a w zasadzie jego brak, ma sporo wad - po pierwsze, wartość sygnału 0 oznaczałaby, że modulator nie ingerowałby w falę nośną - czyli symbol 0 zostałby nadany na częstotliwości środkowej (bezpośrednio na częstotliwości fali nośnej), a symbol 1 na częstotliwości dewiacji, czyli zdefiniowanej odchyłki częstotliwości. Raczej będziemy dążyć do sytuacji, w której częstotliwość fali nośnej jest punktem środkowym, a zmodulowane symbole na osi częstotliwości będą symetrycznie rozmieszczone względem częstotliwości sygnału nośnego. Przy takiej samej dewiacji, maksymalna odchyłka częstotliwości od fali nośnej będzie 2 razy mniejsza.
Tak więc kodowanie to sposób tworzenia sygnału modulującego z otrzymanych danych. Z jednej strony mamy dane binarne, które chcemy wysłać, a z drugiej strony chcemy wypuścić sygnał modulujący do modulatora. Dla zobrazowania rozbuduję poprzedni „uproszczony schemat nadajnika FSK”:
Dalej omówię przypadki kodowania na sybolach binarnych.
NRZ
Non Return to Zero - a więc „nie wracaj do zera”. Podstawowe kodowanie, które rozwiązuje problem opisany wyżej. Czyli przesuwamy wartości sygnału modulującego w dół tak, aby 0 znajdowało się symetrycznie względem stanu wysokiego a niskiego.
Dla uproszczenia symbole zakodowane w NRZ* będę zapisywał jako + dodatni, a - ujemny. Więc kodując w NRZ ciąg binarny 010101 uzyskujemy -+-+-+
Bez konkretnej wartości, ponieważ to już zależy od sposobu modulowania. Przykładowo, jeśli modulujemy poprzez zmiany w napięciu VCO, to wartość sygnału ’+’ będzie oznaczać przyrost napięcia potrzebny do zmiany częstotliwości o częstotliwość dewiacji, a ’-’ spadek napięcia potrzebny do obniżenia częstotliwości VCO.

NRZI
Non Return to Zero Inverted - czyli, tak jak w poprzednim przypadku, nie wracamy do zera. Natomiast już nie kopiujemy bezpośrednio wejściowego ciągu binarnego, lecz reagujemy na zmianę stanu bitu względem poprzedniego. Dla zobrazowania:
Na wejściu mamy ciąg 00000000 -> kodujemy do -------- oznacza to, że żaden bit się nie zmienił, więc kodujemy ciąg bez zmian stanu.
Na wejściu mamy ciąg 00001111 -> kodujemy do ----+---- przez pierwsze 4 bity stan sygnału się nie zmienił, więc kodujemy -; piąty bit to 1, czyli mamy zmianę stanu, a więc kodujemy +. Następne bity to dalej 1, więc względem poprzedniego bitu nie ma zmiany - kodujemy -.

Takie kodowanie upraszcza implementację demodulatora, ponieważ nie musimy rozróżniać znaku symbolu ’+’ czy ’-’, a poprzez same przekroczenia punktu 0 jesteśmy w stanie odtworzyć wcześniej zmodulowany ciąg binarny.
Kodowanie to jest popularne przy modulacji fazy, w której demodulator - bez żadnego dodatkowego sygnału referencyjnego - nie jest w stanie określić bezwzględnej wartości fazy, a jedynie jej względne zmiany.
Przykładowo, jeśli chcielibyśmy zdekodować transmisję FSK używająć radiostacji krótkofalarskiej oraz karty dzwiękowej. Tansmisja kodowana NRZI zostanie poprawnie zdekodowana niezależnie czy na radiu mamy załączone LSB czy USB.
Manchester
Na razie przeanalizowaliśmy dwa sposoby kodowania, natomiast mają one pewną wadę - długi ciąg 0 bądź 1 w danych do przesłania skutkuje brakiem zmiany stanu sygnału modulującego, co z kolei może prowadzić do problemów z synchronizacją po stronie odbiornika. Przy dużej prędkości przesyłu danych nawet drobne rozstrojenie zegara odbiornika względem zegara nadajnika może spowodować, że odbiornik pominie jakiś symbol bądź go zduplikuje.
Każda zmiana stanu sygnału modulującego daje możliwość synchronizacji oraz wyznaczenia względnego czasu trwania pojedynczego symbolu.

Kodowanie Manchester rozwiązuje ten problem poprzez użycie 2 syboli na jeden bit, z czego zawsze te 2 symbole mają różne stany.
Przykładowo 0 kodujemy jako +-
a 1 kodujemy jako -+
W zamian za 2 krotną ilość symboli wymaganych do przesłania tych samych danych, uzyskujemy możliwośc synchronizacji nawet gdy wartości ciągu wejsciowego nie ulegają zmianie.
Bit stuffing
Nie jest bezpośrednim sposobem kodowania danych, lecz często jest stosowany przy NRZ i NRZI, by zapobiec desynchronizacji. Co określoną liczbę symboli nie zmieniających stanu dorzuca się dodatkowy symbol o innym stanie.
ciąg wejsciowy: +++++++++
po bit stuffingu: +++++-++++
w tym przypadku co 5 powtarzających się symboli dorzucamy dodatkowy o przeciwnym stanie. Żeby to działało odbiornik i nadajnik muszą wiedzieć co ile symboli występuje insercja dodatkowego symbolu.
GFSK
Gaussian Frequency Shift Keying - jest to wariant modulacji FSK, w którym sygnał modulujący przed trafieniem do modulatora filtrowany jest filtrem Gaussowskim. Co powoduje wygładzenie zmian stanów sygnału modulującego.

Symulator (G) FSK
Źródła & fajne czytanki
Esezam PW · FSK · NRZ · Manchester code
Copyright © sq9p.com