Автоматическая передача данных через радиоканал
Re: Автоматическая передача данных через радиоканал
Провёл условно "эфирные" испытания: приём вёлся на наклонный луч диапазона 80 м, источником сигнала являлся ГСС, работающий на отрезок провода длиной 10 см, уровень сигнала 3 В.
НЧ сигнал с выхода радиостанции заведён на плату Arduino UNO через разделительный конденсатор и цепь смещения.
Уровень сигнала регулируется ручкой громкости так, чтобы не возникало перегрузки АЦП.
. .
Примерно так выглядит НЧ сигнал на выходе радиостанции.
Среди шумов просматривается наличие сигнала 1 кГц, на слух тон определяется очень хорошо.
. .
Считанные значения отсчётов с частотой сэмплирования 9 кГц, N=200, разрядность 10 бит, смещение 512 .
осцилограмма по отсчётам сигнала
. .
Спектрограмма принятого сигнала (по кнопке "Анализ") с обработкой оконной функцией HAMMING
В реальности шумовая полка кишит перемежающимися пиками уровня до 5000, но сильный тон в 1 кГц читается довольно устойчиво.
. .
без обработки оконными функциями сильно мешают низкочастотные компоненты
. .
НЧ сигнал с выхода радиостанции заведён на плату Arduino UNO через разделительный конденсатор и цепь смещения.
Уровень сигнала регулируется ручкой громкости так, чтобы не возникало перегрузки АЦП.
. .
Примерно так выглядит НЧ сигнал на выходе радиостанции.
Среди шумов просматривается наличие сигнала 1 кГц, на слух тон определяется очень хорошо.
. .
Считанные значения отсчётов с частотой сэмплирования 9 кГц, N=200, разрядность 10 бит, смещение 512 .
осцилограмма по отсчётам сигнала
. .
Спектрограмма принятого сигнала (по кнопке "Анализ") с обработкой оконной функцией HAMMING
В реальности шумовая полка кишит перемежающимися пиками уровня до 5000, но сильный тон в 1 кГц читается довольно устойчиво.
. .
без обработки оконными функциями сильно мешают низкочастотные компоненты
. .
Re: Автоматическая передача данных через радиоканал
Так, считанные пики не содержат полезной составляющей.
А если увеличить уровень входного сигнала в 2 раза, но ограничить разрядностью АЦП, т.е. усилить и подрезать?
делаю это пока в аналитическом виде на уже считанной последовательности: .
на осциллограмме видно ограничение большинства пиков
. .
думается, что некоторое ограничение имеет смысл.
Надо попробовать вариант схемы с диодами
.
А если увеличить уровень входного сигнала в 2 раза, но ограничить разрядностью АЦП, т.е. усилить и подрезать?
делаю это пока в аналитическом виде на уже считанной последовательности: .
на осциллограмме видно ограничение большинства пиков
. .
думается, что некоторое ограничение имеет смысл.
Надо попробовать вариант схемы с диодами
.
Re: Автоматическая передача данных через радиоканал
Для облегчения работы цифрового детектора был собран предварительный аналоговый фильтр на ОУ
. .
теоретическая характеристика
. .
фактическая характеристика (по шуму эфира)
. .
испытательные сигналы
.
. .
теоретическая характеристика
. .
фактическая характеристика (по шуму эфира)
. .
испытательные сигналы
.
Re: Автоматическая передача данных через радиоканал
Идея использовать частотный анализ для приёма сигналов RTTY по его протоколу оказалась ущербной.
Анализ требует длительного сбора данных, а протокол не предоставляет достаточно времени для этого.
Поэтому временно откладываем Гёрцеля в сторону и начинаем измерять непосредственно длительность интервалов прямоугольных импульсов.
Все RTTY-модемы имеют последним компонентом в своём составе компаратор. То есть, НЧ сигнал проходит диодный ограничитель, который срезает единичные выбросы (уровень сигнала подбирается заранее).
Далее сигнал фильтруется каскадом полосовых фильтров - выделяется нужная полоса частот.
Затем компаратором (усилитель без ООС, с большим Ку) итоговый сигнал превращается в прямоугольник.
На шумовом сигнале период импульсов постоянно меняется, при наличии полезного сигнала периоды постоянны.
Измеряя каждый период в отдельности можно получить представление о том сигнал какой частоты в данный конкретный момент времени присутствует на входе.
Нам нужно измерить и отличить частоты 1000 и 1170 Гц.
Период частоты 1000 Гц равен (1/1000)*1000000 = 1000 мкс. Полупериод 1000/2 = 500 мкс.
Для частоты 1170 Гц период (1/1170)*1000000 = 854,7 мкс. Соответственно , полупериод = 427 мкс.
Значит, нам нужно чётко отличать длительность импульса в 500 и 427 мкс. Разность в 73 мкс.
Ардуино позволяет производить отсчёт времени с квантом в 4 мкс.
Пробую написать скетч.
. .
По входу D2 объявляю отслеживание прерываний - сначала по фронту сигнала, потом по спаду.
В прерывании устанавливается только флаг прерывания, обработка происходит в основном цикле.
- вычисляется интервал относительно предыдущего полупериода,
- по каждому полупериоду определяется длительность,
- по фронту определяется частота,
- если частота оказалась в допускаемых пределах - в таблицу вписывается MARK или SPACE с меткой времени,
- пока идёт обработка прерывания - новое прерывание запрещено.
При наличии единичных ошибок (MSM или SMS) - таблица принудительно корректируется.
Таблица постоянно, с каждый новым считанным полупериодом двигается от начала к концу. Нулевой элемент самый свежий.
Обработки таблицы по протоколу пока нет,
просто если 20 раз подряд повторилась одна и та же частота - зажигаем светодиод.
Для контроля нужен RTTY-маяк.
Например, вот такой
https://github.com/lu1aat/rtty-arduino- ... ree/master
Анализ требует длительного сбора данных, а протокол не предоставляет достаточно времени для этого.
Поэтому временно откладываем Гёрцеля в сторону и начинаем измерять непосредственно длительность интервалов прямоугольных импульсов.
Все RTTY-модемы имеют последним компонентом в своём составе компаратор. То есть, НЧ сигнал проходит диодный ограничитель, который срезает единичные выбросы (уровень сигнала подбирается заранее).
Далее сигнал фильтруется каскадом полосовых фильтров - выделяется нужная полоса частот.
Затем компаратором (усилитель без ООС, с большим Ку) итоговый сигнал превращается в прямоугольник.
На шумовом сигнале период импульсов постоянно меняется, при наличии полезного сигнала периоды постоянны.
Измеряя каждый период в отдельности можно получить представление о том сигнал какой частоты в данный конкретный момент времени присутствует на входе.
Нам нужно измерить и отличить частоты 1000 и 1170 Гц.
Период частоты 1000 Гц равен (1/1000)*1000000 = 1000 мкс. Полупериод 1000/2 = 500 мкс.
Для частоты 1170 Гц период (1/1170)*1000000 = 854,7 мкс. Соответственно , полупериод = 427 мкс.
Значит, нам нужно чётко отличать длительность импульса в 500 и 427 мкс. Разность в 73 мкс.
Ардуино позволяет производить отсчёт времени с квантом в 4 мкс.
Пробую написать скетч.
. .
По входу D2 объявляю отслеживание прерываний - сначала по фронту сигнала, потом по спаду.
В прерывании устанавливается только флаг прерывания, обработка происходит в основном цикле.
- вычисляется интервал относительно предыдущего полупериода,
- по каждому полупериоду определяется длительность,
- по фронту определяется частота,
- если частота оказалась в допускаемых пределах - в таблицу вписывается MARK или SPACE с меткой времени,
- пока идёт обработка прерывания - новое прерывание запрещено.
При наличии единичных ошибок (MSM или SMS) - таблица принудительно корректируется.
Таблица постоянно, с каждый новым считанным полупериодом двигается от начала к концу. Нулевой элемент самый свежий.
Обработки таблицы по протоколу пока нет,
просто если 20 раз подряд повторилась одна и та же частота - зажигаем светодиод.
Для контроля нужен RTTY-маяк.
Например, вот такой
https://github.com/lu1aat/rtty-arduino- ... ree/master
Re: Автоматическая передача данных через радиоканал
Посмотрел, как распознают RTTY японцы.
Например K.Iwasa JI3BNB
https://k183.bake-neko.net/ji3bnb/page13.html#TELEMETRY
. .
Периодически тикает таймер (каждую миллисекунду) и в прерывании читает состояние пина.
Если обнаружен стартовый бит, то через 10 мс от его начала запускается счётчик миллисекунд:
- через 22 мм читается состояние бит0,
- через 44 мм читается состояние бит1,
- через 66 мм читается состояние бит2,
- через 88 мм читается состояние бит3,
- через 110 мм читается состояние бит4 и выставляется флаг приёма данных.
На 135 миллисекунде приём символа прекращается. Таймер возвращается в исходное состояние.
Например K.Iwasa JI3BNB
https://k183.bake-neko.net/ji3bnb/page13.html#TELEMETRY
. .
Периодически тикает таймер (каждую миллисекунду) и в прерывании читает состояние пина.
Если обнаружен стартовый бит, то через 10 мс от его начала запускается счётчик миллисекунд:
- через 22 мм читается состояние бит0,
- через 44 мм читается состояние бит1,
- через 66 мм читается состояние бит2,
- через 88 мм читается состояние бит3,
- через 110 мм читается состояние бит4 и выставляется флаг приёма данных.
На 135 миллисекунде приём символа прекращается. Таймер возвращается в исходное состояние.
Re: Автоматическая передача данных через радиоканал
Измерение времени полупериодов позволяет быстро и чётко различать частоты.
На меандре редко проскакивают ошибки в один квант:
- это от 992 до 1008 Гц для частоты 1000 Гц,
- и от 1157 до 1179 Гц для 1170 Гц.
На реальном сигнале достаточно определить +/- 50 Гц, это указал в программе
. .
.
При каждом нарастании амплитуды происходит прерывание ISR_UP, которое читает время TimeUp.
При каждом спаде амплитуды происходит прерывание ISR_DWN, которое читает время TimeDwn.
. .
Разность этих точек составляет длительность положительного или отрицательного полупериодов Time1 и Time2.
Пока ждём следующее прерывание, на основании последних двух полупериодов вычисляем частоту.
Если полученная частота попадает в интервал +/- 50 Гц от частот MARK или SPACE, то поднимаем соответствующий флаг.
На меандре редко проскакивают ошибки в один квант:
- это от 992 до 1008 Гц для частоты 1000 Гц,
- и от 1157 до 1179 Гц для 1170 Гц.
На реальном сигнале достаточно определить +/- 50 Гц, это указал в программе
. .
Код: Выделить всё
void ISR_UP() {
// произошло прерывание по фронту
detachInterrupt(0); // отключить прерывание 0
TimeUp = micros(); // старт таймера Up
Time1 = TimeUp - TimeDwn; // длительность - полупериода
attachInterrupt(0, ISR_DWN, FALLING); // включить прерывание по спаду
}
void ISR_DWN() {
// произошло прерывание по спаду
detachInterrupt(0); // отключить прерывание 0
TimeDwn = micros(); // старт таймера Dwn
Time2 = TimeDwn - TimeUp; // длительность + полупериода
attachInterrupt(0, ISR_UP, RISING); // включить прерывание по фронту
}
void loop() {
Freq = 1000000/(Time1+Time2);
if (Freq <= Fm+dF && Freq >= Fm-dF) {Mark = true;} // пишем MARK
else if (Freq <= Fs+dF && Freq >= Fs-dF) {Space = true;} // пишем SPACE
else {Mark = false; Space = false;} // если частота невнятная, то ничего
// включить светодиоды LEDMARK или LEDSPACE
if (Mark == 1) digitalWrite(LEDMARK_PIN, HIGH); else digitalWrite(LEDMARK_PIN, LOW);
if (Space == 1) digitalWrite(LEDSPACE_PIN, HIGH); else digitalWrite(LEDSPACE_PIN, LOW);
При каждом нарастании амплитуды происходит прерывание ISR_UP, которое читает время TimeUp.
При каждом спаде амплитуды происходит прерывание ISR_DWN, которое читает время TimeDwn.
. .
Разность этих точек составляет длительность положительного или отрицательного полупериодов Time1 и Time2.
Пока ждём следующее прерывание, на основании последних двух полупериодов вычисляем частоту.
Если полученная частота попадает в интервал +/- 50 Гц от частот MARK или SPACE, то поднимаем соответствующий флаг.
Re: Автоматическая передача данных через радиоканал
Чтобы добиться чёткости работы и проследить за изменениями уровней сигналов, я затормозил передачу символов до 500 мс на бит.
Передатчик передаёт напрямую через модуль Si5351 на частоте 3650 кГц - 1 кГц - 170 Гц для приёма в LSB.
. .
MESSAGE[] = "CQ DE";
MARK = 1000 Гц
SPACE = 1170 Гц
Передаваемые символы
37 CR
37 CR
2 C
16 Q
36 SPACE
3 D
4 E
37 CR
37 CR
Передаются следующие уровни (длительность каждого бита DATA - 500 мс)
Передача ведётся на провод длиной 10 см.
На приёмной стороне антенна наклонный луч на 80 м и радиостанция Карат-3,5АТ. С разъёма гарнитуры через полосовой фильтр и компаратор сигнал подаётся на цифровой вход платы Arduino Uno.
. .
Программным способом, о котором уже писал выше, определяется частота сигнала и выводится значения MARK, SPACE и их длительность:
Передатчик передаёт напрямую через модуль Si5351 на частоте 3650 кГц - 1 кГц - 170 Гц для приёма в LSB.
. .
MESSAGE[] = "CQ DE";
MARK = 1000 Гц
SPACE = 1170 Гц
Передаваемые символы
37 CR
37 CR
2 C
16 Q
36 SPACE
3 D
4 E
37 CR
37 CR
Передаются следующие уровни (длительность каждого бита DATA - 500 мс)
Код: Выделить всё
MARK1 = 200
StartBit: SPACE0 = 500
DATA0
DATA0
DATA0
DATA1
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA0
DATA0
DATA0
DATA1
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA0
DATA1
DATA1
DATA1
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA1
DATA1
DATA1
DATA0
DATA1
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA0
DATA0
DATA1
DATA0
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA1
DATA0
DATA0
DATA1
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA1
DATA0
DATA0
DATA0
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA0
DATA0
DATA0
DATA1
DATA0
StopBit: MARK1 = 750.00
StartBit: SPACE0 = 500
DATA0
DATA0
DATA0
DATA1
DATA0
StopBit: MARK1 = 750.00На приёмной стороне антенна наклонный луч на 80 м и радиостанция Карат-3,5АТ. С разъёма гарнитуры через полосовой фильтр и компаратор сигнал подаётся на цифровой вход платы Arduino Uno.
. .
Программным способом, о котором уже писал выше, определяется частота сигнала и выводится значения MARK, SPACE и их длительность:
Код: Выделить всё
MARK=1 SPACE=0 DUR=221
23:44:52.584 -> MARK=0 SPACE=1 DUR=2014
23:44:54.589 -> MARK=1 SPACE=0 DUR=504
23:44:55.099 -> MARK=0 SPACE=1 DUR=504
23:44:55.609 -> MARK=1 SPACE=0 DUR=753
23:44:56.358 -> MARK=0 SPACE=1 DUR=2014
23:44:58.362 -> MARK=1 SPACE=0 DUR=502
23:44:58.872 -> MARK=0 SPACE=1 DUR=502
23:44:59.382 -> MARK=1 SPACE=0 DUR=755
23:45:00.130 -> MARK=0 SPACE=1 DUR=1005
23:45:01.150 -> MARK=1 SPACE=0 DUR=1509
23:45:02.644 -> MARK=0 SPACE=1 DUR=504
23:45:03.154 -> MARK=1 SPACE=0 DUR=753
23:45:03.902 -> MARK=0 SPACE=1 DUR=504
23:45:04.412 -> MARK=1 SPACE=0 DUR=1511
23:45:05.908 -> MARK=0 SPACE=1 DUR=503
23:45:06.418 -> MARK=1 SPACE=0 DUR=1258
23:45:07.676 -> MARK=0 SPACE=1 DUR=1510
23:45:09.206 -> MARK=1 SPACE=0 DUR=503
23:45:09.682 -> MARK=0 SPACE=1 DUR=1008
23:45:10.701 -> MARK=1 SPACE=0 DUR=753
23:45:11.449 -> MARK=0 SPACE=1 DUR=503
23:45:11.960 -> MARK=1 SPACE=0 DUR=504
23:45:12.470 -> MARK=0 SPACE=1 DUR=1007
23:45:13.456 -> MARK=1 SPACE=0 DUR=502
23:45:13.965 -> MARK=0 SPACE=1 DUR=504
23:45:14.475 -> MARK=1 SPACE=0 DUR=754
23:45:15.223 -> MARK=0 SPACE=1 DUR=503
23:45:15.733 -> MARK=1 SPACE=0 DUR=504
23:45:16.243 -> MARK=0 SPACE=1 DUR=2015
23:45:18.248 -> MARK=1 SPACE=0 DUR=751
23:45:18.995 -> MARK=0 SPACE=1 DUR=2014
23:45:21.036 -> MARK=1 SPACE=0 DUR=504
23:45:21.511 -> MARK=0 SPACE=1 DUR=504
23:45:22.020 -> MARK=1 SPACE=0 DUR=754
23:45:22.767 -> MARK=0 SPACE=1 DUR=2013
23:45:24.806 -> MARK=1 SPACE=0 DUR=504
23:45:25.315 -> MARK=0 SPACE=1 DUR=503
23:45:25.791 -> MARK=1 SPACE=0 DUR=1097
Re: Автоматическая передача данных через радиоканал
Как видим, со временем тайминги уплывают.
Для точной привязки думаю следует каждый раз определять время начала старт-бита и синхронизироваться по нему.
В течении передачи одного символа рассинхронизация маловероятна.
График по принятым выше данным:
. .
Как можно определить стартовый бит?
Перед ним длительность уровня MARK приблизительно равна 1,5 от длительности тона,
т.е. это не единица, слившаяся со стоповым битом (тогда длина была бы больше),
и в то же время это не две смежные единицы в середине посылки.
Выявив MARK длительностью х1,5, можно предположить, что следующий за ним фронт SPACE будет началом стартового бита.
Но лучше подождать х0,8 длины, чтобы убедиться окончательно.
. .
Теперь можно поднять флаг чтения символа и, отмеряя интервалы от красной линии, получать значения битов (зелёные линии).
Не очень хочу использовать таймер, т.к. пока непонятно, как его прерывание будет конфликтовать с прерыванием по чтению частоты.
Возможно позже таймер заменит все эти конструкции.
В данном случае передаётся код 0-0-0-1-0, что соответствует символу № 37 - Carriage Return
Для точной привязки думаю следует каждый раз определять время начала старт-бита и синхронизироваться по нему.
В течении передачи одного символа рассинхронизация маловероятна.
График по принятым выше данным:
. .
Как можно определить стартовый бит?
Перед ним длительность уровня MARK приблизительно равна 1,5 от длительности тона,
т.е. это не единица, слившаяся со стоповым битом (тогда длина была бы больше),
и в то же время это не две смежные единицы в середине посылки.
Выявив MARK длительностью х1,5, можно предположить, что следующий за ним фронт SPACE будет началом стартового бита.
Но лучше подождать х0,8 длины, чтобы убедиться окончательно.
. .
Теперь можно поднять флаг чтения символа и, отмеряя интервалы от красной линии, получать значения битов (зелёные линии).
Не очень хочу использовать таймер, т.к. пока непонятно, как его прерывание будет конфликтовать с прерыванием по чтению частоты.
Возможно позже таймер заменит все эти конструкции.
В данном случае передаётся код 0-0-0-1-0, что соответствует символу № 37 - Carriage Return
- Вложения
-
- m006.rar
- (2.15 КБ) 1153 скачивания
Re: Автоматическая передача данных через радиоканал
Первая версия предварительного аналогового фильтра-формирователя.
Питание предполагается от разъёма тангенты радиостанции Карат-3.5, поэтому последовательно стоят линейные стабилизаторы для аналоговой и цифровой частей на +9 и +5 В соответственно.
Так как размах сигнала на выходе радиостанции достигает 12 В, на входе установлен делитель 1:10 и диодный ограничитель, который срабатывает только на пиках сигнала (щелчки или перегрузка).
Далее идёт аналоговый трёхкаскадный полосовой фильтр с полосой пропускания 1000...1170 Гц (характеристика приведена ниже).
После фильтрации сигнал поступает на усилитель-ограничитель с высоким коэффициентом усиления, собранный на ОУ без обратной связи. Балансировкой (резистор R15) добиваются наивысшей чувствительности (размах сигнала на входе - 5...10 мВ).
Оконечная часть (триггер Шмитта на DD1) ещё находится на отладке.
. . .
Разводка выполнена на макетной плате 5х7 см
.
Питание предполагается от разъёма тангенты радиостанции Карат-3.5, поэтому последовательно стоят линейные стабилизаторы для аналоговой и цифровой частей на +9 и +5 В соответственно.
Так как размах сигнала на выходе радиостанции достигает 12 В, на входе установлен делитель 1:10 и диодный ограничитель, который срабатывает только на пиках сигнала (щелчки или перегрузка).
Далее идёт аналоговый трёхкаскадный полосовой фильтр с полосой пропускания 1000...1170 Гц (характеристика приведена ниже).
После фильтрации сигнал поступает на усилитель-ограничитель с высоким коэффициентом усиления, собранный на ОУ без обратной связи. Балансировкой (резистор R15) добиваются наивысшей чувствительности (размах сигнала на входе - 5...10 мВ).
Оконечная часть (триггер Шмитта на DD1) ещё находится на отладке.
. . .
Разводка выполнена на макетной плате 5х7 см
.
- Вложения
-
- Modem_v101.rar
- (607.82 КБ) 763 скачивания
Re: Автоматическая передача данных через радиоканал
Полный размах сигнала на НЧ-выходе радиостанции (шум эфира)
. .
то же (сигнал)
. .
шум эфира на выходе фильтра-формирователя
. .
полезный сигнал на выходе фильтра-формирователя
.
. .
то же (сигнал)
. .
шум эфира на выходе фильтра-формирователя
. .
полезный сигнал на выходе фильтра-формирователя
.