【エレキー】
インターネットではIambic Keyerで調べると、色々検索できた。
Iambic keyer with Arduino
Arduino CW keyer
Arduino Iambic Keyer
このなかで3.Arduino CW keyerを利用することにした。現在のマイコンボードではポートの数の関係でメモリーを持つことや、速度調節の機能を持たすことはできない。シンプルなキーヤーがとりあえず必要だ。DDSをコントロールして7MHzのトランシーバーを完成させて、それから機能を拡張していきたい。
【Sketch】
// Iambic Morse Code Keyer Sketch
// Copyright (c) 2009 Steven T. Elliott
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details:
//
// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
// Boston, MA 02111-1307 USA
//
// http://openqrp.org/?p=343
//
// "Trimmed" by Bill Bishop - wrb[at]wrbishop.com
//
///////////////////////////////////////////////////////////////////////////////
//
// openQRP CPU Pin Definitions
//
///////////////////////////////////////////////////////////////////////////////
//
// Digital Pins
//
int buzzerPin = 10; // Tone output pin
int LeftPin = 0; // Left paddle input
int RightPin = 1; // Right paddle input
int ledPin = 13; //
//
////////////////////////////////////////////////////////////////////////////////
//
// keyerControl bit definitions
//
#define DIT_L 0x01 // Dit latch
#define DAH_L 0x02 // Dah latch
#define DIT_PROC 0x04 // Dit is being processed
#define PDLSWAP 0x08 // 0 for normal, 1 for swap
#define IAMBICB 0x00 // 0 for Iambic A, 1 for Iambic B
//
////////////////////////////////////////////////////////////////////////////////
// Global Variables
//
unsigned long ditTime; // No. milliseconds per dit
unsigned char keyerControl;
unsigned char keyerState;
#define NOTE_D5 587 // "pitch.h" at http://arduino.cc/en/Tutorial/Tone
///////////////////////////////////////////////////////////////////////////////
//
// State Machine Defines
enum KSTYPE {IDLE, CHK_DIT, CHK_DAH, KEYED_PREP, KEYED, INTER_ELEMENT };
///////////////////////////////////////////////////////////////////////////////
//
// System Initialization
//
///////////////////////////////////////////////////////////////////////////////
void setup() {
// Setup outputs
pinMode(ledPin, OUTPUT); // sets the digital pin as output
// Setup control input pins
pinMode(LeftPin, INPUT); // sets Left Paddle digital pin as input
pinMode(RightPin, INPUT); // sets Right Paddle digital pin as input
digitalWrite(ledPin, LOW); // turn the LED off
keyerState = IDLE;
keyerControl = IAMBICB; // Or 0 for IAMBICA
loadWPM(15); // Fix speed at 15 WPM
}
///////////////////////////////////////////////////////////////////////////////
//
// Main Work Loop
//
///////////////////////////////////////////////////////////////////////////////
void loop()
{
static long ktimer;
int debounce;
// Basic Iambic Keyer
// keyerControl contains processing flags and keyer mode bits
// Supports Iambic A and B
// State machine based, uses calls to millis() for timing.
switch (keyerState) {
case IDLE:
// Wait for direct or latched paddle press
if ((digitalRead(LeftPin) == LOW) ||
(digitalRead(RightPin) == LOW) ||
(keyerControl & 0x03)) {
update_PaddleLatch();
keyerState = CHK_DIT;
}
break;
case CHK_DIT:
// See if the dit paddle was pressed
if (keyerControl & DIT_L) {
keyerControl |= DIT_PROC;
ktimer = ditTime;
keyerState = KEYED_PREP;
}
else {
keyerState = CHK_DAH;
}
break;
case CHK_DAH:
// See if dah paddle was pressed
if (keyerControl & DAH_L) {
ktimer = ditTime*3;
keyerState = KEYED_PREP;
}
else {
keyerState = IDLE;
}
break;
case KEYED_PREP:
// Assert key down, start timing, state shared for dit or dah
digitalWrite(ledPin, HIGH); // turn the LED on
tone( buzzerPin, NOTE_D5 );
ktimer += millis(); // set ktimer to interval end time
keyerControl &= ~(DIT_L + DAH_L); // clear both paddle latch bits
keyerState = KEYED; // next state
break;
case KEYED:
// Wait for timer to expire
if (millis() > ktimer) { // are we at end of key down ?
digitalWrite(ledPin, LOW); // turn the LED off
noTone( buzzerPin );
ktimer = millis() + ditTime; // inter-element time
keyerState = INTER_ELEMENT; // next state
}
else if (keyerControl & IAMBICB) {
update_PaddleLatch(); // early paddle latch in Iambic B mode
}
break;
case INTER_ELEMENT:
// Insert time between dits/dahs
update_PaddleLatch(); // latch paddle state
if (millis() > ktimer) { // are we at end of inter-space ?
if (keyerControl & DIT_PROC) { // was it a dit or dah ?
keyerControl &= ~(DIT_L + DIT_PROC); // clear two bits
keyerState = CHK_DAH; // dit done, check for dah
}
else {
keyerControl &= ~(DAH_L); // clear dah latch
keyerState = IDLE; // go idle
}
}
break;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Latch dit and/or dah press
//
// Called by keyer routine
//
///////////////////////////////////////////////////////////////////////////////
void update_PaddleLatch()
{
if (digitalRead(RightPin) == LOW) {
keyerControl |= DIT_L;
}
if (digitalRead(LeftPin) == LOW) {
keyerControl |= DAH_L;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Calculate new time constants based on wpm value
//
//////////////////////////////////////////////////////////////////////////////
void loadWPM (int wpm)
{
ditTime = 1200/wpm;
}
0 件のコメント:
コメントを投稿