Jump to content
Forum sending old emails Read more... ×
Sign in to follow this  
RobG

LaunchPad as Iambic Keyer

Recommended Posts

Here's my first iambic keyer, it's very simple, but I am planning to add some more functions.

I know, I know, my morse is little rusty, but it's been a long time and I am not used to the Bencher, I am a straight key guy.

EDIT: New addition, press S2 + paddle to change the speed +/-1wpm.


post-197-135135499065_thumb.png

#include 

#define AUDIO BIT4 // audio monitor output, 781.25Hz
#define KEYOUT BIT0 // key output
#define DOT BIT1 // dot paddle
#define DASH BIT2 // dash paddle
#define SPEEDSWITCH BIT3 // press S2 switch and paddle to change the speed, dot paddle + 1 wpm, dash - 1 wpm.

unsigned int counter = 0; // main counter
unsigned char counterOn = 0; // counting enabled
unsigned int wpm = 18; // speed in WMP
unsigned int dotCount = 0; // duration of one dot for the given speed
unsigned int onCount = 0; // count needed to complete "on" cycle, for dash it will be dotCount * 3
unsigned char dotDash = 0; // used to determine what to send next when both paddles are pressed
unsigned char pressed = 0; // indicates that one of the paddles is presses

void main() {

WDTCTL = WDTPW + WDTHOLD; // stop WDT

BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
BCSCTL2 |= DIVS_3; // 1MHz/8

P1DIR = KEYOUT; // key output
// paddle inputs and speed switch
P1OUT = DOT + DASH + SPEEDSWITCH; // pull up
P1REN = DOT + DASH + SPEEDSWITCH; // enable resistors
P1IES = DOT + DASH; // trigger hi -> low
P1IFG = 0; // clear flags
P1IE = DOT + DASH; // enable interrupts

dotCount = 1875 / wpm; // duration in ms is 1200 by WPM, but our interrupt is every 640us

TACTL = TASSEL_2 + MC_1 + ID_3; // SMCLK/8, upmode
CCR0 = 10; // 10 * 64us = 640us
CCTL0 = CCIE; // CCR0 interrupt enabled

_bis_SR_register(LPM0_bits + GIE); // LPM0 with interrupt

while(1) {
if(pressed == 0) { // do nothing
counter = 0;
} else {
if(counter == 0) { // starting new dot/dash
onCount = dotCount; // set count to duration of dot
if((P1IN & (DOT + DASH)) == 0) { // both paddles are pressed, set count to the opposite of what it was last
if(dotDash) {
onCount *= 3; // set duration to dash
}
} else if(~P1IN & DASH) { // dash paddle pressed, set count to dash
onCount *= 3;
dotDash = 1;
}

if((~P1IN & (DOT + DASH)) == 0) { // just in case, if key was released, reset
counter = 0;
pressed = 0;
dotDash = 0;
counterOn = 0;
} else { // turn audio and key on
P1DIR |= AUDIO;
P1OUT |= KEYOUT;
counterOn = 1;
}
} else if(counter == onCount) { // turn off audio and key
P1DIR &= ~AUDIO;
P1OUT &= ~KEYOUT;
} else if(counter == (onCount + dotCount)) { // done with dot/dash and space after
counter = 0;
counterOn = 0;
if ((~P1IN & (DOT + DASH)) == 0) { // paddles released
pressed = 0;
dotDash = 0;
} else { // still holding paddle(s)
if(~P1IN & SPEEDSWITCH) { // changing speed?
if(~P1IN & DOT) {
wpm++;
} else if(~P1IN & DASH) {
wpm--;
}
dotCount = 1875 / wpm; // new dot count
}
if((P1IN & (DOT + DASH)) == 0) { // both paddles are squeezed, toggle
dotDash ^= 1;
}
}
}
}
_bis_SR_register(LPM0_bits);
}
}

// Timer A0 interrupt service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void) {
if(counterOn) {
counter++;
}
P1OUT ^= AUDIO; // toggle every 640us to generate 781.25Hz waveform
_bic_SR_register_on_exit(LPM0_bits);
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {
P1IE = 0;
P1IFG = 0;
pressed = 1;
P1IE |= DOT + DASH;
}

Share this post


Link to post
Share on other sites

Some additional info' for anyone interested...

 

;
; Some general information about Morse Code Speed;
;
; <1> A Dash is three times longer than a Dot
; <2> A Dot space between Dashes and Dots within a character
; <3> A pause between characters is three Dots long
; <4> A pause between words is seven dots long
;
; The word 'Paris' was established as an international standard
; for calculating the speed of Morse in words-per-minute (wpm) 
; and characters-per-minute (cpm)...  This works out to 50 dots
; (or dot times) per word and yields the following timing;
;
;  5-wpm ( 25-cpm) =  60 /  250 dots = 240-msec / dot
;  6-wpm ( 30-cpm) =  60 /  300 dots = 200-msec / dot
;  7-wpm ( 35-cpm) =  60 /  350 dots = 171-msec / dot
;  8-wpm ( 40-cpm) =  60 /  400 dots = 150-msec / dot
;  9-wpm ( 45-cpm) =  60 /  450 dots = 133-msec / dot
; 10-wpm ( 50-cpm) =  60 /  500 dots = 120-msec / dot
; 15-wpm ( 75-cpm) =  60 /  750 dots =  80-msec / dot
; 20-wpm (100-cpm) =  60 / 1000 dots =  60-msec / dot
; 25-wpm (125-cpm) =  60 / 1250 dots =  48-msec / dot
; 30-wpm (150-cpm) =  60 / 1500 dots =  40-msec / dot
; 35-wpm (175-cpm) =  60 / 1750 dots =  34-msec / dot
; 40-wpm (200-cpm) =  60 / 2000 dots =  30-msec / dot
; 50-wpm (250-cpm) =  60 / 2500 dots =  24-msec / dot
; 

Share this post


Link to post
Share on other sites

Some old-schoolers (maybe US Navy?) were taught 5-dot times between words

although the current teaching is to us 7-dot times of spacing. I dug that up when

I wrote my text-to-morse-code program.

 

-Rusty-

Share this post


Link to post
Share on other sites

Rusty,

 

I seem to recall some debate about five or seven dot spacing between words too Sir.

 

 

 

Rob,

 

Forgot to say "nice job" on the iambic keyer program. I'm looking forward to studying it.

 

 

 

Regards, Mike

Share this post


Link to post
Share on other sites
This is a great use of the 430! You should submit this as an article to QST.

I didn't even think about that, but why not (once I add some extra features of course.)

I think LP makes a nice alternative to PIC and QST would be a good way to spread the word.

Share this post


Link to post
Share on other sites

Rob,

 

What is the circuit you're using to drive the permanent magnet speaker, please? Is that some sort of emitter follower?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×