Arduinoで作っちゃいました ~ CW練習機(パート3) ~

2025年3月9日日曜日

t f B! P L

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個送出
     [toneOnにして短点(長点)の時間だけdelay()、その後toneOffにしてブランク(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/DashKeyOnになっているかを読みとって、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.    今回のまとめ

今回はエレキーの基本機能を作成しました。
次回は、速度変更などを加え、またエレキーの使用感を高めるブラッシュアップをしてみます。

 


このブログを検索

ブログ アーカイブ

CW Decoderの製作講習会を開催しました

 先日、「マイコンで作る 本格的CW デコーダ」を掲載しましたが、これを、船橋市アマチュア無線クラブ(FARC: JJ1YNA)で発表したところ、大画面化したものが欲しいとのご要望をいただきました。 そこで、OLEDをタッチパネル付きのTFT液晶に変更して大画面化、操作性を改善し...

QooQ