From the Workbench: Arduino CW Keyer

I’m pleased to announce my Arduino CW keyer code is ready for prime time and available for download here.  At first this started out as merely porting my PIC keyer code to the Arduino, but the advanced features and ease (and joy) of coding for this platform encouraged me to venture further.  Beyond my original PIC keyer features, this creation also has a speed potentiometer, a serial port command line interface, more and bigger memories, QRSS, HSCW, and memory macros.  It also has a callsign receive practice mode, CW keyboard, and Hellscreiber sending capability.  I’m trying to figure out a way to interface with Ham Radio Deluxe and N1MM, and I have in the works a frequency counter option for use within homebew rigs, like my original PIC keyer.

The code is stable at this point, and I’m not aware of any bugs.  If anyone tries this code out and has bug reports, feedback, or feature requests, please drop me a comment.  Next I’m going to finish the Yaesu rotator computer interface.

I have a lot of ideas for an Arduino controlled antenna tuner swimming around in my mind.  After having two commercial automatic antenna tuners that were disappointing, I think I can build a better mousetrap.  The tuner will be a balanced L design capable of 150 watts or more, but still capable and accurate at QRP power levels.

Fun stuff!


14 thoughts on “From the Workbench: Arduino CW Keyer

  1. Hi Goody, can you post a zip file of the source? I am having problems pulling it off the site.


  2. Wow that project sure is cool. Love the revamped webpage, probably less obligation to always come with something to say too, but I hope you won’t be shy about adding ham radio politics either.
    Ya know what I’ve always thought would be cool? a straight key keyer. It would guarantee the length of a dit, force the spacing, and cut long dahs. I bet something like that would be pretty tricky to program into a microchip for a regular guy, but maybe not for you. Very best of 73 amigo, de Tom AB9NZ

    1. Hmmmm. It could be done. If the keyer knows the desired speed in WPM, it could mathematically determine if a key-down time is closer to a dit or dah in length and then time it appropriately. Inter-element spacing is easy, that’s always one element length and if key-up time goes beyond say 1.25 element lengths you could assume it’s an inter-character space and should be three elements long. The same algorithm could be applied to inter-word spaces.

      It would probably throw the user off (mentally) to hear the sidetone not corresponding to their key down times. One way to overcome this would be to have the sidetone correspond exactly to the straight key, but have the transmitter keying line working independently (and probably delayed a bit so you could clean up too long key up times).

      Oh, you’re going to make me want to code this, aren’t you! I like challenges :-)

  3. Hi Goody,
    I am looking into adding the SimpleFiFO library to the keyer for serial sending. Have do looked into this? I know that this is mainly a paddel input device, but it would be nice to have both options. It works well with the keyboard, but now way of error corrections during sending. So hence the idea of the FIFO on the serial side. 73,

    1. Hi Chris,

      The CW keyboard feature does do somewhat of a FIFO today, though it is using the internal UART functionality and not a FIFO in software. (If you use a terminal program like PuTTY the keyer will send serial characters immediately without a carriage return.) If I’m understanding you correctly, are you looking to be able to backspace and delete characters in the buffer, and/or perhaps delete all unsent characters in the buffer with one keystroke?

      Looking at the code, it wouldn’t take much to put a FIFO in there and be able to do backspace and a FIFO dump. I’m working up something now….

    2. Hi Chris,

      I just posted some new code that implements slash slash (\\) as a command to dump the entire buffer and backspace will delete single characters out of the buffer. The keyer now reads all characters out of the UART buffer into an array as soon as it knows there are some there.

  4. What a great project – I can’t believe it ! :-)

    I am very much interested in the planned “Winkeyer” emulation mode in progress in order to have a homebrew/freeware alternative available for building a nice contest keyer for use with N1MM contest logging software.

    How are you progressing? I think the host PC is expecting that the keyer is echoing the characters in order to check if a winkeyer is connected. There are some programming examples on how to communicate from a computer with a Winkeyer 2 here: (see last pages) and in the handbook there is a serial interface host mode command description (page 5pp.):

    BTW, I tested VSPE (virtual serial port emulator) with N1MM soft to analyze and monitor the serial commands two ways. It works great….

    Unfortunately, I am not yet very familiar with Arduino as I come from the AVR BASCOM world… :-) 73 de Oscar

  5. Hello Oscar,

    I have written some code that parses the commands from N1MM, but no matter what I send back to the program (echos or not), it stops talking after two CW message commands. So apparently the code is missing something N1MM wants to see. If you have a VSPE capture of the two way communication, I would love to see it. I’ll figure it out sooner or later. I think I’m very close.


    1. Hi,

      I spent some time the last week investigating the Winkeyer bidirectional protocol syntax. The whole secret is that you need to carefully read the Winkeyer software datasheet (second link above) – it contains all essential infos and lots of hints.
      I manage now to “mimic” a connected Winkeyer by using a dumb terminal like hTerm (which allos sending hex bytes).
      The secret is that for a very minimalistic setup you need to send back a status byte C4 (hex) which signals to N1MM that the keyer is currently sending out the previously received text string. Then letter by letter is echoed back to N1MM (as it is morsed). After the last letter was morsed you need to send a stutus bye C0 (hex), which means the keyer is not sending CW anymore and is reay for sending the next string.
      For a minimalsit Winkeyer emulation this should do the job, however I would recommend also to add parsing a few of the other commands too for making the whole thing a bit more robust and add functionality (e.g. CW speed change)…
      Try the two status bytes first – it should work…
      73 DJ0MY, Oscar

      1. Hi Oscar,

        I spent more time on it today. I think there is more handshaking than that because the program doesn’t think the Winkey device is present unless it sees a version number come back from the 0x00, 0x02 command it sends. I send a 0x01 back and it doesn’t give an error message anymore, but it does many 0x0E, 0x15 commands continually, until I hit a memory key.

        Are you able to determine what is supposed to be echoed back? Is it only sent CW characters or also commands? Could you send me a full capture of the bidirectional data?

    1. Hi,

      strange – I can send the Function Key messages w/o reporting version number back at all.

      Anyway, version number would be 10 for Winkeyer 1 chip and 20-23 (decimal?) for Winkeyer 2 chip depending on firmare revision number.

      But in my case I can simply ignore all the initialization stuff (however I twiggled a bit with the Winkeyer settings in N1MM setup – specially to ignore the Winkeyer Seepdpot is enabled in my config – perhaps yours is waiting for the speedpot setting feedback byte?).

      When I hit a function key the first TX string goes out (with some speed and buffer comands embedded in front, such as buffered speed comends)…..but if I hit a function key twice the second string to be sent is blocked till N1MM gets the C0 status byte back from the keyer (or in my case typed by me from the terminal soft).
      It seems therefore that the N1MM DLL has also its built in FIFO buffer on the PC side, because if you press a function key twice and send the C0 status byte the new string waiting in the buffer of the PC is sent immedientely to the keyer….(this way you could even avaid having a FIFO buffer in the keyer itself, because you can control the serial port flow by the status byte flags).

      Only Status bytes (whenever anything important in the keyer changes – like sending morse or being readz with sending morse – see status byte documentation) is echoed back and text currently sent in morese is echoed back. Other than that there should be no echoes at all.

      If you want we can take it offline and discuss this by mail incl some bidirectional data capture exchange…my mail is – just drop me a short note and I reply to you with more stuff….

      I think you do not need to implement much of the original firmware protocol, other than the Status byte feedback and CW character TXed echo as well as perhaps the WPM speed control. The rest most likely can be fully ignored in the first experimental phase.

      73 de Oscar

Leave a Reply to Oscar DJ0MY Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s