エレキーを使用すると簡単にきれいなモールス信号を送信することができます。左右に接点のあるパドルキーに、モールス符号を組み立てるキーヤーと呼ばれる電子回路を接続しますが、最近は無線機にこのキーヤーが組み込まれているケースが多いようです。このためか、単体のキーヤーは意外と高価です。動作は単純なのでPICで作成しましたした。
Curiosityに、パドルを接続します。モールス符号の送信速度は、Curiosityボード付属のVRで調整し、短点の長さを 60ms-187ms の範囲で調整が可能です。
CW(モールス)信号は、ボードのLEDで確認すると共に、PWM出力された正弦波のToneとしても出力されています。ここでは、RCでローパスフィルタを構成すると共に出力を落として、AMP付きのスピーカーを利用して聞いています。
1 使用部品
パドル電鍵
CQオーム社から購入した、パドル業界で最も売れ続けているモデルの CW-ONE を接続しました。外部からの雑音による誤動作防止のため、0.1uF のコンデンサーを取り付けています。効果の程は不明ですが現在は不安定な動作はありません。もし、強力なEMI対策が必要になった場合は、ソフトウエアの対策を施そうと考えています。
ポータブルスピーカー SP-A35M
JVC社のアンプ内蔵スピーカーを使っています。信号は小さなユニバーサルボードに組んだRCフィルターを通しています。
RCフィルター
RCでローパスフィルタを構成すると共に出力を落として、AMP付きのスピーカーに接続します。ユニバーサルボードを小さく切り、R、C、3.5mmステレオ用コネクタを半田付けしました。
2 プログラム概要
このプログラムでは以下の周辺モジュールを使用しています。
- ADC
- Curiosityボード付属のVRからの電圧をAD変換します。変換結果は左詰めとし、上位8ビットのみを使用して、60 - 187の値に変換します。
- TMR2
- PWM3と共に機能し、サイドトーンのベースとなります。Fosc/4 (8MHz)を 1/100 し、80kHz のPWM周期で、その5回に一度(16kHz)、波形データを更新します。
- PWM3
- 波形データは、正弦波を20分割した値を使用するので、出力波形は、800Hz (16kHz/20)です。
PushSWを押すと、TMR2 postscaler が、1:5 -> 1:6 -> 1:4 -> 1:5 と変化するので、出力される周波数数も、666、800、1000Hzから選ぶことができます。
3 MPLAB X プロジェクトの作成
この例では、「New Project...」から、Elekey という名称のプロジェクトを作成しました。
- Device: PIC16F1619
- MPLAB X; v5.45
- MPLAB XC8; v2.20
- MCC; v3.95.0
4 システムクロックの設定
MCCの設定から8MHz_HF を選択し、PLL Enabled にレ点を付けます。
Current System Clock が、32 MHz になることを確認します。
5 ADC Module のロード
Device Resources ウインド内の Libraries list にある ADC icon を展開して現れる ADC icon をダブルクリックします。
モジュールがロードされるとADC設定画面が現れます。
6 ADC の設定
表示される画面を見ながら、マウスでクリックして設定します。Clock Source は Fosc/32 を選択します。それ以外はデフォルトでOKでした。Result Alignment は left となっていることを確認します。
7 TMR2 の設定
Device Resources ウインド内の Libraries list にある Timer icon を展開して TMR2 icon をダブルクリックします。モジュールがロードされるとTMR2設定画面が現れます。
表示される画面を見ながら、マウスでクリックして設定します。下記の4項目以外はデフォルトでOKでした。
- Clock Source は Fosc/4 を選択
- Postscaler は 1:5
- Timer Period は 62.5us を入力
- Enable Timer Interrupt に レ点を入れる
参考:Postscaler を 1:4 に設定すると、正弦波周波数を 1kHz に変更することができます。
8 PWM3 の設定
Device Resources ウインド内の Libraries list にある PWM icon を展開して PWM3 icon をダブルクリックします。モジュールがロードされると PWM3 設定画面が現れます。
Duty Cycle を 100% に変更します。
PWM Polarityは、active_lo にします。
画面で連携タイマーがにTimer2 が選択されていて、PWM Frequency が 80KHz と表示されいるのを確認します。
9 入出力の指定
各module がロードされると、Pin Manager に、利用できる 入出力pinが表示されます。
- ADC ANx : RC0
- PWM3OUT : RC5
- GPIO input : RA4
- GPIO input : RC2
- GPIO input : RC4
- GPIO output : RA1
- GPIO output : RA2
- GPIO output : RA5
Pin Module画面で、RA4 RC2 のWPU(弱プルアップ)にレ点を入れます。
さらに、Registersタブをクリックし OPTION_REG の nWPUEN を enabled に変更します。
10 Code 生成
Generate ボタンをクリックします。
11 処理ルーチンを main.c に記載
自動生成された main.c ファイルを開き、内容を下のリストの様に全面変更します。
なお、MPLAB X プロジェクトを下のリンクからダウンロードですることができます。また、プロジェクトをコンパイルした HEXファイル(Elekey.hex)も同梱しました。その HEXファイルを MPLAB IPE を使用しCuriosityボードに書き込んでも良いでしょう。
---> Elekey.X.zip
#include "mcc_generated_files/mcc.h" #define keyDASH !RA4 #define keyDOT !RC2 #define lenSp lenDOT #define CWout LATA5 // Sin定数 20分割 MAX 99 uint8_t wave[] = { 97,90,79,65,50,34,20,9,2,0,2,9,20,34,50,65,79,90,97,99 }; /* ++++++++ 共通変数 ++++++++ */ uint8_t p_wave; int lenDOT = 100; bool flagDASH = false; bool flagDOT = false; /* ++++++++ プロトタイプ ++++++++ */ void SigDOT(void); void delayDOT (int); void SigDASH(void); void delayDASH (int); void changeFreq(void); void MyTMR_ISR(void); // 割り込み処理関数プロトタイプ /* Main application */ void main(void) { SYSTEM_Initialize(); ADCON0bits.CHS = 4; // ADチャンネル設定 __delay_ms(5); // ADチャージ時間 GO = 1; // AD変換開始 while(GO); // AD変換終了待ち lenDOT = (ADRESH / 2) + 60; // AD変換値を端点時間にセット TMR2_SetInterruptHandler(MyTMR_ISR); // 割り込み処理関数設定 INTERRUPT_GlobalInterruptEnable(); INTERRUPT_PeripheralInterruptEnable(); while (1) { if(flagDOT || keyDOT) SigDOT(); // 短点が押下なら短点処理 if(flagDASH || keyDASH) SigDASH(); // 長点が押下なら長点処理 if(!RC4) changeFreq(); // SWが押下で Side Tone変更 } } //++++++++++++++++++++++++++++++++++++++++++++++ // 短点とマーク間スペースを送信 // この間、長点キーを繰り返しチェックし押されれば記憶する // スペース開始前にVRのAD変換を開始し // スペース終了後に変換値を送信速度に変換し保存 //++++++++++++++++++++++++++++++++++++++++++++++ void SigDOT(void){ CWout = 1; // CW出力 On delayDOT(lenDOT); // 文字間スペース開始 CWout = 0; // CW出力 Off ADCON0bits.GO=1; // AD変換開始 delayDOT(lenSp); // 文字間スペース開始 lenDOT = (ADRESH / 2) + 60; // AD変換値を端点時間にセット if(!keyDOT)flagDOT = false; // 短点Keyが離れれば、フラグクリア } void delayDOT(int len){ while(len--){ // 指定の長さだけ繰り返す __delay_ms(1); // 1ms 待ち if(keyDASH) flagDASH = true; // 長点が押されれば記憶 } } //++++++++++++++++++++++++++++++++++++++++++++++ // 長点とマーク間スペースを送信 // 長点時間は短点の3倍 //++++++++++++++++++++++++++++++++++++++++++++++ void SigDASH(void){ CWout = 1; // CW出力 On delayDASH(lenDOT * 3); // 長点の長さだけ遅延 CWout = 0; // CW出力 Off ADCON0bits.GO=1; // AD変換開始 delayDASH(lenSp); // 文字間の長さだけ遅延 lenDOT = (ADRESH / 2) + 60; // AD変換値を端点時間にセット if(!keyDASH)flagDASH = false; // 長点Keyが離れれば、フラグクリア } void delayDASH(int len){ while(len--){ // 指定の長さだけ繰り返す __delay_ms(1); // 1ms 待ち if(keyDOT) flagDOT = true; // 短点が押されれば記憶 } } // サイドトーンの周波数を変更する void changeFreq(void){ switch(T2CON){ case 0x84: T2CON = 0x85; break; // 666Hz case 0x85: T2CON = 0x83; break; // 1 kHz default: T2CON = 0x84; break; // 800Hz } LATA5 = 1; // LED を点灯し音を出す while(!RC4); // SW が離れるのを待つ LATA5 = 0; // LED を消灯 } // 割り込み処理関数設定 --------------------------- void MyTMR_ISR(void){ PWM3DCH = wave[p_wave]; // 波形定数を更新 if(p_wave >= 19){ // 零点なら if(CWout) p_wave = 0; // CWout ON で継続 }else{ // 零点以外なら p_wave ++; // 波形定数を進める } } /** End of File **/
12 プロジェクトのコンパイルと書き込み
Program アイコンをクリックし、PICにプログラムを書き込みます。
13 動作の確認
書き込み終了後に、電鍵・RCフィルター・スピーカーを接続します。
Curiosityボード付属のVRで調整し、端点の長さで、60ms-187ms の範囲で調整が可能です。
電鍵のキーを押すとサイドトーンが聞こえ、ボードのLEDが点灯します。
PushSWを押すと、トーン周波数数を、666、800、1000Hzから選ぶことができます。