An ARDUINO Iambic Keyer

posted in: Projects | 0

An Iambic Keyer for Practice or for Keying an older rig without a built in Keyer.
For Christmas I received as a gift a Bencher Morse Paddle but alas…. my paddle skills are lacking.
I decided that I would need an Iambic practice keyer to get me up to speed.The ARDUINO is the obvious choice and with a simple Google search I found this
http://www.jel.gr/cw-mode/iambic-keyer-with-arduino-in-5-minutes/
An Iambic keyer in 5 minutes, The Keyer described uses touch sensitive pads instead of a paddle, with a few changes to Demitris code and a couple of 12K ohm pull-up resistors added from Pin 8 and Pin 10 to the 5 volt rail. A normal paddle connected from pin 8 and 10 with the common to ground now makes the device work happily with a standard paddle. I also added two momentary push buttons from pins 4 and 7 to ground. A momentary push of the button to pin 7 increases the keying speed and a momentary push of the button connected to pin 4 decreases the keying speed. Repeated very momentary presses of each button will continue to increase or decrease the keying speed between 2 preset limits. This was achieved with minor alterations to the original code.
Pin 13 flashes the Led and can also be used as an output to key an older rig without an inbuilt keyer.

The Modified Sketch:

/* Iambic keyer for arduino with baud selection buttons 2018-01-12 */
/* Based on Iambic keyer for arduino by Dimitris Sapountzakis (01/12/2011) http://www.jel.gr/cw-mode/iambic-keyer-with-arduino-in-5-minutes/ */

// Iambic keyer
#define DIT_PIN 8
#define DAH_PIN 10
#define LED 13
#define BAUD_DURATION 70 //mSec default
#define TOUCH_THRESHOLD 0 // how long to wait in uSec, before sampling the touch pin.

// baud up/down pins
#define BAUDUP_PIN 7
#define BAUDDOWN_PIN 4

// keyer state
enum{
IDLE,
DIT,
DAH,
PAUSE,
};

int dit,dah;
int state;

// baud settings
#define BAUD_MIN 10
#define BAUD_MAX 200

unsigned long baud = BAUD_DURATION;

unsigned long interbaud_duration = baud*1;
unsigned long interletter_duration = baud*2; // extra time after a baud
unsigned long dit_duration = baud;
unsigned long dah_duration = baud*3;

void recalculateBaud()
{
interbaud_duration = baud*1;
interletter_duration = baud*2; // extra time after a baud
dit_duration = baud;
dah_duration = baud*3;
}

void readBaudUpDown()
{
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(BAUDUP_PIN)) {
baud++;
if(baud > BAUD_MAX){
baud = BAUD_MAX;
}
recalculateBaud();
}

if(digitalRead(BAUDDOWN_PIN)) {
baud–;
if(baud < BAUD_MIN){
baud = BAUD_MIN;
}
recalculateBaud();
}
}

void readDit()
{
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DIT_PIN)) {
dit=0;
} else {
dit=1;
}
}

void readDah()
{
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DAH_PIN)) {
dah=0;
} else {
dah=1;
}
}

void setup()
{
// set baud based on initial default setting
recalculateBaud();

// setup input pins
pinMode(DIT_PIN, INPUT);
pinMode(DAH_PIN, INPUT);

// setup output pins
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW); //turn off led
state = 0;
}

// handles the output of the ciruit.
// if state is 1 then the contact is closed or led is turned on
void contact(unsigned char state)
{
if(state) {
digitalWrite(LED, HIGH);
analogWrite(3,5); // pin 3 drives an 8 Ohm speaker (was 3,127)
} else {
digitalWrite(LED, LOW);
analogWrite(3,0);
}
}

void loop()
{
switch(state){

case IDLE:
// check baud up/down buttons and set baud
readBaudUpDown();

readDit();
if(dit) {
state = DIT;
} else {
delayMicroseconds(0);
readDah();
if(dah) {
state = DAH;
}
}
break;

case DIT:
contact(1);
delay(dit_duration);
contact(0);
delay(interbaud_duration);

// now, if dah is pressed go there, else check for dit
readDah();
if(dah){
state = DAH;
} else {
// read dit now
readDit();
if(dit) {
state = DIT;
} else {
delay(interbaud_duration);
state = IDLE;
}
}
break;

case DAH:
contact(1);
delay(dah_duration);
contact(0);
delay(interbaud_duration);
// now, if dit is pressed go there, else check for dah
readDit();
if(dit){
state = DIT;
} else {
//read dit now
readDah();
if(dah) {
state = DAH;
} else {
delay(interbaud_duration);
state = IDLE;
}
}
break;
} // switch

delay(1);

}

Leave a Reply