Приемопередатчик кода Морзе
Компоненты и расходные материалы
![]() |
| × | 2 | |||
![]() |
| × | 2 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 |
Об этом проекте

Сегодня я вел класс по коммуникационным системам и хотел, чтобы мои ученики учились, визуализируя и испытывая. Мы провели несколько экспериментов, чтобы начать с каменного века и понять необходимость общения и то, что это означает под языком и грамматикой, что такое надежное общение, сигналы, сообщения и т. Д.
Обсуждая все это, мы подошли к моменту, когда захотели определить наш собственный язык для визуального общения, и там мы разработали азбуку Морзе!
Было очевидно, что изучение азбуки Морзе будет утомительной задачей для каждого из нас, и поэтому нам нужна была машина. Итак, мы решили написать небольшую программу, которая может кодировать заданную строку в эквивалентный код Морзе и другой декодер, который может вернуть строку для данного потока кода Морзе.
Чтобы найти код Морзе для символа, я ссылался на следующую таблицу -

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

Это позволило мне быстро закодировать строку в соответствующий код Морзе и наоборот.
Я написал программу на C # как PoC


Вывод
Привет, мир ..... .- .. .- .. --- .-- --- .-. .- .. - ..
Однако, поскольку связь должна происходить между двумя сторонами, я хотел передать этот закодированный код Морзе на другое устройство и расшифровать его там.
Я использовал две платы Arduino для создания передатчика и приемника.
На плате передатчика я подключил лазерный диод от Киза. Легкодоступное и дешевое устройство. Для того расстояния, на котором я работаю, входного напряжения 3 В было более чем достаточно, однако с 5 В я вижу, что лазер достигает как минимум 200 м.

Мой передатчик подключен к компьютеру с последовательным интерфейсом (через USB). Он считывает любые данные из последовательного порта посимвольно. Найдите эквивалентную азбуку Морзе для символа и сгенерируйте световой поток «точка» и «тире».
Я создал импульс 50 мс, где каждая «точка» представляет собой световой луч 50 мс, а «тире» - световой луч 150 мс. Каждые «точка» и «тире» разделяются паузами 50 мс. После каждого символа следует еще 100 мс молчания.
Код передатчика
const char * MorseTable [] ={NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // пробел,!, ", #, $,%, &, 'NULL," -. -.-- ",".-..-. ", NULL, NULL, NULL, NULL," .----. ", // () * +, -. /" -.--. ", "-.--.-", НУЛЕВОЙ, ".-.-.", "--..--", "-....-", ".-.-.-", "-.. -. ", // 0 1 2 3 4 5 6 7" ----- "," .---- "," ..--- "," ...-- "," ... .- "," ..... "," -.... "," --... ", // 8 9:; <=>?" --- .. "," --- -. "," ---... "," -.-.-. ", NULL," -...- ", NULL," ..-- .. ", // @ ABCDEFG" .- -.-. "," .- "," -... "," -.-. "," - .. ",". "," ..-. "," -. ", // HIJKLMNO "....", "..", ".---", "-.-", ".- ..", "-", "-.", "---", / / PQRSTUVW ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--" , // XYZ [\] ^ _ "-..-", "-.--", "- .. ", NULL, NULL, NULL, NULL," .. - .- ", // 'abcdefg NULL," .- "," -... "," -.-. "," - .. ",". "," ..-. "," -. ", // hijklmno" .... "," .. "," .--- "," -.- "," .- .. "," - "," -. "," --- ", // pqrstuvw" .--. "," --.- "," .-. "," ... "," - "," ..- "," ...- "," .-- ", // xyz {| } ~ DEL "-..-", "-.--", "- ..", NULL, NULL, NULL, NULL, NULL,}; int dotLength =50; int dashLength =dotLength * 3; установка void () {// поместите сюда свой установочный код, чтобы запустить его один раз:pinMode (13, OUTPUT); Serial.begin (9600);} void loop () {char ch; если (Serial.available ()) {ch =Serial.read (); flashDashDot (MorseTable [ch]); задержка (длина точки * 2); }} void flashDashDot (const char * morseCode) {int i =0; в то время как (morseCode [я]! =0) {если (morseCode [я] =='.') {точка (); } иначе, если (morseCode [я] =='-') {тире (); } I ++; }} void dot () {digitalWrite (13, HIGH); задержка (dotLength); digitalWrite (13, LOW); задержка (dotLength);} недействительный тире () {digitalWrite (13, HIGH); задержка (dashLength); digitalWrite (13, LOW); задержка (dotLength);}
На плате Receiver Arduino я подключил LDR , Пьезозуммер и светодиод . Светодиод и зуммер дублируют друг друга, просто они дают обратную связь по аудио и видео, и приятно видеть, как все работает 😉

Мой приемник также подключен к компьютеру для чтения полученного строкового символа.
На устройстве в цикле я считываю наличие любого света, попадающего на LDR, подключенный к аналоговому порту 4. Я экранировал его от любого окружающего света, заключив в капсулу с длинной трубкой. Когда свет моего лазерного диода попадает на этот LDR, результирующее значение становится высоким, я включаю динамик и включаю светодиод. Когда он погаснет, я отключаю динамик и выключаю.
Я вычисляю длину светового луча, чтобы определить, была ли это «точка» или «тире». С учетом всех задержек, на моем процессоре Atmel с тактовой частотой 16 МГц получилось ~ 400 циклов на импульс.
Код получателя
// Двоичное дерево кода Морзе // Левый дочерний элемент в 2n + 1 // Правый дочерний элемент в 2n + 2 // <. | -> // .E -T // .I -A .N - M // const char MorseTree [] ={'\ 0', 'E', 'T', 'I', 'A', 'N', 'M', 'S', 'U', 'R' , 'W', 'D', 'K', 'G', 'O', 'H', 'V', 'F', 'U', 'L', 'A', 'P', ' J ',' B ',' X ',' C ',' Y ',' Z ',' Q ',' \ 0 ',' \ 0 ',' 5 ',' 4 ',' \ 0 ', '3', '\ 0', '\ 0', '\ 0', '2', '\ 0', '\ 0', '+', '\ 0', '\ 0', '\ 0 ',' \ 0 ',' 1 ',' 6 ',' =',' / ',' \ 0 ',' \ 0 ',' \ 0 ',' (',' \ 0 ',' 7 ') , '\ 0', '\ 0', '\ 0', '8', '\ 0', '9', '0', '\ 0', '\ 0', '\ 0', '\ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ','? ',' _ '. , '\ 0', '\ 0', '\ 0', '\ 0', '"', '\ 0', '\ 0', '.', '\ 0', '\ 0', ' \ 0 ',' \ 0 ',' @ ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' - ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ', '\ 0', ';', '!', '\ 0', ')', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', ',' , '\ 0', '\ 0', '\ 0', '\ 0', ':', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0'}; int val =0; // Переменная для хранения значения освещения из LDRint ctrHigh =0; int ctrLow =0; int codePtr =0; int dotLen =400; void setup () {Serial.begin (9600); // Запуск последовательного соединения Последовательный .print (codePtr);} цикл void () {val =analogRead (4); если (значение> =10) {ctrHigh ++; ctrLow =0; digitalWrite (13, ВЫСОКИЙ); тон (9, 1000); } else {ctrLow ++; если ((ctrHigh> =dotLen) &&(ctrHigh =dotLen * 2) {Serial.print ("-"); codePtr =(2 * codePtr) + 2; } else {если (ctrLow ==dotLen * 2) {Serial.print (MorseTree [codePtr]); codePtr =0; }} CtrHigh =0; digitalWrite (13, LOW); noTone (9); }}
Вывод на приемнике .... HE - .. L .- .. L --- O .-- W --- O .-. R .- .. L - .. D-. -.--!
Код
- Передатчик
- Получатель
Передатчик Arduino
Код передатчикаconst char * MorseTable [] ={NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // пробел,!, ", #, $,%, &, 'NULL," -.- - ",".-..-. ", NULL, NULL, NULL, NULL," .----. ", // () * +, -. /" -.--. "," -.--.-", НУЛЕВОЙ, ".-.-.", "--..--", "-....-", ".-.-.-", "-..- . ", // 0 1 2 3 4 5 6 7" ----- "," .---- "," ..--- "," ...-- "," .... - "," ..... "," -.... "," --... ", // 8 9:; <=>?" --- .. "," ---- . "," ---... "," -.-.-. ", NULL," -...- ", NULL," ..-- .. ", // @ ABCDEFG" .-- .-. "," .- "," -... "," -.-. "," - .. ",". "," ..-. "," -. ", // HIJKLMNO «....», «..», «.---», «-.-», «.- ..», «-», «-.», «---», // PQRSTUVW ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", // XYZ [\] ^ _ "-..-", "-.--", "- ..", NULL, NULL, NULL, NULL, ".. - .-", // 'abcdefg NULL, «.-», «-...», «-.-.», «- ..», «.», «..-.», «-.», // hijklmn o "....", "..", ".---", "-.-", ".- ..", "-", "-.", "---", / / pqrstuvw ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--" , // xyz {| } ~ DEL "-..-", "-.--", "- ..", NULL, NULL, NULL, NULL, NULL,}; int dotLength =50; int dashLength =dotLength * 3; установка void () {// поместите сюда свой установочный код, чтобы запустить его один раз:pinMode (13, OUTPUT); Serial.begin (9600);} void loop () {char ch; если (Serial.available ()) {ch =Serial.read (); flashDashDot (MorseTable [ch]); задержка (длина точки * 2); }} void flashDashDot (const char * morseCode) {int i =0; в то время как (morseCode [я]! =0) {если (morseCode [я] =='.') {точка (); } иначе, если (morseCode [я] =='-') {тире (); } i ++; }} void dot () {digitalWrite (13, HIGH); задержка (dotLength); digitalWrite (13, LOW); задержка (dotLength);} недействительный тире () {digitalWrite (13, HIGH); задержка (dashLength); digitalWrite (13, LOW); задержка (dotLength);}
Приемник Arduino
Код приемника// Двоичное дерево кода Морзе // Левый дочерний элемент в 2n + 1 // Правый дочерний элемент в 2n + 2 // <. | -> // .E -T // .I -A .N -M // const char MorseTree [] ={'\ 0', 'E', 'T', 'I', 'A', 'N', 'M', 'S', 'U', 'R', W, D, K, G, O, H, V, F, U, L, A, P, J ',' B ',' X ',' C ',' Y ',' Z ',' Q ',' \ 0 ',' \ 0 ',' 5 ',' 4 ',' \ 0 ',' 3 ',' \ 0 ',' \ 0 ',' \ 0 ',' 2 ',' \ 0 ',' \ 0 ',' + ',' \ 0 ',' \ 0 ',' \ 0 ' , '\ 0', '1', '6', '=', '/', '\ 0', '\ 0', '\ 0', '(', '\ 0', '7', '\ 0', '\ 0', '\ 0', '8', '\ 0', '9', '0', '\ 0', '\ 0', '\ 0', '\ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ','? ',' _ ', '\ 0', '\ 0', '\ 0', '\ 0', '"', '\ 0', '\ 0', '.', '\ 0', '\ 0', '\ 0 ',' \ 0 ',' @ ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' - ',' \ 0 ' , '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', '\ 0', ';', '!', '\ 0', ' ) ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',', ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',':',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 ',' \ 0 '}; int val =0; // A Переменная для сохранения значения освещенности из LDRint ctrHigh =0; int ctrLow =0; int codePtr =0; int dotLen =400; void setup () {Serial.begin (9600); // Запуск последовательного соединения Serial.print ( codePtr); } void loop () {val =analogRead (4); если (значение> =10) {ctrHigh ++; ctrLow =0; digitalWrite (13, ВЫСОКИЙ); тон (9, 1000); } else {ctrLow ++; если ((ctrHigh> =dotLen) &&(ctrHigh=dotLen * 2) {Serial.print ("-"); codePtr =(2 * codePtr) + 2; } else {если (ctrLow ==dotLen * 2) {Serial.print (MorseTree [codePtr]); codePtr =0; }} ctrHigh =0; digitalWrite (13, LOW); noTone (9); }}
Схема
Схема приемника кода Морзе morsereceiver_1JpG6jZ6yv.fzz Схема передатчика кода Морзе morsetransmitter_sOKvrIbOv3.fzzПроизводственный процесс
- Сканер штрих-кода
- С++ Комментарии
- Общие сведения о частоте ошибок кода АЦП
- Код Морзе и двойное вымогательство:состояние вредоносного ПО сегодня
- Декодер DTMF с использованием только Arduino
- Система сигнализации Arduino:SERENA
- Коды Data Matrix против QR-кодов
- Введение в G-код ЧПУ
- Список G-кодов Fanuc
- Полный список G-кодов