Jump to content

LaunchPad as Iambic Keyer

Recommended Posts

  • Replies 39
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Thanks for creating this project.   After I received my Ham License I wanted to start learning CW, but using a straight key has been a challenge. I found this project inspiring and I think I now ha

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 a

Here is my iambic keyer. In the spirit of the MSP430 I put it to sleep at every opportunity, including between starting and stoping dits and dahs. It uses a 32 kHz clock crystal and sleeps in LPM3 f

Posted Images

Thanks Rob. Can I impose on you a moment, please?


I haven't quite figured out what's goin' on in your program so I took a look at an old (mode B) iambic keyer program I wrote in 2003. Converted from assembly, it should look something like the listing below. Please tell me if your program is doing approximately the same thing?


It looks like my old program continually sampled the paddles and updated a memory bit for each paddle input while generating the dot or dash side-tone. After sending a dot the dot paddle memory would be cleared and after sending a dash the dash paddle memory would be cleared. If there isn't a pending iambic (opposite paddle) memory bit the paddle memory would be refreshed to see if the same paddle was still being pressed. So after the last "memory" (dot or dash) has been sent it looks like I added a two dot time space to effectively force a 3 dot time inter-character space. Is this similar to what you're doing?


Cheerful regards, Mike


//  pseudo C code approximation of my 2003 assembly language program
   paddles |= (~gpio & 3);     // refresh paddle memories (GP0 & GP1)
   if(ditpaddle) goto dit;     // if dit memory (paddles.bit0)
   if(dahpaddle) goto dah;     // if dah memory (paddles.bit1)
   goto loop;                  // wait for paddle input
   doDit(1);                   // send dit + 1 dot space
   ditpaddle = 0;              // clear dit memory
   if(!dahpaddle) goto eoc;    // branch if no dah memory
   doDit(3);                   // send dah + 1 dot space
   dahpaddle = 0;              // clear dah memory
   if(ditpaddle) goto dit;     // if pending dit memory, do dit
   paddles |= (~gpio & 3);     // refresh paddle memories
   if(paddles == 0);           // if end-of-character
     doSpc(2);                 // force 3 dot time inter-char space
   goto loop;                  // and loop

Link to post
Share on other sites

The timer is set to interrupt every 640us. During each interrupt, an audio port is toggled (producing 781.25Hz sound when active) and duration counter is increased when sending dot/dash is in progress. Duration of a dot is 1875/wpm, which can be adjusted by pressing S2 and a paddle. When a paddle is pressed, a flag is set. Each time timer's ISR is finished, MCU wakes up and goes through the while loop, state of paddles is checked, and so is progress of sending. When duration counter is 0 and the pressed flag is set, audio and key are turned on and duration counter is enabled. When duration counter reaches the end of dot/dash, sound and key are turned off and then it continues counting until it reaches dot/dash + dot. At that time, if any of the paddles are still pressed, sending continues alternating dot and dash when both paddles are pressed.


Improvements to come:

putting MCU in LPM4 when not active (piece of cake.)

refactoring while loop to allow characters/messages to be sent from memory or from USI,

adding ASCII to morse converter (almost done.)

Link to post
Share on other sites

Thanks for the explanation Rob. May I ask which environment you're using, please? I'm getting errors trying to compile your program in CCS v4...


Thanks, Mike



Oops! Please disregard... It's compiling ok now...

Link to post
Share on other sites

Ok Rob, I got it all hooked up and working but it's pretty much unusable for me. I'm an avid CW op' and it seems like you're implementing Mode A which doesn't use a 1 bit paddle memory. Almost all keyers, including the one built-in to my Icom 756Pro-II, use Iambic Mode B with 1 bit paddle memory. The difference is that when sending a C (dah-di-dah-dit) I can release the dit and dah paddles during the last dah and the keyer will send the last dit. It really makes a gargungous difference in Iambic keyer operation to a CW op'. Any chance you can implement Mode B?


More later. Cheerful regards, Mike



Here's my favorite set of paddles, the WBL V22 (on the left), which was custom made by Stan Hails, W9WBL. I waited about seven months for mine after ordering it. They're no longer in production.



Link to post
Share on other sites

Mode A is actually the way keyers should work, but I was thinking about adding mode B since it's difficult for users to switch between them. It will most likely come with other improvements.


Those are some monster keys. Myself, I was never into iambic keys until I got one several years ago, but then came the kids and my gear is now gone except for that lonely Bencher, some parts, and a collection of handbooks. When I began as SP5RDV, I had to learn on a straight key (to get novice, 12 wpm was required, 20 for higher class.)


On a personal note, I think ham radio lost some of its magic, in part because of the internet and in part because of commercially made rig. I got into ham radio because I was into electronics and building my own rig was right up my alley. Using my Yaesu or Kenwood was just not the same and not as exciting as using what I have built from scratch (usually not as stable or precise and without fancy features.) My next rig will definitely be home brewed :)

Link to post
Share on other sites
Mode A is actually the way keyers should work...


If you're not going to preface a statement like that with "in my opinion" then my response might be something like "you have no idea what you're talking about" (lol).


Ok on your original SP5RDV callsign. I was DA1LM in Germany many years ago while serving as Chief Operator and License Custodian for Army MARS Station AE1MAN (DL5MA) at Nellingen Barracks near Stuttgart. Got out of the hobby while raising kids but after Helen and I got our Private Pilot licenses in '97 I thought about Ham Radio again. I attended a local radio club meeting in March '98 without a license and shocked everyone by showing up for the April meeting with a brand new Extra Class license (20-wpm code). I enjoy DX and have 318 countries confirmed. Other awards include WAS CW, SSB, RTTY (8 bands), DXCC CW, SSB, RTTY (8 bands), CQ WAZ CW, SSB (6 bands), ARRL A1 Operator Club, and more. While it was operational, I also enjoyed using the Russian RS12/13 low earth orbit satellite transponder (2m up, 10m down) for CW contacts. I used some really incredible software from AMSAT to predict AOS (acquisition of signal) and LOS (loss of signal) for the satellite and to control the VFOs on a Yaesu FT-847 transceiver to compensate for Doppler Shift which was pretty important since you might only be within the satellite footprint for 10 to 15 minutes on some passes.


I'm sorry to hear you've lost interest in Ham Radio. There are some very fascinating state-of-the-art aspects that keep me interested like SDR (software defined radio) and many new digital modes, all which take advantage of the DSP processing capabilities of a PC Sound Card.


More later... Mike, K8LH

Link to post
Share on other sites
Woah! Stan Hails seems to love his CW paddles!


That's a labour of love! Amazing!


Yes, his paddles were hand made. There are also several other very nice commercial paddles out there but they're incredibly expensive.


Take care... Regards, Mike

Link to post
Share on other sites
Mode A is actually the way keyers should work...

If you're not going to preface a statement like that with "in my opinion" then my response might be something like "you have no idea what you're talking about" (lol).

Well, that statement is true. After all, isn't mode B a result of a bug (not sure if the memory effect in the original accu-keyer was intentional or not) which simply caught on?

Link to post
Share on other sites
Mode A is actually the way keyers should work...

If you're not going to preface a statement like that with "in my opinion" then my response might be something like "you have no idea what you're talking about" (lol).

Well, that statement is true.

Can you prove that empirically? Isn't that just your opinion? And so what may seem like an authoritative statement to someone a little less knowledgeable has the potential to make you look like an ass to someone who's a little more familiar with the subject. A simple qualifier can go along way. After all, you don't claim to be an authority or expert on everything, right?


After all, isn't mode B a result of a bug (not sure if the memory effect in the original accu-keyer was intentional or not) which simply caught on?

Here's a reprint of the original accu-keyer article by James M. Garrett, WB4VVF, which appeared in the August 1973 issue of QST. After a quick read it seems he's intentionally using Mode B but why not take a look for yourself.


I've never read anything about "a bug" in one mode or the other during my research. I just know some people prefer Mode A, especially if they're used to using a vibroplex bug or a single paddle, and some people prefer Mode B. I learned how to use a keyer by building and using the accu-keyer and I suspect that's why I prefer Mode B. I still have it in a storage box somewhere. If I come across it I'll post a picture. It's a remarkable example of how we used to do things "the hard way" with discrete logic ICs before microcontrollers (grin).


Have fun with your projects.


Cheerful regards, Mike

Link to post
Share on other sites

There is a reason this mode is called Mode B, it is not the primary mode. In fact, modes are not mentioned anywhere in that article simply because modes were not defined yet, the feature was referred to as memory. Modes were introduced later because people had a hard time switching between them.

The bottom line is Mode A is what you would expect the keyer to work like, just like the original Curtis, you release the paddles, the current bit is the last bit to be sent. If some people prefer an alternate behavior, then it's their choice, but it doesn't change the fact that Mode B is an altered version of original Mode A.


...according to John[Curtis], Mode B was actually a design error by an unnamed company...

Source: ARRL


The only thing I may be wrong about is who introduced this design error, because it looks like it is pre-accu-keyer. Somehow I was always associating Mode A with Curtis and Mode B with accu-keyer. Other than that, all my statements are valid.

Link to post
Share on other sites

Your reasoning and logic is incredible (grin) so we should probably just agree to disagree (lol).


Moving on... I wonder if you or other forum members might care to comment on my attempt to optimize that old PIC iambic keyer algorithm? I'm almost embarrassed at how crude that code looked after eight years (lol).


The iambic logic uses just two variables; a "paddles" memory bit variable and an iambic "select" bit variable. Iambic "select" bits are toggled each time through the while(paddles) loop to support the iambic logic. After sending a dit or dah, a pending iambic (opposite) "paddles" memory bit will be processed the next time through the while(paddles) loop. In the absense of a pending iambic (opposite) "paddles" memory bit, a pending non-iambic bit (multiple dits or dahs) will be processed after two trips through the while(paddles) loop. At end-of-character (no pending paddle memory bits) the code falls out of the while(paddles) loop and generates a 2 dit space for 3 dit inter-character spacing. The algorithm supports both Mode A and Mode B.


The send() routine sets up timers and sends either a dit (0) or a dah (1) followed by a 1 dit space. While sending the dit or dah and space, the "paddles" memory is refreshed at the side-tone frequency which should be more than fast enough to pick up inserted iambic (opposite) paddle memory bits for Mode B.


TIA for any suggestions, advice, or criticism Gentlemen. I wanted to provide Rob with a different perspective before I started a new thread to ask for help implementing the algorithm on an MSP430.


Cheerful regards, Mike


   *  K8LH optimized iambic keyer algorithm, (C) 2011, Mike McLaren
   void main()                   // 
   { ...                         // initialization code
     ...                         // initialization code

     while(1)                    // 
     { while(paddles == 0)       // while no paddle memory bits
       { paddles |= (~gpio & 3); // refresh paddle memory bits
       }                         // and check again (loop)

       while(paddles)            // while pending paddle memory bits
       { if(paddles & select)    // if paddles & iambic select bit
         { send(select & 1);     // send dit or dah + 1 dit space
           if(Mode_            // if iambic mode B
             paddles ^= select;  // clear only current memory bit
           else                  // if iambic mode A
             paddles = 0;        // clear both paddle memory bits
         }                       //
         select ^= 3;            // toggle iambic select bits (01 or 10)
         paddles |= (~gpio & 3); // refresh paddle memory bits
       }                         // 
       space(2);                 // force 3 dit inter-char space
     }                           //

   }                             // end "main()"

Link to post
Share on other sites

I am actually in the process of completely rewriting my code to support not only paddles but also sending from memory and from serial interface (and of course adding Mode B.)

This turned out to be not an easy task.

First thing I did, I have created an ASCII to CW converter.

Then, I have changed the way audio is generated. That task is now handled by WDT.

Next, I have moved bit generation to the timer's interrupt routine.

What's left to do is putting all necessary logic into while loop.

I am still debating on how power savvy should I be, LPM4, LPM0, no LPM during sending. Complexity of low power design might not be worth in this case because compared to what the speaker is using, I would be saving almost nothing.

Link to post
Share on other sites

Good luck reworking the program Rob. I've done almost everything on your to-do list so don't let the Not Invented Here Syndrome keep you from asking for advice or suggestions. That old PIC keyer of mine even sent characters entered via the paddles to a terminal.


I just got my first keyer test program working on the 'G2231. It's actually my first MSP430 program so I'm really geeked. I used your schematic with paddles on P1.1 and P1.2 and piezo on P1.4 and I hard coded it for 20 wpm with a 600-Hz side-tone. It's not using interrupts or low power modes. I just wanted to verify the new iambic algorithm. Interestingly, the program uses 400 bytes of program memory and 16 bytes of RAM but the same program only uses 100 bytes of program memory and 6 bytes of RAM on a PIC. It looks like there's quite a difference between the Harvard architecture (PIC) and the von Neumann architecture (MSP430).


More later. Cheerful regards, Mike


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...