27 Arduino モールス通信キーヤーを作成 2 EEPROM
この記事では、モールス通信をするときに使用するエレクトリック・キーヤーを作成します。前回の記事で作成した回路に押しボタン2個を追加し送信速度設定ができるように変更します。
送信速度は、PARIS方式で計測した1分間に送信する字数で定め、押しボタンを1回押すごとに10文字分の速度を増減できます。
今回使用する部品は、前回までの圧電スピーカーとパドルキーと、今回追加したSW2個で、以下のピンに接続しています。
- pin 2 -> パドルのDot接点
- pin 3 -> パドルのDash接点
- pin 6 -> SW UP
- pin 7 -> SW DOWN
- pin 9 -> 圧電スピーカー
PARIS方式
モールス通信の符号は、文字により符号の長さが大きく異なるため、単に通信速度に毎分何文字と言っても、通信文内容に出現する文字の種類のよりその全体速度が大きく左右されてしまします。そこで、速度を規定するため「PARIS」という単語を送信する時の速度を標準として規程した符号速度のことです。
「PARIS」を送信すると、50短点の送信時間になるので、一文字10短点時間とも考えられます。
例えば、60字/分は、1字/秒、10短点時間/秒 なので、短点の時間は、100msになります。
EEPROMに記録
自分の好みの通信速度を一度設定したら、次に使用する時もその速度で通信をしたいものです。しかし、変数としてRAMエリアに書き込むのでは電源を切るとその値も消えてしまします。そこで、電源を落としても記録内容の消えないEEPROMエリアに送信速度を保存します。使用するArduino関数は以下の二つになります。
- EEPROM.read(address)
EEPROMの指定したアドレスから1バイト読み込みます。 - EEPROM.write(address, value)
EEPROMのaddress位置に1バイトのvalue値(0から255)を書き込みます。
EEPROMへの書き込みには3.3ミリ秒かかります。
送信速度を 180 - 20(字/分)の範囲で、 10字/分ステップで設定します。この値をEEPROMの1番地に書き込みます。
電源ONでEEPrOMを読み込み、短点の時間に変換してスケッチで使用します。
押しボタンを押して速度を変更したらすぐにEEPROMの1番地に上書きします。
プログラムの流れ
setup関数内でEEPROMからデーターを読み込む関数 ckEEPROMdata( ) を実行します。
loop関数内では、送信速度を設定するSWが押されたか確認し、UPキーが押されればcgSpeedUp関数を実行、DOWNキーが押されれば cgSpeedDOWN関数を実行し、速度を10字/分ステップで増減します。
- ckEEPROMdata関数
EEPROMアドレスを読み取り保存されているデータの有効性判断をします。
確認項目は、値が変更可能範囲内か? 一の位がゼロか?
もし、無効ならEEPROMデータをデフォルト値に置き換えます。
有効が確認されたなら、文字/分を短点の時間に変換します。 - cgSpeedUp関数
UpSWが離れるのを待って、EEPROM値を読み込みその値を確認します。
もし、上限に達していれば、Beep音を3回鳴らし復帰します。
変更可能なら、送信速度(文字/分)を10文字増やしEEPROMに上書きします。
更新した文字/分を短点の時間に変換します。 - cgSpeedDOWN関数
DownSWが離れるのを待って、EEPROM値を読み込みその値を確認します。
もし、下限に達していれば、Beep音を3回鳴らし復帰します。
変更可能なら、送信速度(文字/分)を10文字減らしEEPROMに上書きします。
更新した文字/分を短点の時間に変換します。す。
スケッチの内容
前回のスケッチに送信速度変更部分を追加しただけで、主たるプログラムフローの変更はありません。
// 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を使いサイドトーン周波数の設定も変更記録する方法の記事を予定します。