Arduinoで作っちゃいました ~ CW練習機(パート3) ~
今回から2回に分けてエレキーの機能を追加した過程を説明します。今回はエレキーの1回目基本機能の作成です。
1.
全体の構成
まず、エレキーのパドルと、エレキーの送出速度(WPM)を変更するボタン2個を追加します。ソフト的にはボタン(接点)が4個追加となる形です。
2.
要求仕様とプログラム構成の検討
目標とするエレキーの性能は、私が使用するIC-705の内蔵エレキーと同等の操作感の実現です。また同時に、電鍵と同じように、エレキーのCW符号の読み取りと表示も実行させます。
以下使用する用語として、短点(Dot)、長点(Dash)、短点や長点の間の時間をブランク(Blank)、文字と文字の間をスペース(Space)とし、次の入力が来るのを待っている状態を待ち(IDLE)として進めます。
一番簡単なプログラムの構成は、電鍵と同様に、CW_Readerの中で
1) getElekeyStatus()を繰り返し呼びながら、パドルのOn/Offを監視して、
2) パドルがOnであれば(Onが続けば)、短点(または長点)とブランク(blank)を1個送出
[toneをOnにして短点(長点)の時間だけdelay()、その後toneをOffにしてブランク(blank)の時間だけdelay()する]
3) 送出が終わったら、短点・長点のデータを作成し、また文字区切りを判定。その処理中に各設定ボタンのOn/Offチェック(とその処理)も実行
4) 1文字分のデータを文字判定処理
となります。
前回のプログラムに2)の短点/長点送出部分が追加になりましたが、この2)の処理にはdelay()が2回も使われています。マイコンはここで時間が経つのをずっと待っているので、この間は別の処理が全くできません。(マイコンの処理能力を浪費しています。) そのため、この部分をループ化します。
ループ化したプログラム構成
CW_Reader()[親側のプログラム]は、CW符号の読み取りのため、getElekeyStatus()を繰り返し呼びだして接点のOn/Offを確認します。
getElekeyStatus()では、
1)
エレキーのパドルの接点の状態データを更新(チャタリング処理)
(ただし、エレキーではこれがそのままキーのOn/Offとはなりません)
2)
Dot/Dash信号を「送出中」であれば、Onを返す。
3)
ブランクを「送出中」であれば、Offを返す。
4)
Dot/Dashを送出し終わった場合は、ブランクを「送出を開始」してOffを返す。
5)
ブランクを送出し終わった場合は、DotKey/DashKeyがOnになっているかを読みとって、Onであれば「送出を開始」してOnを返す。
6)
いずれもOffであれば、待ち(IDLE)としてOffを返す。
となります。
信号(短点・長点およびブランク)を「送出中」であるか否かは、現在時刻(ミリ秒)をmillis()で取得して、信号の開始時刻(start_time)から信号の長さ分の時間が経過しているか、いないかを判断します。
[フローチャートで書くとこうなります]

3.
プログラム
上のフローチャートをそのままプログラムに落とし込んだだけの内容です。
(check_dotKey_status()は前回のボタン処理と同じ内容です)
エレキーの部分は、EleKey.inoとして別ファイルとしました。
/*******************************
* パート3 エレキーの機能 *
*******************************/
/// ハードウェアの接続定義 ///
#define DOT_PIN 3 // Paddle
#define DASH_PIN 2
#define BTN3_PIN 11 // ボタン3
#define BTN4_PIN 10 // ボタン4
#define SPK_PIN 8 // スピーカー
#define Off 0
#define On 1
// KEYやボタンの状態変化 //
#define BtnOnEdge 1
#define BtnOffEdge 2
#define NoChange 0
#define IDLE 0
#define DOT 1
#define DASH 2
#define BLANK 3
int eleKeySt = IDLE ;
unsigned long start_time = 0 ; // 時間監視用
unsigned long duration = 0 ; // 送出時間 (ミリ秒)
// WPMと送出時間(msec)
int WPM = 10 ;
int dot_length = 120 ;
int dash_length = 360 ;
int blank_length = 120 ;
//
extern int dotKeyStatus, dashKeyStatus ; // 後方参照int getElekeyStatus() {
// パドルの状態を更新 (チャタリング処理)
check_dotKey_status(); // 状態の更新だけ
check_dashKey_status(); // 状態の更新だけ
// 信号送出中か?
if ((eleKeySt == DOT)||(eleKeySt == DASH)) { // 信号送出中
if (millis()-start_time <= duration) return (On); // 信号送出の時間が経過していない
}
if (eleKeySt == BLANK) { // ブランク送出中
if (millis()-start_time <= duration) return (Off); // 信号送出の時間が経過していない
}
// IDLE状態または信号送出が完了した場合
// 送出完了したのが、dotかdashの場合はBlankを送出する
if ((eleKeySt == DOT) || (eleKeySt == DASH)) {
eleKeySt = BLANK ;
duration = blank_length ;
start_time = millis() ;
noTone(SPK_PIN) ;
return (Off) ;
}
// 送出し終わったのがBlank
if(eleKeySt == BLANK) {
eleKeySt = IDLE ;
}
// 次に送出する符号
if (dotKeyStatus == On) { // dotKey On
eleKeySt = DOT ;
tone(SPK_PIN, Pitch); // 音を出す
digitalWrite(LED_BUILTIN, LOW); // LED On (追加)
duration = dot_length ;
start_time = millis() ;
return (On) ;
}
if (dashKeyStatus == On) { // Key On Edge
eleKeySt = DASH ;
tone(SPK_PIN, Pitch); // 音を出す
digitalWrite(LED_BUILTIN, LOW); // LED On (追加)
duration = dash_length ;
start_time = millis() ;
return (On) ;
}
// IDLE中
return(Off) ; // IDLE中
}
4.
今回のまとめ
今回はエレキーの基本機能を作成しました。
次回は、速度変更などを加え、またエレキーの使用感を高めるブラッシュアップをしてみます。
0 件のコメント:
コメントを投稿