Это проект по сборке простого маломощного AM-передатчика кода Морзе, позволяющего передавать сообщения, которые можно будет принимать на любом транзисторном радиоприемнике в средневолновом диапазоне. Этого диапазона вполне достаточно для передачи между комнатами в доме, и при этом нет риска пересечься с каналом радиовещания.

Передатчик можно использовать для ручной отправки сообщений, вводя их при помощи кнопки или ключа Морзе. Вторая кнопка автоматически отправляет предопределенное сообщение, что может пригодиться для отработки навыка понимания кода.

Введение


Сын моего друга недавно заинтересовался кодом Морзе, что подтолкнуло меня собрать это устройство в подспорье его изучению и экспериментированию с отправкой сообщений.
Возможности у передатчика получились следующие:

  • Он позволяет телеграфировать код Морзе вручную, используя нажимную кнопку. При этом можно отслеживать его на светодиодном дисплее или слышать через пьезодинамик.
  • Если подключить к нему метровый кабель в качестве антенны, он сможет передавать код находящемуся неподалеку транзисторному АМ-радиоприемнику, позволяя двум людям обмениваться секретными, находясь в разных комнатах одного дома.
  • Он также способен воспроизводить или передавать предопределенное сообщение, что можно использовать для лучшего понимания кода Морзе и наработки скорости его ввода.

Построено устройство на базе ATtiny85 с минимумом дополнительных компонентов и является простым как в настройке, так и в использовании.

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

Код Морзе


В кодировке Морзе используется последовательность коротких и длинных сигналов, кодирующих буквы от A до Z, цифры от 0 до 9 и несколько знаков препинания. Таким образом сообщения могут посредством звука или света передаваться между двух людей, которые этот код знают. Чтобы придерживаться максимально коротких сообщений для самых распространенных букв английского алфавита определена краткая кодировка. Для редких же букв, наоборот:

Последовательности азбуки Морзе для букв и цифр

Продолжительность сигналов:
Элемент Продолжительность
Точка 1 единица
Тире 3 единицы
Пробел между точками или тире 1 единица
Пробел между символами 3 единицы
Пробел между словами 7 единиц

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

Схематичное представление последовательностей кода Морзе для букв от A до Z

Передача кода Морзе


Традиционно код Морзе передается при помощи техники, известной как «незатухающая волна», или CW. Точки и тире отправляются посредством подачи импульсов несущей частоты. На стандартном AM-передатчике присутствие несущей частоты можно обнаружить только путем настройки на эту частоту с последующей регистрацией провалов в фоновом шуме. Чтобы сделать код Морзе более отчетливым, радиолюбители встраивают в приемники генератор биений (BFO) с частотой близкой к несущей, в результате чего при ее присутствии возникает слышимый сигнал.

Поскольку домашние транзисторные AM-радиоприемники не имеют генератора биений, данный простой передатчик Морзе модулирует несущую частоту так, чтобы она генерировала слышимый тон. Вот образец графика такой амплитудно-модулированной несущей частоты1:


Схема


А вот схема самого передатчика:


Я взял ATtiny85, но программа также вполне подойдет и для ATtiny45 или ATtiny25.

Антенна должна представлять собой кабель до одного метра в длину. Один конец подключаем к PB1, второй оставляем неподключенным. Кабель при этом вывешивается примерно вертикально.

Если передавать код на радиоприемник вы не планируете, то антенну можно не делать, а обойтись просто пьезодинамиком2.

Использование АМ-передатчика


Для ручной генерации кода нажмите кнопку Keyer. Если у вас есть профессиональный ключ Морзе, то можете подключить его параллельно с этой кнопкой. Я использовал NanoKey от Phoenix Kits3.

Для генерации предопределенного в программе сообщения нажмите Auto. Чтобы прервать сообщение и вернуться в ручной режим, нажмите Keyer.

Можете заменить это сообщение любым желаемым, лишь бы оно вмещалось в память. Хранится оно в программной памяти ATtiny85, значит всего вам доступно около 7000 символов.

Программа


Выполнение всего тайминга и генерацию сигналов программа реализует через два таймера/счетчика ATtiny85 и сторожевой таймер, которые настраиваются в setup() следующим образом:

Таймер/Счетчик1


На ATtiny85 вы можете тактировать Таймер/Счетчик1 из системы ФАПЧ, которая из внутренних 8МГц генерирует 32МГц. Эта величина в OCR1C делится на 28, генерируя сигнал, используемый для активации вывода на антенну, PB1:

  // Настройка Таймера/Счетчика1 на генерацию 552кГц
  PLLCSR = 1<<LSM | 1<<PCKE | 1<<PLLE;
  TCCR1 =  1<<CTC1 | 1<<COM1A0 | 1<<CS10; // режим CTC /1
  OCR1C = 28;

Несущая частота:

f = 
 
320000002 × (28 + 1)
 
 = 552kHz

Эта частота находится в средневолновом диапазоне АМ, который простирается от 530кГц до 1600кГц, значит для получения кода Морзе приемник нужно просто настроить на эту частоту.

Точность тактов процессора ATtiny85 колеблется на ±10%, поэтому по факту несущая частота может оказаться несколько смещенной относительно указанной, и вам придется подстроить радио, пока в эфире не раздадутся гудки. Приведенная далее таблица показывает номинальные частоты, которые получатся для заданных значений OCR1C:

OCR1C 22 23 24 25 26 27 28 29
Частота 696кГц 667кГц 640кГц 615кГц 593кГц 571кГц 552кГц 533кГц

Выбирайте такую, которая соответствует свободному сегменту диапазона без транслирующих станций.

Таймер/Счетчик0


Таймер/Счетчик0 используется для генерации слышимой частоты в районе 644Гц4:

  // Настройка Таймера/Счетчика0 на 644Гц
  TCCR0A = 1<<COM0A0 | 2<<WGM00;          // режим CTC
  TCCR0B = 0<<WGM02 | 3<<CS00;            // Тактирование / 64
  OCR0A = 96;                             // Деление на 97
  TIMSK = 1<<OCIE0A;                      // Прерывание активно

Таймер/Счетчик0 активирует вывод PB0 для управления пьезодинамиком. Помимо этого, он служит для генерации прерываний. Процедура обработки прерываний включает/отключает тактирование Таймера/Счетчика1. Это ведет к появлению/исчезновению несущей частоты, что в качестве простой формы амплитудной модуляции делает точки и тире слышимыми на радиоприемнике в виде гудков:

// Прерывание модулирует несущую частоту 644Гц
ISR (TIMER0_COMPA_vect) {
  TCCR1 = TCCR1 ^ 1<<CS10;
}

В периоды тишины передается чистая несущая частота.

Сторожевой таймер


При автоматической генерации кода Морзе программа использует сторожевой таймер, генерируя прерывание 32Гц, которое служит для отсчета продолжительности точек, тире и интервалов:

  // Устанавливаем сторожевой таймер на прерывание 32Гц для таймера тиков
  WDTCR = 1<<WDIE | 1<<WDP0;              // Прерывание 32Гц 

Обработчик прерываний просто инкрементирует глобальный счетчик тиков, Ticks:

// Прерывание, генерируемое сторожевым таймером, отсчитывает тики (1/32сек)
ISR (WDT_vect) {
  WDTCR |= 1<<WDIE;
  Ticks++;
}

Прерывание автоматически восстанавливает сторожевой таймер, приводя к сбросу перед очередным прерыванием. Чтобы избежать этого, обработчик устанавливает бит прерывания до его следующего срабатывания:

  WDTCR |= 1<<WDIE;

Сторожевой таймер используется процедурой Wait(), которая ожидает заданное число тиков:

// Таймер тиков
void Wait (int units) {
  NextTick = NextTick + units * Dot;
  unsigned int t;
  do {
    cli(); t = Ticks; sei();
  } while (t < NextTick);
}

Обратите внимание, что на время считывания переменной Ticks прерывания отключены, чтобы исключить ее возможное обновление ими.

Общая скорость определяется константой Dot, которая указывает длительность точки в 1/32-х долях секунды. Изначально Dot установлена на 6, определяя скорость около 5 слов в минуту (WPM). Такая скорость достаточно невелика, чтобы можно было записывать буквы после их считывания. К тому же, именно такое ее значение использовалось на квалификационном экзамене радиолюбителей5. Для увеличения скорости уменьшите значение переменной Dot.

Генерация гудка


Процедура Beep() активирует/отключает генерацию гудка:

void Beep (bool on) {
  if (on) {
    digitalWrite(Lamp, HIGH);             // светодиод включен
    TCCR0B = 0<<WGM02 | 3<<CS00;          // тактирование / 64 
  } else {
    digitalWrite(Lamp, LOW);              // светодиод отключен
    TCCR0B = 0<<WGM02 | 0<<CS00;          // тактирование отключено
    TCCR1 =  TCCR1 | 1<<CS10;             // Оставляем несущую частоту активной
  }
}

Если параметр истинен, светодиод загорается и активируется тактирование Таймера/Счетчика0.

Если параметр ложен, светодиод тухнет и тактирование Таймера/Счетчика0 прекращается. Процедура также активирует тактирование Таймера/Счетчика1, потому что обработчик прерываний Таймера/Счетчика0 может оставить его отключенным.

Автоматическая генерация кода Морзе


Нажатие кнопки Auto приводит к генерации кода для строки Message[]:

const char Message[] PROGMEM = "The quick brown fox jumps over the lazy dog.  ";

Директива PROGMEM сохраняет сообщение во флэш памяти.

Кодирование букв от A до Z, цифр от 0 до 9 и выбор знаков препинания в программе реализуется с помощью таблицы соответствий Chars[], где представлены коды для точек и тире:

uint8_t Chars[42] = {
//A           B           C           D           E           F
  0b01100000, 0b10001000, 0b10101000, 0b10010000, 0b01000000, 0b00101000,
//G           H           I           J           K           L
  0b11010000, 0b00001000, 0b00100000, 0b01111000, 0b10110000, 0b01001000,
//M           N           O           P           Q           R
  0b11100000, 0b10100000, 0b11110000, 0b01101000, 0b11011000, 0b01010000,
//S           T           U           V           W           X
  0b00010000, 0b11000000, 0b00110000, 0b00011000, 0b01110000, 0b10011000,
//Y           Z           0           1           2           3
  0b10111000, 0b11001000, 0b11111100, 0b01111100, 0b00111100, 0b00011100,
//4           5           6           7           8           9
  0b00001100, 0b00000100, 0b10000100, 0b11000100, 0b11100100, 0b11110100,
//+           ,           -           .           ?           !
  0b01010100, 0b11001110, 0b10001100, 0b01010110, 0b00110010, 0b10101110,
};

Каждый восьмибитный код состоит из 0-й для точки и 1-ц для тире, которые сопровождаются завершающей 1, указывающей конец последовательности. Оставшиеся биты заполняются нулями.

Процедура Letter() получает символ ASCII, преобразует его в верный индекс из таблицы соответствий Chars[], после чего через вызов DotDash() выводит результат в виде последовательности точек и тире :

void Letter (char letter) {
  uint8_t index;
  letter = letter | 0x20;                 // Преобразует буквы в нижний регистр
  if (letter == ' ') { Wait(4); return; }
  if (letter >= '0' && letter <= '9') index = letter - '0' + 26;
  else if (letter >= 'a' && letter <= 'z') index = letter - 'a';
  else if (letter >= '+' && letter <= '.') index = letter - '+' + 36;
  else if (letter = '?') index = 38;
  else if (letter = '!') index = 39;
  else return;
  uint8_t code = Chars[index];
  while (code != 0x80) {
    DotDash(code & 0x80);
    code = code<<1;
  }
  Wait(2);
}

Процедура DotDash():

void DotDash (bool dash) {
  Beep(true);
  if (dash) Wait(3); else Wait(1);
  Beep(false);
  Wait(1);
}

DotDash() добавляет пробел продолжительностью в одну единицу времени после каждой точки или тире. Letter() при определении разрыва между символами и словами этот пробел учитывает.

Основная программа


Основная программа циклически проверяет нажатие любой из кнопок:

void loop() {
  // Manual mode
  if (digitalRead(Keyer) == 0) Beep(true);
  else Beep(false);
  // Auto mode
  if (digitalRead(Auto) == 0) {
    int p = 0; char c;
    do {
      char c = pgm_read_byte(&Message[p++]);
      if (c == 0 || digitalRead(Keyer) == 0) break;
      Letter(c);
    } while (true);
  } 
}

Кнопка Keyer при отжатии отправляет гудок. Кнопка Auto передает предопределенное сообщение. При этом также можно нажать Keyer, чтобы прервать отправку сообщения и вернуться к ручному вводу.

Компиляция программы


Для компиляции используйте ATTiny Core от Spence Konde6. Во вкладке ATtinyCore выберите опцию ATtiny25/45/85 (No bootloader), ведущую в меню Board. Убедитесь, что опции выставлены как указано ниже (прочие игнорируйте):

Chip: «ATtiny85»
Clock: «8 MHz (internal)»

Выберите Burn Bootloader для установки фьюз-битов в соответствии с этим вариантом частоты. Затем загрузите программу, используя ISP (внутрисхемное программирование). Я использовал программатор Tiny AVR от Sparkfun. Подробнее о нем можете почитать в статье ATtiny-Based Beginner's Kit.

Листинг программы


Вся программа для AM-передатчика кода Морзе лежит здесь: AM Morse-Code Transmitter Program.

Сноски


1. Этот график был сделан при помощи BitScope Micro BS05 Oscilloscope, который можно заказать на Pimoroni в UK.
2. Piezo Buzzer на сайте Adafruit.
3. The NanoKey на сайте PhoenixKitsonline.co.uk.
4. Это близко к 641Гц, частоте, используемой армией США для обучения работе с азбукой Морзе.
5. Традиционно величина WPM измеряется таймингом слов PARIS CODEX.
6. ATTinyCore на GitHub.

Комментарии (32)


  1. dMac
    01.01.2022 13:15
    +9

    Может быть, код Морзе и устарел, и неактуален, но - это единственный по-настоящему дальнобойный вид модуляции, который декодируется ушами и мозгом.


    1. drWhy
      01.01.2022 15:44
      +2

      Он неоптимален с той точки зрения, что различение двух сигналов выгоднее определения наличия или отсутствия одного, т.е. если бы ключ переключал две несущих, а не включал/выключал одну — дальность приёма исходя из соотношения сигнал/шум ещё увеличилась бы, а уж мозг приспособится.

      И да, декодировать перескок частоты или квадратурную модуляцию мозгу несколько сложнее. Но тот же перескок частоты придумала актриса Хеди Ламарр совместно с композитором и пианистом Джорджем Антейлом — тренированное ухо музыканта уверенно различает несколько нот в аккорде, т.е. как минимум приём треллис-кодирования освоить в принципе возможно.

      А азбука Морзе послужила на славу, и послужит ещё.


      1. sergej_pipets
        02.01.2022 16:34
        +1

        Переключение между двумя несущими - "частотная телеграфия (манипуляция)" тоже применяется. Но она сложнее в реализации, и плохо пригодна для хуманного приема.


      1. wAgo
        03.01.2022 17:22

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

        https://www.youtube.com/watch?v=nx3Ui_2I9ZU


      1. green88
        04.01.2022 12:07

        Именно служит.) Не так давно делал человеку (военнослужащему) преобразователь PS/2 клавиатуры в код Морзе. https://www.youtube.com/watch?v=BgdzBgIMACc


    1. funnycar
      01.01.2022 15:45
      +4

      Это да. В армии принимали радиограммы слушая изменения уровня помех, часто в таких условиях получалось принять без ошибок.


      1. green88
        04.01.2022 11:22

        Я до армии имел 1-й (взрослый) разряд по приёму/передаче. А в полку связи был только один прапорщик, который принимал 120 зн/минуту. Эх, молодость.)


    1. kwazar1471
      03.01.2022 05:54

      !


  1. alex323
    01.01.2022 13:30
    +9

    Может при такой малой мощности это не очень актуально, но передатчик явно излучает кучу гармоник.


    1. R820T2
      02.01.2022 17:38
      +1

      Импульсный блок питания излчает больше. Неактуально при такой мощности и использовании "как эксперимента"


  1. ioccy
    01.01.2022 13:47
    +2

    ATtiny слишком маломощен для такого сложного применения. Нужна как минимум STM32.


  1. AntonSor
    01.01.2022 14:35
    +5

    Нет, использовать в качестве передатчика "когда технологические решения окажутся недоступны" его не получится, как минимум, нужно будет на чем-нибудь его запрограммировать. Так что берете 6П3С и вперед


    1. drWhy
      01.01.2022 15:47
      +3

      Генератор от Москвича со снятым конденсатором — и перегазовкой SOS передать можно до горизонта. По крайней мере при проезде такого под окнами киловаттный телевизионный передатчик подавляло вплоть до срыва синхронизации.


      1. AntonSor
        01.01.2022 16:11
        +3

        Только с генератором постоянного тока :) со щетками :)


    1. CrashLogger
      01.01.2022 23:32
      +2

      В случае техногенной катастрофы найти компьютер и AVR будет намного проще, чем 6П3C и повышающий трансформатор для нее.


      1. sergej_pipets
        02.01.2022 16:38

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

        https://www.youtube.com/watch?v=QAuvFjVNtz8


      1. sim2q
        02.01.2022 18:57

        В случае техногенной катастрофы найти компьютер и AVR будет намного проще

        главное что бы там прошивки уцелели после гаммы и порты после ЭМИ


  1. Ukaru
    01.01.2022 14:42
    +2

    маломощного AM-передатчика кода Морзе, позволяющего передавать и принимать сообщения на любом транзисторном радиоприемнике

    То есть транзисторный радиоприёмник используется для передачи? Или предложение как сформулировано не очень удачно?

    Может быть "передавать сообщения которые легко могут быть приняты транзисторнвм радиоприемником"?


  1. korean_pilot
    01.01.2022 14:57
    +5

    Схемы на одном транзисторе для этих целей в современных реалиях уже явно недостаточно :-(


    1. drWhy
      01.01.2022 15:53

      Есть схема голосового передатчика на мощном транзисторе — электретный микрофон включается непосредственно в контур генератора и благодаря изменению его ёмкости в зависимости от речи позволяет генерировать ЧМ-сигнал.


      1. ioccy
        01.01.2022 16:03

        Да китайцы даже таких уродцев клепают

        Заголовок спойлера
        image


        1. drWhy
          01.01.2022 16:12
          +1

          Тридцать лет назад генератор передатчика от 27 МГц системы радиоуправления подключил к 100 В выходу трансляционного усилителя в школьном радиоузле, а на приёмнике с наушником слушал музыку на уроках с одноклассниками. Надо было запускать производство ;)


  1. begin_end
    01.01.2022 15:03
    +4

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

    С точки зрения стабильности частоты сигнала, чистоты от гармоник, мощности и отсутствии настройки антенны для отдачи этой мощности — радиопередающая часть проекта не удовлетворительна, можно сказать отсутствует.
    Сохранив почти всю программную часть, можно было бы управлять с контроллера каким-нибудь синтезатором типа AD9833, да с кварцем. А на выход простой фильтр, он же и согласование. Это не более чем вдвое усложнит схемотехнику, но будет уже не поделка для кружка, а очень маленький полноценный и цифровой QRPP передатчик.


    1. N-Cube
      01.01.2022 15:35
      +1

      Зачем тогда контроллер? Тут ведь микроконтроллер с кварцем вместо кварца всунут :) Да и синтезатор к чему... пусть кварц модулирует сигнал транзистора, если прямоугольный сигнал устраивает (нужна синосоида - плюс RC цепочка).


      1. begin_end
        01.01.2022 16:03
        +2

        Ну, сейчас все-таки не 30 лет назад. Если малыми усилиями можно получить удобное устройство, частота которого будет именно там, где надо сейчас и без плавания, почему бы и нет? + С некоторой автоматикой для морзянки (макросы на часто используемые фразы, такие как позывной, «cq text ...» при участии в определенном контесте, повторяемая автопередача когда сам стоишь на частоте и приглашаешь и др.).
        Другое дело, что именно схема в статье действительно бесполезна в таком применении.
        Ну и на ВЧ обычно не применяют RC фильтры — характеристики LC фильтров гораздо лучше, даже если использовать миниатюрные дросселя, а не добротные катушки.


        1. N-Cube
          01.01.2022 17:28
          +1

          характеристики LC фильтров гораздо лучше...

          Наверное, просто я никогда с покупными дросселями не сталкивался (проволоку и сердечник подобрать, намотать... куда проще RC фильтр поставить), динозавр, да.

          С некоторой автоматикой для морзянки...

          Ого, я о таком и не думал :)


    1. roach1967
      01.01.2022 19:37
      +1

      Здесь можно было-бы подключить вместо (или вместе с) пьезика какой-нибудь LC-генератор на трёхточке (ещё 3-6 деталек) — нам ведь нужно добить до соседней комнаты. А освободившийся вывод назначить на ввод своего сообщения.
      PS: только вывод на антенну лучше делать через дополнительную обмотку связи. Конечно это увеличит ещё больше сложность в монтаже, но частота передатчика не будет плавать от положения антенны от руки...


  1. VT100
    01.01.2022 20:48
    +6

    The antenna should be a length of cable up to a metre long.

    Длина антенны должна совпадать с длиной кабеля и иметь длину до одного метра.

    Поясните работу Вашего ИИ. Или у Вас "базовый надмозг"?


  1. deema35
    01.01.2022 21:17
    +2

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


  1. belav
    02.01.2022 04:01
    +5

    Кто ж азбуку Морзе учит по точкам и тире? Для каждого символа своя мелодия:

    А - ай-дА

    С - са-мо-лёт

    О - О-кО-лО


    1. sergej_pipets
      02.01.2022 16:45
      +1

      Потому у него и скорость 5 слов в минуту. Вместо минимальных зачетных 12 (не знаю, откуда взято именно пять как минимум). Пригодно разве что для бакена.

      Я не могу принимать уже где-то при 4wpm - разваливается мелодия.

      de RA1ATE


  1. sim31r
    02.01.2022 20:51
    +1

    Немного доработать и можно отправлять сигнал на другую сторону Земли

    https://habr.com/ru/post/369589/

    Как далеко можно передать радиосигнал? Это, пожалуй, наиболее интересный вопрос, который поднимался задолго до появления термина IoT как такового. Наиболее комплексно на этот вопрос попытался ответить Joseph Hooton Taylor, американский астрофизик и лауреат Нобелевской премии, создав в 2008 году программу Weak Signal Propagation Reporter (WSPR). Идея программы проста — передать сигнал, несущий минимум информации, который за счет этого может быть декодирован на максимально большом расстоянии. ... WSPR — это максимально простой цифровой сигнал, передающийся со скоростью всего лишь 1.4648 бод (да, лишь чуть больше 1 бита в секунду).