Arduinoでモールス信号を表示してみました

先日はじめたばかりのArduino(Arduinoはじめました参照)ですが、カラフルなタクトスイッチを買ったので、Arduinoとスイッチを使ってモールス信号を表示する回路を作ってみました。

赤いスイッチと白いスイッチを適当な回数押して文字を指定してから黄色いスイッチを押すと、LEDが入力された文字のモールス信号で光ります。

モールス信号

モールス信号は、長い音(または光)と短い音(または光)の組み合わせで文字を表示する元祖デジタル信号。 日本語やハングルなどいろいろな文字があらわせるようなんですけど、ここではアルファベットのAからZまでだけを使っています。 くわしくはWikipediaで見てくださいね。

ここでは赤のスイッチと白のスイッチの二つで16進数を入力するようにしています。 例えば、「A」のモールス信号でLEDを光らせたかったら、赤を4回、白を1回押してから黄色を押してくださいね。 「B」だったら赤を4回、白を2回押してから黄色。 「C」だったら赤を4回、白を3回押してから黄色。 といった感じです。 (hexのascii codeです。)

SOSを出したかったらこんな感じでどうぞ。 「S」だったら赤を5回、白を3回押してから黄色。 「O」だったら赤を4回、白を15回押してから黄色。

パーツ

Arduinoに加えて、秋月電子でこちらのパーツを買いました。

抵抗の値が150Ωなのは、なんとなく……です。

回路

スイッチを使ったシンプルな回路です。 抵抗を適当にさしているので、導線どうしが触れてしまいそうなのがちょっと気になります。 (線を短くきればいいんだけど、そうすると再利用できなさそうなので、ついそのままで使ってます。)

20121229-175058.jpg

回路図で書くとこんな感じです。 (手書きですが。回路図を書くソフトが欲しいなー。あと、LEDってどんな記号だったか忘れてしまいました。) 実は、最初は150Ωの抵抗を抜かして回路を作ってしまって、「USBに過電流が流れています」とMac側でエラーがでてしまいました。

20121229-175229.jpg

ソースコード

ソースコードはこんな感じで。 5,6,7をデジタル入力として使用、13をLED用の出力として使用しています。 7で赤いタクトスイッチ、6で白いタクトスイッチ、5で黄色いタクトスイッチの入力を読んでいます。

loopの中で、赤か白のタクトスイッチが押された場合に、ボタンを押された回数をカウントアップしていき、黄色タクトスイッチが押されるとdigitalWriteとdelayでモールス信号を表示させています。 モールス信号情報は、morse_codeで保持してます。

const int BUTTON_RED = 7;
const int BUTTON_WHITE = 6;
const int BUTTON_YELLOW = 5;

const int LED = 13;

int press_count_red = 0;
int press_count_white = 0;
int press_count_yellow = 0;
int old_state_red = LOW;
int new_state_red = LOW;
int old_state_white = LOW;
int new_state_white = LOW;
int old_state_yellow = LOW;
int new_state_yellow = LOW;

//なし:0 トン:1 ツー:2
int morse_code[26][4] = {
  {1,2,0,0}, // A
  {2,1,1,1},
  {2,1,2,1},
  {2,1,1,0},
  {1,0,0,0}, // E
  {1,1,2,1},
  {2,2,1,0},
  {1,1,1,1},
  {1,1,0,0}, // I
  {1,2,2,2},
  {2,1,2,0},
  {1,2,1,1},
  {2,2,0,0}, // M
  {2,1,0,0},
  {2,2,2,0},
  {1,2,2,1},
  {2,2,1,2}, // Q
  {1,2,1,0},
  {1,1,1,0},
  {2,0,0,0},
  {1,1,2,0}, // U
  {1,1,1,2},
  {1,2,2,0},
  {2,1,1,2},
  {2,1,2,2}, // Y
  {2,2,1,1}
};

void setup(){
  
  Serial.begin(9600);
  
  pinMode(LED, OUTPUT);
  pinMode(BUTTON_RED,INPUT);
  pinMode(BUTTON_WHITE,INPUT);
  pinMode(BUTTON_YELLOW,INPUT);
}

void loop(){
  
  new_state_red = digitalRead(BUTTON_RED);
  new_state_white = digitalRead(BUTTON_WHITE);
  new_state_yellow = digitalRead(BUTTON_YELLOW);
  
  if( (new_state_red == HIGH) && (old_state_red == LOW) ){
    
    press_count_red = press_count_red + 1;
  }
  
  if( (new_state_white == HIGH) && (old_state_white == LOW) ){
    
    press_count_white = press_count_white + 1;
  }
  
  if( (new_state_yellow == HIGH) && (old_state_yellow == LOW) ){
    
    morse( press_count_red, press_count_white);
    press_count_red = 0;
    press_count_white = 0; 
    
  }

  delay(20);
  
  old_state_red = new_state_red;
  old_state_white = new_state_white;
  old_state_yellow = new_state_yellow;
  /*
  Serial.print("Press Count : ");
  Serial.print( press_count_red);
  Serial.print( " ");
  Serial.print( press_count_white);
  Serial.print( " ");
  Serial.print( press_count_yellow);
  Serial.print("\n\r");
  */
}

void morse(int a, int b){
  
  // ascii codeのみ。hexです。(from 41 to 5a)
  
  //Serial.print( "Morse with ");
  //Serial.print( a);
  //Serial.print( b);
  
  int a_code = 16*a + b;
  if( (a_code < 0x41) || (a_code > 0x5a)){
    //なにかエラー処理してあげたいんだけど……。
    return;
  }
  
  for( int i=0; i<4;i++){
    
    int morse_pulse = morse_code[a_code - 0x41][i];
    if( morse_pulse == 1){
      digitalWrite(LED,HIGH);
      delay(300);
      digitalWrite(LED,LOW);
      delay(300);
    }
    else if( morse_pulse == 2){
      digitalWrite(LED,HIGH);
      delay(1000);
      digitalWrite(LED,LOW);
      delay(300);
    }
    
  }
}

動作

動かすとこんな感じです。


Morse with Arduino

カラフルなタクトスイッチってかわいいので、いろいろと無駄に使ってみたくなりますね。

20121229-175105.jpg