Arduino CW decoder(モールス 解読器)

2015年1月23日


CW(モールス)デコーダ(解読器)をArduinoで作ってみました。
0番ピンにCW(モールス符号)のdigital信号を入れます。
表示は秋月電子のSC1602BBWB(バックライト付き白抜き文字表示)を使いました。

回路図です。

Arduino UNO とブレッドボードの接続の様子です。(和文モールスも解読できます)

自分なりに解読(デコード)のアルゴリズムを考えてみました。(たぶん、もっと良い方法があると思いますが、参考までに)
入力する信号の様子です。
エレキーからの出力などをプルアップした0番ピンに入力するとdot(短点)またはdash(長点)の時にLOWレベルになります。
Arduinoの内部タイマのmillis()関数を利用して、LOW状態が始まった時刻とHIGH状態が始まった時刻を測定します。
図のLOWtimeは、startHIGH - startLOWで求めることができます。
このLOWtimeが基準時間より短ければdot、長ければdashと判定します。
基準時間を100msとすると12wpmから35wpm程度まで、dotとdashを判定できます。
実用上は、この値で十分だと思います。(将来的には速度の自動調節を考えています)

dot(短点)とdash(長点)の判定が出来たら、モールス符号を中間コードにします。
例えば、次のようにA、Bというモールス符号なら、入力は図のようになります。

この部分のスケッチは、次のようになります。
Mcodeは中間コード、8bitなので、byte型です。
Mcodeは初期値として1(スタートビット)にしておきます。
dot(data=0)または、dash(data=1)が入力されるたびにMcodeは左に1bitシフトして、
dataとのORをとることにより中間コードを生成します。

  if (LOWtime < dottime){//基準時間(dottime)より短ければ
  data=0;//dot
  Ltime=LOWtime;//短点の時間を記憶
  }else{
  data=1;//dash
  }
bitcount++;//入力されたビット数をカウント
Mcode=Mcode<<1;//Mcodeを左に1bitシフト
Mcode=Mcode | data;//McodeとdataのORをとる
}

短点時間の2倍(2*Ltime)程度信号がなければ、
中間コードにしたモールス符号を、swich case文で、アスキーコードに変換します。
短点時間の7倍(7*Ltime)程度信号がなければ、1個だけスペースを表示します。
基準時間の何倍で、変換するかまたは、スペースを入れるかは、実際の運用で調整する必要がありそうです。

void decode(){
  switch(Mcode){
   case   B00000101:
   printascii(65);//"A"
   break;
   case B00011000:
   printascii(66);//"B"
   break;

   省略

   case B00110001:
   printascii(91);//"["
   printascii(66);//"B"
   printascii(84);//"T"
   printascii(93);//"]"
   break;
   case B01100111://"ホレ"
   wabun=true;
   printascii(60);//"<"
   break;
   default:
   printascii(42);//"*"
  }
}
 

和文に対応するため、欧文受信中に[ホレ]を受信したら、和文フラッグ(boolean wabun)をtrueとします。
和文フラッグがtrueの時、decodewabun()ルーチンで和文コードに対応した文字を表示します。
[ラタ]を受信したら、欧文モードに戻ります。また、和文中に"("を受信したら欧文に")"を受信したら和文に切り替えます。

 void decodewabun(){
  switch(Mcode){
   case B00010111:
   printascii(166);//"ヲ"
   break;
   case B00101101:
   printascii(176);//"-"
   break;
   case B00111011:
   printascii(177);//"ア"
   break;
   case B00000101:
   printascii(178);//"イ"

     省略

   case B00100010://"ラタ"
   wabun=false;
   printascii(62);//">"
   break;
   case B01101101:
   wabun=false;
   printascii(40);//"("
   break;
   case B01010010:
   wabun=true;
   printascii(41);//")"
   break;
   default:
   printascii(42);//"*"
  }
}

LCDへの表示ルーチンprintascii(asciinumber)のスケッチは、OZ1JHM局のCWデコーダのスケッチを使わせていただきました。(TKS FER OZ1JHM)

今のところ、エレキーを接続するとうまくデコードできました。実際の交信をデコードするとノイズの問題や、
トーンデコーダ(このプログラムには含まれません)の性能などにより、なかなかデコードが難しいこともあると思います。
Arduinoのプログラミング練習として取り組みましたので、今後改良していきたいと思います。
また、皆さんが自分で作成したCWデコーダを公開していただければ、切磋琢磨してより良いCWデコーダができると思っています。
稚拙なスケッチですが、最後に掲載しておきます。

Arduino CW decoderのスケッチです。(テキストファイル)

inserted by FC2 system