このサイトはMacを使って Arduino Uno の動作や活用法を学びます。

27 Arduino モールス通信キーヤーを作成 2 EEPROM

この記事では、モールス通信をするときに使用するエレクトリック・キーヤーを作成します。前回の記事で作成した回路に押しボタン2個を追加し送信速度設定ができるように変更します。

送信速度は、PARIS方式で計測した1分間に送信する字数で定め、押しボタンを1回押すごとに10文字分の速度を増減できます。

今回使用する部品は、前回までの圧電スピーカーとパドルキーと、今回追加したSW2個で、以下のピンに接続しています。

PARIS方式

モールス通信の符号は、文字により符号の長さが大きく異なるため、単に通信速度に毎分何文字と言っても、通信文内容に出現する文字の種類のよりその全体速度が大きく左右されてしまします。そこで、速度を規定するため「PARIS」という単語を送信する時の速度を標準として規程した符号速度のことです。

「PARIS」を送信すると、50短点の送信時間になるので、一文字10短点時間とも考えられます。

例えば、60字/分は、1字/秒、10短点時間/秒 なので、短点の時間は、100msになります。

EEPROMに記録

自分の好みの通信速度を一度設定したら、次に使用する時もその速度で通信をしたいものです。しかし、変数としてRAMエリアに書き込むのでは電源を切るとその値も消えてしまします。そこで、電源を落としても記録内容の消えないEEPROMエリアに送信速度を保存します。使用するArduino関数は以下の二つになります。

送信速度を 180 - 20(字/分)の範囲で、 10字/分ステップで設定します。この値をEEPROMの1番地に書き込みます。

電源ONでEEPrOMを読み込み、短点の時間に変換してスケッチで使用します。

押しボタンを押して速度を変更したらすぐにEEPROMの1番地に上書きします。

プログラムの流れ

setup関数内でEEPROMからデーターを読み込む関数 ckEEPROMdata( ) を実行します。

loop関数内では、送信速度を設定するSWが押されたか確認し、UPキーが押されればcgSpeedUp関数を実行、DOWNキーが押されれば cgSpeedDOWN関数を実行し、速度を10字/分ステップで増減します。

 

スケッチの内容

前回のスケッチに送信速度変更部分を追加しただけで、主たるプログラムフローの変更はありません。

 

// Electoric keyer
// SWで送信速度変更
// 2021-6-25

#include <EEPROM.h>

int keySpeed = 125;   // 短点の時間 ms
int frequency = 700;  // サイドトーン周波数

int KEY_DOT  = 2;     // pin 2 パドルのDot接点
int KEY_DASH = 3;     // pin 3 パドルのDash接点
int SW_UP    = 6;     // pin 6 Up SW
int SW_DOWN  = 7;     // pin 7 Down SW
int PIN_SPK  = 9;     // pin 9 圧電スピーカー
int PIN_LED1 = 13;    // ボード内蔵 LED 使用
boolean flagDot  = 0; // Dotが押された
boolean flagDash = 0; // Dashが押された
unsigned long tUp;    // 完了時間

void setup() {
    pinMode(KEY_DOT,  INPUT_PULLUP);
    pinMode(KEY_DASH, INPUT_PULLUP);
    pinMode(SW_UP,    INPUT_PULLUP);
    pinMode(SW_DOWN,  INPUT_PULLUP);
    pinMode(PIN_LED1, OUTPUT);
    ckEEPROMdata();    // EEPROMデータ取得
}

void loop() {
  // 短点が押されてたなら、sendDot()を実行
  if(! digitalRead(KEY_DOT))  flagDot = 1;
  if(flagDot)sendDot();
  // 長点が押されたなら、sendDash()を実行
  if(! digitalRead(KEY_DASH)) flagDash = 1;
  if(flagDash)sendDash();
  // 送信速度の変更
  if(! digitalRead(SW_UP))   cgSpeedUp();
  if(! digitalRead(SW_DOWN)) cgSpeedDown();
}

// keySpeedデータの有効性確認と短点単位時間への変換
// 1番地;送信速度(文字/分)
// 文字/分で記録、6000/(ch/min)で単位時間に変換
void ckEEPROMdata(){
  boolean notValid = 0;
  keySpeed = EEPROM.read(1);
  if((keySpeed % 10)!=0) notValid = 1;
  if(keySpeed > 180) notValid = 1;
  if(keySpeed <  20) notValid = 1;
  // 無効なあらデフォルト値をセット
  if(notValid){                   // EEPROMデータが無効なら
    keySpeed  = 60;               // デフォルト値に変更
    EEPROM.write(1, keySpeed);    // EEPROMに上書き
    delay(5);                     // 書き込み時間の確保
  }
  keySpeed  = 6000/keySpeed;      // 単位時間に変換
}

void cgSpeedUp(){
  while(! digitalRead(SW_UP));  // SWが離れるのを待つ
  int data = EEPROM.read(1);    // EEPROMの値を読み込む
  if(data >= 180){              // 上限なら
    beep();beep();beep();       //   beep音を3回
  }else{                        // 変更可能なら
    data += 10;                 //   10増加
    EEPROM.write(1, data);      // EEPROMに書き込む
    beep();                     //   beep音を1回
    keySpeed  = 6000/data;      // 短点時間に変更
  }
}

void cgSpeedDown(){
  while(! digitalRead(SW_DOWN));  // SWが離れるのを待つ
  int data = EEPROM.read(1);      // EEPROMの値を読み込む
  if(data <= 20){                 // 下限なら
    beep();beep();beep();         //   beep音を3回
  }else{                          // 変更可能なら
    data -= 10;                   //   10減少
    EEPROM.write(1, data);        // EEPROMに書き込む
    beep();                       //   beep音を1回
    keySpeed  = 6000/data;        // 短点時間に変更
  }
}

// dot信号を送る
void sendDot(){
    flagDot = 0;                // 端点フラグをクリア
    digitalWrite(PIN_LED1, 1);  // LED ON
    tone(PIN_SPK,frequency);    // サイドトーン ON
    tUp = millis() + keySpeed;  // Mark終了時間セット
    while(tUp > millis()){      // Mark終了時間まで待つ
      // 長点が押されたなら、長点フラグをセット
      if(! digitalRead(KEY_DASH)) flagDash = 1;
    }
    digitalWrite(PIN_LED1, 0);  // LED OFF
    noTone(PIN_SPK);            // サイドトーン OFF
    tUp = millis() + keySpeed;  // コード終了時間セット
    while(tUp > millis()){      // コード終了を待つ
      // 長点が押されたなら、長点フラグをセット
      if(! digitalRead(KEY_DASH)) flagDash = 1;
    }
}

// Dash信号を送る
void sendDash(){
    flagDash = 0;
    digitalWrite(PIN_LED1, 1);
    tone(PIN_SPK,frequency);
    tUp = millis() + (keySpeed * 3);
    while(tUp > millis()){
      if(! digitalRead(KEY_DOT)) flagDot = 1;
    }
    digitalWrite(PIN_LED1, 0);
    noTone(PIN_SPK);
    tUp = millis() + keySpeed;
    while(tUp > millis()){
      if(! digitalRead(KEY_DOT)) flagDot = 1;
    }
}

// Beep音を鳴らす ON 100ms - OFF 50ms
void beep(){
    tone(PIN_SPK,1000,100);
    delay(150);
}

 

動作の確認

スケッチを Arduino に書き込みプログラムがスタートしたら、接続したパドルを叩いて下ださい。ボード上の「L」LEDが点灯し、LEDに同期してサイドトーンが圧電スピーカーから聞こえます。押しボタンを押すと(正確には離した時)Beep音が1回鳴り送信速度が変更されます。パドルを叩いて確認してください。

 


 

次回は、使いやすくするために、EEPROMを使いサイドトーン周波数の設定も変更記録する方法の記事を予定します。