Передача азбуки Морзе лазерным модулем — двухсторонний проект на Arduino
Компоненты и материалы
| Arduino UNO | 2 шт. |
| Макетная плата (breadboard) | 2 шт. |
| Лазерный передатчик (Autodesk LASER TRANSMITTER) | 1 шт. |
| Фоторезистор (LDR) | 1 шт. |
| Перемычки (набор) | 1 шт. |
Приложения и сервисы
- Arduino IDE
О проекте
Азбука Морзе
Азбука Морзе — это кодирование буквенно-цифровых символов (букв и цифр) в последовательности точек и тире. У каждого символа уникальная комбинация. Используется для передачи секретных или закодированных данных. В этом проекте реализованы передатчик и приёмник Морзе. Уникальность — в максимально простом алгоритме приёмника.
Шаг 1: Передатчик
Передатчик отправляет введённые данные через лазер.
Необходимое оборудование
- Arduino Uno
- Лазерный передатчик
- Макетная плата
- Перемычки
Подключение
Плюс лазера — к 13-му цифровому пину Arduino (как в коде). GND лазера — к GND Arduino.
Алгоритм программы
- Данные для передачи хранятся в массиве char.
- Определяется пин лазера.
- Задаётся скорость Морзе (длительность точки).
- Определяются длительности точки, тире, пауз между элементами, символами и словами.
- Каждый введённый символ проверяется через switch-case и преобразуется в последовательность HIGH/LOW на пине лазера.
Шаг 2: Приёмник
Закодированные данные, переданные лазером, принимаются, обрабатываются и выводятся в Serial Monitor.
Необходимое оборудование
- Arduino Uno
- Фоторезистор (LDR)
- Резистор 10 кОм
- Макетная плата
- Перемычки
Подключение
Один конец LDR — к 5 В Arduino. Второй конец LDR — к резистору 10 кОм и к аналоговому входу A0. Второй конец резистора — к GND Arduino.
Алгоритм приёмника (самый простой из существующих)
- Без лазера на LDR значение < 1000. Если даже при свете лазера значение не превышает 1000 — нужно прикрыть LDR от постороннего света (я использовал купол из чёрной бумаги).
- Когда лазер попадает на LDR, значение > 1000 — входим в цикл измерения.
- Квантуем значения: > 1000 → '1', иначе → '0'.
- В цикле считаем количество '1' (переменная
a) и '0' (переменнаяf) за фиксированное число отсчётов (13 итераций с задержкой 200 мс). - Сравниваем полученные пары
aиfс эталонами для каждого символа. Совпадение — выводим символ.
Ограничения
Приведённый код распознаёт только ограниченный набор символов. Его можно расширить, добавив больше комбинаций a/f. Главная цель — продемонстрировать алгоритм и принцип работы.
Код
КОД-1: Управление лазерным излучателем (передатчик)
int led13 = 13;
int dotLen = 200;
int dashLen = dotLen * 3;
int elemPause = dotLen;
int Spaces = dotLen * 3;
int wordPause = dotLen * 7;
char stringToMorseCode[] = "HELLO WORLD"; // пример сообщения
void setup() {
pinMode(led13, OUTPUT);
}
void loop() {
for (int i = 0; i < sizeof(stringToMorseCode) - 1; i++) {
char tmpChar = stringToMorseCode[i];
tmpChar = toLowerCase(tmpChar);
GetChar(tmpChar);
}
LightsOff(8000);
}
void MorseDot() {
digitalWrite(led13, HIGH);
delay(dotLen);
}
void MorseDash() {
digitalWrite(led13, HIGH);
delay(dashLen);
}
void LightsOff(int delayTime) {
digitalWrite(led13, LOW);
delay(delayTime);
}
void GetChar(char tmpChar) {
switch (tmpChar) {
case 'a': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'b': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'c': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'd': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'e': MorseDot(); LightsOff(elemPause); break;
case 'f': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'g': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'h': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'i': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'j': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'k': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'l': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'm': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'n': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'o': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'p': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 'q': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'r': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 's': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
case 't': MorseDash(); LightsOff(elemPause); break;
case 'u': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'v': MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'w': MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'x': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'y': MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); break;
case 'z': MorseDash(); LightsOff(elemPause); MorseDash(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); MorseDot(); LightsOff(elemPause); break;
default: LightsOff(Spaces);
}
}
КОД-2: Приёмник (LDR)
int sensorPin = 0;
int sensorValue = 0;
int a, f;
void setup() {
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(sensorPin);
if(sensorValue > 1000) {
for(int i=0; i<=13; i++) {
sensorValue = analogRead(sensorPin);
if(sensorValue > 1000) {
a++;
delay(200);
} else {
f++;
delay(200);
}
}
}
if(a==4 && f==10) { Serial.print("a"); }
if(a==6 && f==8) { Serial.print("b"); }
if(a==8 && f==6) { Serial.print("c"); }
if(a==1 && f==13) { Serial.print("e"); }
if(a==2 && f==12) { Serial.print("i"); }
if(a==10 && f==4) { Serial.print("j"); }
if(a==7 && f==7) { Serial.print("g"); }
if(a==9 && f==5) { Serial.print("o"); }
if(a==3 && f==11) { Serial.print("s"); }
f = a = 0;
delay(200);
}
Пользовательские детали и корпуса
Схемы
Производственный процесс
- Полное руководство по лазерной маркировке: типы, преимущества и применения
- Лазерный указатель: дизайн, производство и обзор безопасности
- Полупроводниковые лазеры: точное генерирование света для современных технологий
- Сканеры штрих-кода: технологии, дизайн и будущие тренды
- Лазерно-наводимые ракеты: разработка, производство и стратегическое воздействие
- Создание интерактивного лазерного проектора с Zigbee-сенсорами и платформой Gravio Edge
- Настройка UART-коммуникации между Raspberry Pi 4 и HiFive1
- Жестово-управляемый робот на Raspberry Pi
- Создание DTMF-декодера на Arduino без внешних микросхем
- 4 ключевых выгоды low-code решений для промышленного производства