Почему лазерный луч, а не радиосвязь? Ради фана. С целью обеспечения секретности, радиопередачи перехватывают все кому не лень, а перехватывать вспышки света не догадаются, к тому же нужно встать в направлении передачи луча. Возможно использовать там, где радиосвязь невозможна из-за сильных помех.
Для эксперимента нам потребуется:
- 2 Arduino;
- 1 Фоторезистор (или LDR) VT90N — компонент, меняющий сопротивление в зависимости от количества света падающего на него. В полной темноте он имеет максимальное сопротивление в сотни килоом, а по мере роста освещённости сопротивление уменьшается до десятков килоом:
- 1 лазерный модуль KY-008:
- 2 сопротивления: 220 Ом для передатчика,10 кОм для приемника.
Передатчик
Передатчик подключается как самая простая схема в Ардуине (Blink), можно поморгать код Морзе и обычным светодиодом, но на небольшое расстояние, для передачи на метровые расстояния придется воспользоваться лазером. Лазер можно взять или из лазерной указки или купить в магазине специальный модуль для Ардуино с 3 контактами:
Схема подключения лазера к Ардуино:
Так как KY-008 part не нашлась в fritzing на схеме пришлось использовать RGB светодиод, подписав ноги S и “-“, S пин подключаем к 13 ноге, минус к GND (земле).
Для передачи данных воспользуемся кодом Морзе — способ представления букв алфавита последовательностью длинных («тире») и коротких («точка») сигналов. Конечно, при передаче кодом Морзе нет коррекции ошибок, но для тестовой передачи можно обойтись и без нее. Так как мы все равно знаем последовательность передаваемых символов.
В коде скетча указываем на каком контакте будет подаваться морзянка, 13 нога (как для большинства blink.ino скетчей моргания светодиодом), второй параметр отвечает за скорость передачи (24 слов в минуту), 3 параметр 1 для beep звукового сигнала и 0 для PTT (переключение пина в HIGH и LOW). Если заглянуть в код Morse.cpp то увидим что для третьего параметра 1 – beep используется как аналоговый выход запись на пин:
analogWrite(_pin, 128);
delay(_dashlen);
analogWrite(_pin, 0);
delay(_dotlen);
а для 0 – используется как цифровой выход
digitalWrite(_pin, HIGH);
delay(_dashlen);
digitalWrite(_pin, LOW);
delay(_dotlen);
В нашем случае используем код: Morse morse(13, 24, 0);
Для работы скетча необходима библиотекой morze.zip автора Erik Linder. Скетч передатчика простой:
// Author Erik Linder // Released 2011 under GNU GPLv3 // // Usage: morse( <pin number>, <speed WPM>, <1=beep, 0=PTT> ) // sendmsg( "<text-to-send>" ) // #include <Morse.h> // Use pin 13 (built-in LED of Arduino 2009) Morse morse(13, 24, 1); void setup() { } void loop() { morse.sendmsg("HELLO WORLD!"); delay (2000); }
Заливаем скетч, система готова к передаче данных.
Приемник
Собираем схему приемника, ничего сложного, фоторезистор одна нога с 5V вторая нога аналоговый порт A0, резистор 10 кОм — одна нога GND («земля»), вторая нога A0:
int LDR_Pin = A0; //analog pin 0 int led = 13; // 10k between GND and A0 // LDR between 5V and A0 #define MORSE_EMPTY 0 // Этими символами мы будем обозначать точки и тире. #define MORSE_DOT '*' #define MORSE_DOT2 '+' #define MORSE_TIRE '-' // Максимальная длина символа азбуки Морзе (в точках и тире) #define MAX_MORSE_SYMBOL_LENGTH 8 char* morseSymbol[MAX_MORSE_SYMBOL_LENGTH]; unsigned int morseSymbolLen; char* newMorseSignal; // Новый введенный сигнал - точка или тире. // Таблица кодов Морзе. N-ный элемент кода соответствует n-ному символу раскладки. char* code[] = { "*-","-***","*--","--*","-**","*","***-","--**","**","*---", "-*-","*-**","--","-*","---","*--*","*-*","***","-","**-", "**-*","****","-*-*","---*","----","--*-","-*--","-**-","**-**","**--", "*-*-", "*----","**---","***--","****-","*****","-****","--***","---**","----*","-----", "......","*-*-*-","---***","-*-*-","-*--*-","*----*","*-**-*","-****-","-**-*","**--**","--**--", "-***-","********","*--*-*","**-*-", "" }; // Кириллическая раскладка. char* layoutCyrillic[] = { "а","б","в","г","д","е","ж","з","и","й", "к","л","м","н","о","п","р","с","т","у", "ф","х","ц","ч","ш","щ","ы","ь","э","ю", "я", "1","2","3","4","5","6","7","8","9","0", ".",",",":",";","(","\'","\"","-","/","?","!", " *DELIMITER* "," *ERR* ","@"," *END* ", "" }; // Латинская раскладка. char* layoutLatin[] = { "a","b","w","g","d","e","v","z","i","j", "k","l","m","n","o","p","r","s","t","u", "f","h","c","ö","ch","q","y","x","é","ü", "ä", "1","2","3","4","5","6","7","8","9","0", ".",",",":",";","(","\'","\"","-","/","?","!", " *DELIMITER* "," *ERR* ","@"," *END* ", "" }; char** currentLayout; char** newLayout; void setup(){ Serial.begin(9600); pinMode(led, OUTPUT); morseSymbolLen = 0; newMorseSignal = MORSE_EMPTY; } int counter_high = 0; int counter_low = 0; int i; void loop(){ int LDRReading = analogRead(LDR_Pin); if (LDRReading >= 800){ counter_high++ ; if ( counter_low > 0 ){ // Serial.print("Low\t"); // Serial.print(counter_low); // Serial.print("\n"); } if ( counter_low > 1200) { // for (i = 0; i< morseSymbolLen; i++) { // Serial.print( currentLayout[i]); // } sendMorseSymbol(); morseSymbolLen=0; Serial.println(); //currentLayout[0]=" "; //currentLayout[1]=" "; //currentLayout[2]=" "; //currentLayout[3]=" "; //currentLayout[4]=" "; //currentLayout[5]=" "; //currentLayout[6]=" "; //currentLayout[7]=" "; //currentLayout[8]=" "; //morseSymbolLen=0; } counter_low=0; digitalWrite(led, HIGH); } else { // Serial.print("."); counter_low++; if ( counter_high > 0 ){ // Serial.print("High\t"); // Serial.print(counter_high); } if ( (counter_high < 1200 ) &&( counter_high >350)){ // Serial.print(counter_high); Serial.print("."); newMorseSignal="*"; morseSymbol[morseSymbolLen++] = newMorseSignal; // currentLayout[morseSymbolLen]="."; // morseSymbolLen=morseSymbolLen+1; } if ( counter_high > 1200 ){ // Serial.print(counter_high); Serial.print("-"); newMorseSignal="-"; morseSymbol[morseSymbolLen++] = newMorseSignal; // currentLayout[morseSymbolLen]="-"; // morseSymbolLen=morseSymbolLen+1; } counter_high=0; digitalWrite(led, LOW); } } void sendMorseSymbol() { boolean est; int i, j; est=-1; if (morseSymbolLen < 1) { return; } Serial.print(morseSymbolLen); // Символ из таблицы кодов Морзе соответствует введенному символу. // Отправим символ на компьютер. String str1; String strm; str1=""; for (i=0;i<morseSymbolLen;i++){ str1=str1+morseSymbol[i]; } // Serial.print(code[6]); for (i=0;i<56;i++){ String str2(code[i]); if (str1.compareTo(str2)==0){ //Serial.print(str1); // Serial.print("est"); Serial.print(str2); est=true; break; } } if (est!=-1){ Serial.print(layoutLatin[i]); } morseSymbolLen = 0; return; }
Приемник с LCD экраном
Полученные данные выводятся в COM порт, это конечно здорово, но не наглядно и требует наличие включенного компьютера. Поэтому подключаем 2 строчный экран с I2C подключением:
Для экрана SDA подключаем ногу arduino UNO A5, SCL – A4, VCC экрана к 5V, GND к GND:
Добавляем в скетче приемника receiver.ino строки отвечающие за вывод на 2 строчный LCD экран. Можно теперь уйти в поле с компактным приемником и прочитать сообщение прямо с LCD экрана.
#include <LCD.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> // Define I2C Address where the PCF8574* is #define I2C_ADDR 0x27 // Define LCD Pins #define BACKLIGHT_PIN 3 #define En_pin 2 #define Rw_pin 1 #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7 // Initialize LiquadCrystal with pin setup LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); int pos_lcd,pos_lcd2; int LDR_Pin = A0; //analog pin 0 int led = 13; // 10k between GND and A0 // LDR between 5V and A0 // настроить чувствительность фотоэлемента #define LEVEL_LDR 800 #define MORSE_EMPTY 0 // Этими символами мы будем обозначать точки и тире. #define MORSE_DOT '*' #define MORSE_DASH '-' //Длина точки и тире для 24 слов в минуту (wpm) = 150 мс и 700 мс, // Для 12 wpm = 700 и 1200 #define MORSE_TIME_DOT 150 #define MORSE_TIME_DASH 700 // Максимальная длина символа азбуки Морзе (в точках и тире) #define MAX_MORSE_SYMBOL_LENGTH 8 char* morseSymbol[MAX_MORSE_SYMBOL_LENGTH]; unsigned int morseSymbolLen; char* newMorseSignal; // Новый введенный сигнал - точка или тире. // Таблица кодов Морзе. N-ный элемент кода соответствует n-ному символу раскладки. char* code[] = { "*-","-***","*--","--*","-**","*","***-","--**","**","*---", "-*-","*-**","--","-*","---","*--*","*-*","***","-","**-", "**-*","****","-*-*","---*","----","--*-","-*--","-**-","**-**","**--", "*-*-", "*----","**---","***--","****-","*****","-****","--***","---**","----*","-----", "......","*-*-*-","---***","-*-*-","-*--*-","*----*","*-**-*","-****-","-**-*","**--**","--**--", "-***-","********","*--*-*","**-*-", "" }; // Кириллическая раскладка. char* layoutCyrillic[] = { "а","б","в","г","д","е","ж","з","и","й", "к","л","м","н","о","п","р","с","т","у", "ф","х","ц","ч","ш","щ","ы","ь","э","ю", "я", "1","2","3","4","5","6","7","8","9","0", ".",",",":",";","(","\'","\"","-","/","?","!", " *DELIMITER* "," *ERR* ","@"," *END* ", "" }; // Латинская раскладка. char* layoutLatin[] = { "a","b","w","g","d","e","v","z","i","j", "k","l","m","n","o","p","r","s","t","u", "f","h","c","ö","ch","q","y","x","é","ü", "ä", "1","2","3","4","5","6","7","8","9","0", ".",",",":",";","(","\'","\"","-","/","?","!", " *DELIMITER* "," *ERR* ","@"," *END* ", "" }; void setup(){ Serial.begin(9600); pos_lcd=0; lcd.begin (16,2); // Switch on the backlight lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); // Reset cursor to home lcd.home (); // Print Hello World // lcd.print("GOTOV priem"); pinMode(led, OUTPUT); morseSymbolLen = 0; newMorseSignal = MORSE_EMPTY; } int counter_high = 0; int counter_low = 0; int i; void loop(){ int LDRReading = analogRead(LDR_Pin); if (LDRReading >= LEVEL_LDR){ counter_high++ ; if ( counter_low > MORSE_TIME_DASH) { sendMorseSymbol(); morseSymbolLen=0; } counter_low=0; digitalWrite(led, HIGH); } else { counter_low++; if ( (counter_high < MORSE_TIME_DASH ) &&( counter_high >MORSE_TIME_DOT)){ Serial.print("."); newMorseSignal="*"; morseSymbol[morseSymbolLen++] = newMorseSignal; } if ( counter_high > MORSE_TIME_DASH ){ Serial.print("-"); newMorseSignal="-"; morseSymbol[morseSymbolLen++] = newMorseSignal; } counter_high=0; digitalWrite(led, LOW); } } void sendMorseSymbol() { boolean est; int i, j; est=-1; if (morseSymbolLen < 1) { return; } // Символ из таблицы кодов Морзе соответствует введенному символу. // Отправим символ на компьютер. String str1; str1=""; for (i=0;i<morseSymbolLen;i++) { str1=str1+morseSymbol[i]; } for (i=0;i<56;i++) { String str2(code[i]); if (str1.compareTo(str2)==0) { Serial.print(str2); est=true; break; } } if (est!=-1) { Serial.print(layoutLatin[i]); // Вывод символа на LCD экран if (pos_lcd>16 ) { Serial.print("vtorayStroka"); pos_lcd2=pos_lcd-17; Serial.print(pos_lcd); lcd.setCursor(pos_lcd2,1 ); //Пишем в LCD на 2 строк } pos_lcd=pos_lcd+1; if (pos_lcd>32) { lcd.clear(); pos_lcd=0; } lcd.print(layoutLatin[i]); lcd.setBacklight(HIGH); // Backlight on } morseSymbolLen = 0; return; }
Итоги
Данный способ передачи успешно работал у меня как и в комнате вечером на расстоянии 0,5–3 метра, так и вечером на улице на расстоянии 7–14 м. Большие расстояния пока не были опробованы. Передача днем потребует светозащищенной трубы чтобы на фотоэлемент не падал солнечный и дневной свет, а только свет от лазера или нужно поиграться параметром LEVEL_LDR отвечающий за чувствительность к свету в скетче приемника.
Источники
- Arduino Morse Code Sender/Receiver pair using lasers
- Знакомство с Arduino, часть 2. Морзе-клавиатура: альфа-версия
- Знакомство с Arduino, часть 3. Морзе-клавиатура: бета-версия
- Фонарик Морзе
- Morse Code Laser Transceiver
- Send Your Secret Spy Messages Wirelessly Through Light with This DIY Laser Audio Transmitter
- Laser Transceiver (laser data link)
- Raspberry Pi & Arduino: a laser pointer communication and a LDR voltage sigmoid
ссылка на оригинал статьи http://geektimes.ru/post/258948/
Добавить комментарий