この1週間ほどArduino CW練習機(モールス符号練習機)のプログラミングをしていました。
HSPやIchigoJamで既にプログラミングした経験があり、簡単にできると思ったのですが、除雪作業の疲れもあり、あまりはかどりませんでした。一応できましたので、公開します。
まず、モールス符号をどのようにして発生させるかです。
モールス符号は、短点(トン、dot)と長点(ツー、dash)から構成され、長点は、短点の3倍の長さ、長点または短点間の間隔は、短点と同じ時間、文字と文字の間は短点の3倍の長さ、語と語の間は短点の7倍の長さと決められています。(A1クラブのHP参照)
Arduinoでは、音を出す関数 tone(pin,frequency,duration)がありますので、これを使います。圧電スピーカーを使えば、ちょうど良い音量で聞くことができます。また、時間を待つ関数は、delay()を使います。
モールス符号の送出速度は、10kΩボリュームの電圧で調整します。(およそ30文字/分~300文字/分の間で調整できます)
配線図です。
実査の配線です。
ABC順、A-Zランダム、A-9ランダムの3つのモードが選べます。ランダムのときは、頭にHR HR BTを送出します。
シリアルモニタの画面です。
ABC順でまず、モールス符号を何度も聞いて覚えましょう。
覚えたら、次はA-Zランダムモードで、アルファベットを確実に覚えましょう。
さらに、0-9の数字を加えたモードで練習をすれば、これでほぼ交信できますが、実際には/ ? , . なども覚える必要があります。
最後に、スケッチです。まだ改良の余地がありますので、まだVERは0.5です。
どうぞ、勝手に改良してお使いください。
----------------------------------------------------------------------------------
/*
CW Trainer Ver0.5
2016.1.22
JH7UBC Keiji Hata
*/
#define SP_PIN 2//圧電スピーカーを接続するピン
#define freq 800//トーン(Hz)
CW Trainer Ver0.5
2016.1.22
JH7UBC Keiji Hata
*/
#define SP_PIN 2//圧電スピーカーを接続するピン
#define freq 800//トーン(Hz)
char moji[37] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//各文字に対するモールスコード(短点0、長点1、ストップビット1 例 A=00000110=6)
byte mcode[36] = {6,17,21,9,2,20,11,16,4,30,13,18,7,5,15,22,27,10,8,3,12,24,14,25,29,19,31,63,60,56,48,32,33,35,39,47};
//各文字に対するモールスコード(短点0、長点1、ストップビット1 例 A=00000110=6)
byte mcode[36] = {6,17,21,9,2,20,11,16,4,30,13,18,7,5,15,22,27,10,8,3,12,24,14,25,29,19,31,63,60,56,48,32,33,35,39,47};
int m = 0; //文字のコード
int y = 0; //モールス符号送出時のビット0の値
int val = 0;//入力した値
int n; //文字数
int interval1;
int interval2;
int y = 0; //モールス符号送出時のビット0の値
int val = 0;//入力した値
int n; //文字数
int interval1;
int interval2;
void setup(){
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println ("***** CW Trainer *****");
}
Serial.begin(9600);
randomSeed(analogRead(0));
Serial.println ("***** CW Trainer *****");
}
void loop(){
Serial.println("");//改行
Serial.println("1:ABC..0..9 2:A-Z(RANDOM) 3:A-Z0-9(RANDOM)");
Serial.println("Input number (1-3)");
input();//入力待ち
switch (val){
case 49://"1"の時の処理
for (int i=0; i<=35; i++){
Serial.print(moji[i]);
Serial.print(" ");
m = mcode[i];
morseTone();
delay(interval1);
}
break;
case 50://"2"の時の処理
HRBT();
n=26;
rndChar();
break;
Serial.println("");//改行
Serial.println("1:ABC..0..9 2:A-Z(RANDOM) 3:A-Z0-9(RANDOM)");
Serial.println("Input number (1-3)");
input();//入力待ち
switch (val){
case 49://"1"の時の処理
for (int i=0; i<=35; i++){
Serial.print(moji[i]);
Serial.print(" ");
m = mcode[i];
morseTone();
delay(interval1);
}
break;
case 50://"2"の時の処理
HRBT();
n=26;
rndChar();
break;
case 51://"3"の時の処理
HRBT();
n=36;
rndChar();
break;
}
}
HRBT();
n=36;
rndChar();
break;
}
}
void HRBT(){ // HR HR BTの送出
HR();
HR();
Serial.print("BT");
m=49;
morseTone();
delay(interval2);
Serial.println("");
}
HR();
HR();
Serial.print("BT");
m=49;
morseTone();
delay(interval2);
Serial.println("");
}
void HR(){
Serial.print("HR ");
m=16;
morseTone();
delay(interval1);
m=10;
morseTone();
delay(interval1);
}
Serial.print("HR ");
m=16;
morseTone();
delay(interval1);
m=10;
morseTone();
delay(interval1);
}
void rndChar(){ //100文字をランダムに送出する
int count=0;//カウンタクリア
while (count < 100){
int x = random(n);
Serial.print(moji[x]);
Serial.print(" ");
m = mcode[x];
morseTone();
delay(interval1);
if (( (count+1) % 10) ==0){ //10文字ごとに改行する
Serial.println("");//改行
}
count++;
}
}
int count=0;//カウンタクリア
while (count < 100){
int x = random(n);
Serial.print(moji[x]);
Serial.print(" ");
m = mcode[x];
morseTone();
delay(interval1);
if (( (count+1) % 10) ==0){ //10文字ごとに改行する
Serial.println("");//改行
}
count++;
}
}
void morseTone(){ //モールス符号を送出する
int dottime = analogRead(1) / 5;
int dashtime = dottime * 3;
interval1 = dottime * 2;
interval2 = dottime * 4;
while (m != 1){
y = m & 1;
if (y == 0){
tone(SP_PIN,freq,dottime);
delay(interval1);
}else{
tone(SP_PIN,freq,dashtime);
delay(interval2);
}
m = m >> 1;//1bit 右にシフト
}
}
int dottime = analogRead(1) / 5;
int dashtime = dottime * 3;
interval1 = dottime * 2;
interval2 = dottime * 4;
while (m != 1){
y = m & 1;
if (y == 0){
tone(SP_PIN,freq,dottime);
delay(interval1);
}else{
tone(SP_PIN,freq,dashtime);
delay(interval2);
}
m = m >> 1;//1bit 右にシフト
}
}
void input(){ //1文字入力
while ( Serial.available() == 0 ){ //入力があるまで待つ
}
val = Serial.read();
}
while ( Serial.available() == 0 ){ //入力があるまで待つ
}
val = Serial.read();
}