Задержка в sdr-modem

В предыдущей статье я планировал реализовать не только отправку, но и приём сигнала с помощью plutosdr. Спустя месяц и несколько важных рефакторингов, я сделал всё, что хотел. Теперь можно напрямую сравнивать приём через plutosdr и через sdr-server. Понятное дело, через plutosdr будет намного быстрее. Мне же хотелось узнать насколько быстрее и померить эту задержку.

Описание стэнда

Алгоритм тестирования для plutosdr и sdr-server выглядит следущим образом:

  • создать сообщение
  • отправить в sdr-modem
  • записать время отправки
  • принять это же сообщение из sdr-modem
  • найти разницу между временем отправки и получения

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

В качестве канального уровня я выбрал HDLC. Он достаточно прост в реализации и уже доступен в jradio. Я отправлял 256 байт полезных данных, которые в результате превращались в 325 байт:

  • 50 байт тренировочной последовательности (01010101). Это нужно, чтобы приёмник лучше синхронизировался с сигналом. Можно было бы выбрать и 25, но я выбрал 50.
  • фрейм 265 байт. HDLC добавляет 0x7E в начало и конец полезной нагрузки, а так же делает положительное выравнивание.
  • 10 байт (00000000) для завершения фрейма. Можно и не добавлять, но мне хотелось посмотреть как будет выглядеть на спектограмме нулевая последовательность бит.

Данные передавались на скорости 9600 бод с помощью 2FSK модуляции. Теоретическая задержка составила бы: 325 байт * 8 бит / 9600 бод = ~270 мс.

Полный код теста можно найти в git репозитории sdr-modem-test.

Алгоритм тестирования в обоих случаях одинаковый, отличается только hardware. В случае с sdr-server схема выглядит следующим образом:

Фрейм отправляется в plutosdr, потом через несколько аттенюаторов попадает в rtl-sdr, потом в sdr-server, потом в sdr-modem и только потом в тест. Для тестирования plutosdr-plutosdr схема выглядит чуть-чуть по-проще.

Результаты

Задержка очень сильно зависит от размеров внутренних буферов. Чем больше буфер, тем меньше ЦПУ расходуется, но тем больше задержка. Чем меньше буфер, тем больше ЦПУ и меньше задержка. Я пробовал тесты для разных размеров буферов: 131072, 16384 и 8192 элемента. Результаты ниже:

Выводы

Для коммуникации в реальном времени, конечно же, лучше всего подходит plutosdr-plutosdr. При размере буфера 16384 или 8192 задержка составляет ~300 мс, что очень близко к теоретической. Кстати, интересно, а где находятся оставшиеся 30 мс? Для одностороннего получения сигнала лучше использовать связку rtl-sdr -> sdr-server -> sdr-modem. Это достаточно гибко и позволяет получать несколько сигналов одновременно.

Со схемой plutosdr-plutosdr, правда, есть несколько недостатков. По-умолчанию, на плате стоит генератор сигнала с TXCO 25ppm. Это достаточно большое число, которое может дать погрешность до 10кГц. Это достаточно много и для узкого сигнала в 9600 бод 2FSK может быть критично. Например, во время тестов принимались только ~6 из 10 сообщений.