산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

부품 및 소모품

Arduino UNO 2
LED (범용) 2
포토레지스터 (조도 센서) 1
부저 1

프로젝트 소개

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

통신 시스템 수업에서 학생들이 시각화와 체험을 통해 배우게 하고 싶었습니다. 석기 시대부터 통신의 필요성, 언어와 문법, 신뢰성 있는 통신, 신호, 메시지 등을 실험으로 다뤘습니다.

이 과정에서 시각 통신용 자체 언어를 정의하게 되었고, 그곳에서 모스 부호를 고안했습니다!

모스 부호를 일일이 외우는 건 힘들므로 기계가 필요했습니다. 주어진 문자열을 모스 부호로 인코딩하고, 모스 부호 스트림을 다시 문자열로 디코딩하는 작은 프로그램을 작성하기로 했습니다.

모스 부호표 및 이진 트리

문자별 모스 부호는 다음 표를 참조했습니다.

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

모스 부호를 문자로 역변환하기 위해 이진 트리로 구성했습니다. '점(.)'은 왼쪽 서브트리, '대시(-)'는 오른쪽 서브트리로 이동합니다.

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

이를 이용해 문자열을 모스 부호로, 모스 부호를 문자열로 빠르게 변환할 수 있었습니다.

먼저 C#으로 개념 증명(PoC) 프로그램을 작성했습니다.

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용
Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

출력 예시

Hello World .... . .-.. .-.. --- .-- --- .-. .-.. -..

하지만 통신은 양방향이어야 하므로, 인코딩된 모스 부호를 다른 장치로 전송해 거기서 디코딩하고 싶었습니다. 두 개의 Arduino 보드로 송신기와 수신기를 만들었습니다.

송신기 (Transmitter)

송신기 보드에는 Keyes 레이저 다이오드를 연결했습니다. 저렴하고 구하기 쉽습니다. 제 거리에서는 3V 입력이 충분했지만 5V면 최소 200m까지 도달합니다.

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

송신기는 USB 시리얼로 컴퓨터와 연결됩니다. 시리얼 포트에서 문자 단위로 데이터를 읽어 해당 문자의 모스 부호를 찾아 '점'과 '대시' 빛 신호로 생성합니다.

50ms 펄스를 기본 단위로, '점'은 50ms 빛, '대시'는 150ms 빛을 냅니다. 각 점/대시 사이 50ms 무음, 문자 사이 100ms 무음을 둡니다.

송신기 코드

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, // space, !, ", #, $, %, &, '
  NULL, "-.-.--", ".-..-.", NULL, NULL, NULL, NULL, ".----.", // ( ) * + , - . /
  "-.--.", "-.--.-", NULL, ".-.-.", "--..--", "-....-", ".-.-.-", "-..-.", // 0-7
  "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", // 8-9 : ; < = > ?
  "---..", "----.", "---...", "-.-.-.", NULL, "-...-", NULL, "..--..", // @ A B C D E F G
  ".--.-.", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", // H I J K L M N O
  "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", // P Q R S T U V W
  ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", // X Y Z [ \ ] ^ _
  "-..-", "-.--", "--..", NULL, NULL, NULL, NULL, "..--.-", // ' a b c d e f g
  NULL, ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", // h i j k l m n o
  "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", // p q r s t u v w
  ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", // x y z { | } ~ DEL
  "-..-", "-.--", "--..", NULL, NULL, NULL, NULL, NULL
};

int dotLength = 50;
int dashLength = dotLength * 3;

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  char ch;
  if (Serial.available()) {
    ch = Serial.read();
    flashDashDot(MorseTable[ch]);
    delay(dotLength * 2);
  }
}

void flashDashDot(const char *morseCode) {
  int i = 0;
  while (morseCode[i] != 0) {
    if (morseCode[i] == '.') dot();
    else if (morseCode[i] == '-') dash();
    i++;
  }
}

void dot() {
  digitalWrite(13, HIGH);
  delay(dotLength);
  digitalWrite(13, LOW);
  delay(dotLength);
}

void dash() {
  digitalWrite(13, HIGH);
  delay(dashLength);
  digitalWrite(13, LOW);
  delay(dotLength);
}

수신기 (Receiver)

수신기 Arduino에는 LDR(조도 센서), 피에조 부저, LED를 연결했습니다. LED와 부저는 오디오/비디오 피드백용으로 필수는 아니지만 작동 확인에 좋습니다.

Arduino UNO로 모스 부호 송수신기 만들기 - 레이저와 조도 센서 활용

수신기도 컴퓨터에 연결해 결과 문자를 읽습니다. 루프에서 아날로그 포트 4에 연결된 LDR로 빛을 감지합니다. 주변광 차단을 위해 긴 튜브로 감쌌습니다. 레이저 빛이 LDR에 닿으면 값이 높아지고 스피커와 LED를 켭니다. 꺼지면 끕니다.

빛 지속 시간을 계산해 '점'인지 '대시'인지 판별합니다. 16MHz 아트멜 프로세서에서 약 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'
};

int val = 0;       // LDR 값
int ctrHigh = 0;   // HIGH 지속 카운트
int ctrLow = 0;    // LOW 지속 카운트
int codePtr = 0;   // 트리 포인터
int dotLen = 400;  // 점 길이 기준

void setup() {
  Serial.begin(9600);
  Serial.print(codePtr);
}

void loop() {
  val = analogRead(4);
  if (val >= 10) { // 빛 감지됨
    ctrHigh++;
    ctrLow = 0;
    digitalWrite(13, HIGH);
    tone(9, 1000);
  } else { // 빛 꺼짐
    ctrLow++;
    if (ctrHigh >= dotLen && ctrHigh < dotLen * 2) {
      Serial.print(".");
      codePtr = (2 * codePtr) + 1; // 왼쪽 자식
    } else if (ctrHigh >= dotLen * 2) {
      Serial.print("-");
      codePtr = (2 * codePtr) + 2; // 오른쪽 자식
    } else {
      if (ctrLow == dotLen * 2) { // 문자 간격
        Serial.print(MorseTree[codePtr]);
        codePtr = 0;
      }
    }
    ctrHigh = 0;
    digitalWrite(13, LOW);
    noTone(9);
  }
}

수신기 출력 예시

....H.E.-..L.-..L---O.--W---O.-.R.-..L-..D-.-.--!

회로도

모스 부호 수신기 회로: morsereceiver_1JpG6jZ6yv.fzz
모스 부호 송신기 회로: morsetransmitter_sOKvrIbOv3.fzz

제조공정

  1. 바코드 스캐너: 기술, 설계 및 미래 트렌드
  2. C++ 주석: 가독성 높고 유지보수하기 좋은 코드 작성법
  3. ADC 코드 에러율 마스터하기: 알아야 할 핵심 사항
  4. 모스 부호와 이중 갈취: 지능형 악성코드 위협의 현재
  5. 아두이노만으로 DTMF 디코더 구축하기 – 추가 IC 불필요
  6. SERENA: TFT LCD 터치스크린 탑재 아두이노 메가 2560 커스텀 알람 시스템
  7. 데이터 매트릭스 vs QR 코드: 비즈니스에 가장 적합한 것은?
  8. CNC G코드 필수 가이드: CNC 프로그래머를 위한 핵심 설명
  9. 완전한 Fanuc G코드 레퍼런스 - 모든 명령어 설명
  10. Fanuc 계열 CNC G코드 완벽 가이드: 전체 명령어 리스트