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のスケッチです。(テキストファイル)