FSK модуляция в sx127x

Я продолжаю работать над библиотекой sx127x. Как только стало понятно как писать интеграционные тесты, я приступил к работе над различными сценариями. sx127x поддерживает достаточно много различных режимов работы, которые неплохо было бы покрыть тестами.

Чип поддерживает три типа модуляции: LoRa, FSK и OOK. LoRa - это проприетарный протокол, основанный на chirp модуляции. Скорей всего его запрещено анализировать и воспроизводить из-за различных патентов и лицензий. А вот FSK и OOK - отличные кандидаты на исследование. Прежде всего за счёт того, что они стандартные и их можно посмотреть на спектрограмме, сделанной rtl-sdr. А всё, что можно визуализировать, то легче анализировать!

FSK без фильтра

Этот режим работы более корретно называть 2FSK, так как сигнал модулируется двумя частотами.

Для визуализации я использовал программу inspectrum. Сверху находится спектрограмма. Ось Y - это частота от +120кГц до -120кГц. Ось X - это время, которое увеличивается слева направо. Снизу находится демодулированный сигнал.

На спектрограмме очень хорошо виден резкий переход от одной частоты к другой. Из-за этого сигнал занимает достаточно широкую полосу частот. Для того, чтобы ограничить сигнал определённой шириной, применяются различные фильтры.

FSK с фильтром BT=0.5

sx127x позволяет фильтровать выходной сигнал гауссовским фильтром с BT=1, BT=0.5 и BT=0.3. Такая модуляция уже будет называться 2GFSK. Вот как это выглядит на спектрограмме:

Тут уже видно, что сигнал полностью помещается внутри канала, а переходы частоты немного сглажены.

Интересно, что передаваемое сообщение {0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00}, очень отчётливо видно. По крайней мере видны 0xFF и 0x00. Даже на спектрограмме вверху видно, что частота не меняется некоторое время. На самом деле такое лучше избегать. Обычно, приёмники имеют особые блоки для коррекции частоты. Для этого они усредняют сигнал и пытаются поместить его в baseband (0Гц). Если же сигнал долго не менялся (передаются одни нули или одни единицы), то такая коррекция может сильно исказить сигнал и результаты. Ещё одной причиной почему надо избегать долгую передачу одних нулей или одних единиц, является то, что непонятно сколько точно их было отправлено. Это прекрасно видно в нижней части скриншота. Для решения этой проблемы используют скрэмблер.

Скрэмблированный FSK с фильтром BT=0.5

Скрэмблер позволяет избегать длинных последовательностей нулей и единиц путём изменения оригинального сигнала. Полином скрэмблера должен быть одинаковый на приёмнике и передатчике. sx127x поддерживает скрэмблирование с помощью полинома X9 + X5 + 1. Результат работы выглядит следующим образом:

На скриншоте теперь видно, что в сигнале стало больше переходов между 0 и 1. А на спектрограмме уже нет такого чёткого разделения между одной и другой частотой.

Скорость передачи данных

sx127x поддерживает передачу данных на скорости от 1200 до 300000 бод. На примере ниже я передавал один и тот же сигнал на скорости 4800, 9600 и 19200 бод. Во всех случаях использовалось расстояние между модулирующими частотами 5кГц.

Здесь явно видно то, что, чем быстрее скорость, тем быстрее сообщение передаётся.

Демодуляция сигнала

Кстати, inspectrum позволяет проанализировать сигнал и вручную его демодулировать. Для этого можно добавить сеточку, где каждая вертикальная линия - это бит. Если сжимать или растягивать эту сеточку, то можно определить скорость передачи данных.

На примере выше, я добавил такую сетку в самое начало сообщения и выровнял по битам преамбулы.

Этот простой инструмент позволяет вручную проанализировать сигнал. Например, в моём случае сигнал начинается с преамбулы. Это специальная последовательность 0 и 1, которая позволяет подстроить частоту приёмника и синхронизатора битов. sx127x позволяет отправить преамбулу длиной 1,2 и 3 байта.

Далее идёт синхрослово размером 2 байта. sx127x поддерживает сихнрослова до 8 байт, но на практике такие большие не используются, так как передача сообщения будет занимать больше времени. Синхрослово позволяет организовывать несколько сетей. При обнаружении синхрослова sx127x будет его сравнивать с ожидаемым, если оно не совпало, то приёмник отбросит фрейм. Это позволяет улучшить отзывчивость приёмника, так как только нужные фреймы будут долетать до процессора.

После синхрослова идёт байт, содержащий длину пакета. sx127x позволяет передавать пакеты двух типов: с произвольной длиной и с фиксированной. У обоих типов есть преимущества и недостатки. В частности пакеты произвольной длины могут иметь максимальную длину 255 байт, а фиксированной - 2047.

И только после длины пакета начинается само сообщение.

На скриншоте этого не видно, но после сообщения идут 2 байта контрольной суммы. sx127x может автоматически генерировать контрольную сумму при отправке сообщения и проверять её при получении.

В принципе такой структуры сигнала достаточно, чтобы организовывать различные сети передачи данных. Если же нужно что-то более надёжное, то можно отключить генерацию контрольной суммы, использовать пакеты фиксированной длины и добавить нужные блоки вручную. Например, в космической связи повсеместно используются корректирующие коды. Наиболее распространённый - это код Рида-Соломона 255,223.

OOK модуляция

sx127x также поддерживает OOK модуляцию. Передатчик генерирует одну частоту если нужно передать 1, и не генерирует ничего если 0. Конфигурация такого режима очень похожа на FSK, за исключением того, что нет расстояния между модулирующими частотами и немного по-другому организован приёмник. Каково же моё удивление было, когда на спектрограмме я увидел картину похожую на FSK модуляцию. И каково же моё удивление было, когда я нашёл багу!

После исправления, спектрограмма стала больше похожа на нужную:

Здесь видно, что сигнала совсем нет, когда передаются нули. И частое включение и выключение, когда передаётся преамбула.

Ещё на спектрограмме видно, что OOK модуляция очень шумная и занимает достаточно широкий канал. Для того, чтобы её уменьшить можно изменить скорость включения и выключения несущего сигнала.

Заключение

В результате я написал около 13 различных тестов и покрыл основной функционал. Но, боюсь, этого недостаточно. Ведь я даже не приступал к более сложным тестам, таким как фильтрация адресов, автоматическая коррекция частоты и расчёт RSSI. Тем не менее, я ожидаю, что API не сильно изменится, а значит, можно будет сделать новый мажорный релиз - 3.0.