Arduino CW Keyer Project (Alpha)

In order to get my first license (Technician Plus) with HF privileges, I had to learn morse code at a level of 5 words per minute. To upgrade to General, you had to learn 13 words per minute and to upgrade to the Extra Class, you had to learn 20 words per minute. I was always told it is better to try and practice at 13 word per minute as you can pick it up better with the right spacing but I never made it that far. A local ham who is SK now bent over backwards to help me learn morse code by sending to me over the air and allowing me to use tapes that he had to practice copying. I passed the test 1st time out because of the work that he put in.

Ever since I got licensed after passing the 5 words per minutes code requirement, I did not touch it again. This was not due to lack of interest, from what I can tell, but lack of time. You need to keep using it in order to stay proficient but you don’t really lose it all. I find myself send in my head occasionally, lol… I do feel bad for not pursuing the CW part of the hobby because I have missed out on some nice contacts and contests. Because I have lost some of the characters, I need to practice to get proficient again.

Since the requirement to pass the CW portion of the test was removed by the ARRL years ago, which I feel should not have happened, it made it easier for more and more people to get into the hobby. CW was a challenge and a good one. It challenges your mind and hand coordination and will always remain as a reliable means of communicating with other hams and even during emergencies, with other agencies on HF. Lately, the sun has been very upset and the radio conditions on HF have been less than perfect. Now, off of my soapbox and on to the project at hand. 😀


First off, I want to thank Anthony (K3NG) for the hard work in the software for this project. If it wasn’t for the software, this may have never gotten done. To help myself learn CW and jump in with both feet, I am going to be building a copy of the K3NG CW keyer which has a lot of capability to work with. According to his web site, located at here are the capabilities that are in place at this time. This is an awesome thing to play with and well worth it once complete. Below will show what I am doing and what I am using to make this project work with my hardware.

The features, which are available through the king_keyer application firmware, are located within the file called keyer_features_and_options.h. This gives a list of available features and options that you can add or remove from the firmware depending on your needs and or space available. From what Anthony told me, all I need to do is uncomment the FEATURE_ lines that I want and recompile to the Arduino Mega. There should not be any special configuration required to make the Mega work with this firmware.


  • CW speed adjustable from 1 to 999 WPM
  • Up to six selectable transmitter keying lines
  • Programming and interfacing via USB port (“command line interface”)
  • USB or PS2 Keyboard Interface for CW keyboard operation without a computer
  • Logging and Contest Program Interfacing via K1EL Winkey 1.0 and 2.0 interface protocol emulation
  • Optional PTT outputs with configurable lead, tail, and hang times
  • Optional LCD Display – Classic 4 bit mode , Adafruit I2C RGB display or YourDuino I2C LCD Display
  • Up to 12 memories with macros
  • Serial numbers
  • CW keyboard (via a terminal server program like Putty or the Arduino Serial program)
  • Speed potentiometer (optional – speed also adjustable with commands)
  • QRSS and HSCW
  • Beacon / Fox mode
  • Iambic A and B
  • Straight key mode
  • Ultimatic mode
  • Bug mode
  • CMOS Super Keyer Iambic B Timing
  • Paddle reverse
  • Hellschreiber mode (keyboard sending, memory macro, beacon)
  • Farnsworth Timing
  • Adjustable frequency sidetone
  • Sidetone disable / sidetone high/low output for keying outboard audio oscillator
  • Command mode for using the paddle to change settings, program memories, etc.
  • Keying Compensation
  • Dah to Dit Ratio adjustment
  • Weighting
  • Callsign receive practice
  • Send practice
  • Memory stacking
  • “Dead Operator Watchdog”
  • Autospace
  • Wordspace Adjustment
  • Pre-configured and Custom Prosigns
  • Non-volatile storage of most settings
  • Modular code design allowing selection of features and easy code modification
  • Non-English Character Support
  • CW Receive Decoder (EXPERIMENTAL)
  • Rotary Encoder Speed Control
  • Sleep Mode
  • USB Mouse Support
  • Mayhew LED Ring Support
  • Alphabet Sending Practice
  • QLF / Straight Key Emulation (NEW)
  • USB Keyboard HID (Human Interface Device) Interface (Keyer = keyboard for your computer) (NEW)



There has been a major change in CW keyer project that I was originally looking into, using this software, which I need to explain. I was originally looking at using the Arduino Yun for the CW keyer project which could also allow remote control via the “Bridge” over a web browser. This could have been done by tying into the web server portion of OpenWRT on the linux side the Yun and talking across to the ATmega programming. I found out that in order to take advantage of the full capability that the firmware has, I would have to look at a different hardware solution. The Yun could not support the firmware due to the size of the ATmega chip used on that device. The Yun uses an ATmega32u4 which is has a flash memory of 32kb (of which 4kb is used be the boot loader). It was recommended to use the Arduino Nano, which houses either 512 bytes (ATmega168) or 1 KB (ATmega328). I am not so sure about this, but many of these keyer projects are using the Nano for their size. I decided to go with the Arduino Mega 2560 which houses 256kb of flash memory (of which 8kb is used by the boot loader). I felt that if I wanted to use all of the capabilities that the firmware was offering, then this would give me the room to do so. There are other considers here as well.

Below shows the Digital / PWM / Analog Pins which are available on each Arduino and you can see another reason why I chose the Mega for this. To have LED’s, buttons, switches, and jacks, the more connections the better. Now, in the circuit, I’m sure that not all of these pins will be used for this as there are ways to tie connections together through a single line such as grounding and the 5 volt line to power the circuit.


Arduino Nano Pins

Digital I/O Pins 14

PWM Pins 6

Analog I/O Pins 8


Arduino Yun Pins

Digital I/O Pins 20

PWM Pins 7

Analog I/O Pins 12


Arduino Mega 2560 Pins

Digital I/O Pins 54

PWM Pins 15

Analog I/O Pins 16




If interested, here are the technical specifications for the Arduino Mega R3. You will want to pay attention to the digital pins, analog pins and clock speed (CW Decoding).

Technical specs
Microcontroller ATmega2560
Operating Voltage 5V
Input Voltage (recommended) 7-12V
Input Voltage (limit) 6-20V
Digital I/O Pins 54 (of which 15 provide PWM output)
Analog Input Pins 16
DC Current per I/O Pin 20 mA
DC Current for 3.3V Pin 50 mA
Flash Memory 256 KB of which 8 KB used by bootloader
Clock Speed 16 MHz
Length 101.52 mm
Width 53.3 mm
Weight 37 g



One thing that is standing out as a change which has taken me some time to get documented is the pin layout of the Arduino Mega which is very different from the Yun and Uno that I have. As you can see below, there is a separate digital section which starts with pin 22 and goes to pin 53. Pins 23, 25, 27, and 29 appear to be 5V Pins and the digital ground is in the lower right for use by digital signals. The analog pin layout is across the bottom and are labeled A0 to A15. The power for the analog section is before the pins with two ground pins and a 5V pin. The way this is shown should give us plenty to work with when building out this keyer and the features in the firmware.

Screen Shot 2015-08-06 at 4.47.09 AM




I have attached the schematic that K3NG put together on the original CW Keyer project. I will be using this for the major part of the build, but will be adding things like an LCD for programming and CW decoding. Since the pin layout will be different on the Arduino Mega, please ignore the pin numbering shown below as they will be changed in the programming to fit our Arduino Mega.





Below shows the schematic for the Arduino Mega to give everyone a better feel for what this looks like. This can be found at

Screen Shot 2015-08-06 at 1.59.59 PM



Now that we have the schematics and other information needed, it is time to get this build underway. One thing to remember while working with the prototype boards, “SLOW DOWN AND TAKE YOUR TIME” It is very easy to make a mistake and short something out, if not careful. Below shows an example as to why you need to slow down and watch. In the below example for the Blink sketch, there are some green highlighted areas. These show the 5v (Red) connections across the top of the board, the negative (Black) right below. What I want you to look at are how the parts are laid out. There are green lines showing that each vertical line on the board are a single piece of metal inside. So if you connect the LED up like it is and try to hook something else up in the same trace, it will not work or could short the LED.





I was looking at the schematic and the symbols used show 5 x 0.01 microfarad (Electrolytic) Capacitors, 1 x 100 microfarad (Electrolytic) Capacitor and for the input audio circuit, 1 x 0.1 microfarad (Ceramic) Disk capacitor. The reason that I am bringing this up now is to help with what the circuit needs. While reading Anthony’s web site, the 5 x 0.01 microfarad capacitors should be ceramic disk capacitors and the 100 microfarad capacitor should be an electrolytic capacitor as well. It looks like the 0.1 microfarad capacitor in the input circuit should be a ceramic disk capacitor, that I will show later on in this post.

1. Ceramic Disk Capacitor

2. Electrolytic Capacitor





Let’s start with making sure that the build can be sent to the Arduino Mega with no hardware or compile issues. In order to do this, below are the steps that I used to get the firmware onto the Arduino Mega. These are the same steps used when uploading any sketch to any arduino using the IDE application shown below.

– Make sure that you have the Arduino IDE package installed from here –

– Download the firmware from this location –

– Since the above link if from GitHub, when you visit that link, go to the right side of the screen, and click on Download Zip

– Unzip the file into the folder into your Arduino sketch folder

– Before compiling and uploading your sketch, just take some time and go through the .h files to make sure it has everything you need for this build. For example, we need to change the pin layout to make sure that we have the pins set to what we need. We also need to uncomment features that we are looking for, etc. By doing this now, we will save time during the build and troubleshooting phases of this project.

– This should compile just fine, but I ran into an issue with the compiler saying the goertzel.h file was missing. To fix this, just go into the libraries folder and copy that file out into the main project folder and compile again. It should work just fine this time.

– If for some reason, the above does not work, try to load the Blink sketch from the IDE and see if it loads without error. If it has errors as well, change your USB cable and try again.

– Always remember that any changes to the code will require a reupload to the Arduino.

– If the .h files are located in the correct locations and you get errors, try to close the IDE and restart it again. Sometimes the IDE has problems with files being moved around while it is operational and can not see the changes live.



ARDUINO PINS with keyer_pin_settings.h

Below shows the pin layout which is located in the file keyer_pin_settings.h. The setting that you see below are the default settings that come with the file. I have not changed them yet.

/* Pins - you must review these and configure ! */
#ifndef keyer_pin_settings_h
#define keyer_pin_settings_h
#define paddle_left 2
#define paddle_right 5
#define tx_key_line_1 11       // (high = key down/tx on)
#define tx_key_line_2 12
#define tx_key_line_3 0
#define tx_key_line_4 0
#define tx_key_line_5 0
#define tx_key_line_6 0
#define sidetone_line 4         // connect a speaker for sidetone
#define potentiometer A0        // Speed potentiometer (0 to 5 V) Use pot from 1k to 10k
#define ptt_tx_1 0              // PTT ("push to talk") lines
#define ptt_tx_2 0              //   Can be used for keying fox transmitter, T/R switch, or keying slow boatanchors
#define ptt_tx_3 0              //   These are optional - set to 0 if unused
#define ptt_tx_4 0
#define ptt_tx_5 0
#define ptt_tx_6 0
#define cw_decoder_pin A11 //A5 //A3  // if using OPTION_CW_DECODER_GOERTZEL_AUDIO_DETECTOR this must be an analog pin!
#define cw_decoder_indicator 24
#define tx_key_dit 0            // if defined, goes high for dit (any transmitter)
#define tx_key_dah 0            // if defined, goes high for dah (any transmitter)

#define analog_buttons_pin A1
#define command_mode_active_led 0

//lcd pins
#define lcd_rs A2
#define lcd_enable 10
#define lcd_d4 6
#define lcd_d5 7
#define lcd_d6 8
#define lcd_d7 9

#ifdef FEATURE_LCD1602_N07DH
#define lcd_rs 8
#define lcd_enable 9
#define lcd_d4 4
#define lcd_d5 5
#define lcd_d6 6
#define lcd_d7 7
#endif //FEATURE_LCD1602_N07DH

//ps2 keyboard pins
#define ps2_keyboard_data A3
#define ps2_keyboard_clock 3    // this must be on an interrupt capable pin!

// rotary encoder pins and options - rotary encoder code from Jim Balls M0CKE
#define OPTION_ENCODER_HALF_STEP_MODE     // Half-step mode?
#define rotary_pin1 0                      // CW Encoder Pin
#define rotary_pin2 0                    // CCW Encoder Pin
#define OPTION_ENCODER_ENABLE_PULLUPS     // define to enable weak pullups.

#define led_ring_sdi    A10 //2    //Data
#define led_ring_clk    A9 //3    //Clock
#define led_ring_le     A8 //4    //Latch

#define correct_answer_led 0
#define wrong_answer_led 0

#define ptt_interlock 0  // this pin disables PTT and TX KEY

#endif //keyer_pin_settings_h




Now that we have we the features chosen and the compiled release added to the Arduino Mega, we can start with the physical build and troubleshooting parts as they come along. I started by separating the voltage lines on the breadboard to make sure that I had what was need for the appropriate pin selections. This also shows what I was referring to about where the digital and analog voltage lines are located. Analog across bottom, digital on the right side or back side of the board. This should get us the voltage required for the circuit to work just fine. Now, I was told that there did not appear to be any separation between the analog and digital sections of this Mega, as far as we can tell. I am still researching to see if these are separate on purpose on just board or if they are electronically separate.

On the prototype board that I am using, there are two sets of voltage pins, the positive (5v) and negative (GND), which located on the top and the bottom. The positive (5v) lines are usually on the inside while the negative (GND) are usually on the outside. Depending on how small of large of the project, you could place the positive (5v) on the top and negative (GND) on the bottom to have them separated better.


SUGGESTION: When you start to build this project out, don’t go with just 5volts to the arduino board. Go ahead and invest in a 12 volt supply for this project. The reason is that an LCD display, LED bulbs, etc will be added and could cause a drain from the main board. I have witnessed this already so I added a 12V 1.5 amp power supply and this project became more stable. 

Screen Shot 2015-08-06 at 4.54.12 AM




Now we will look at adding the buttons to the board to make sure that we have room to build this out. According to the schematic below, there are six buttons which can be added. One button for the command section and programming and the others are memory buttons. You can add on as many as you need for this project. The buttons appear to be single pull / single throw buttons where one terminal is tied together with 1k resistors throughout the build. The initial resistor being added before the buttons is a 10k, according to the schematic. The resistors connect from the terminal back to the 5 volt line. The line heading off the page goes from the same voltage terminal to the analog pin 18 which will be changed to another pin to fit our Arduino Mega. The terminal connecting the actuator of the button is connecting to the ground.

Screen Shot 2015-08-07 at 7.00.34 AM







I have decided to break this out a little more than I should so that I can show what I am doing in the prototype build process. Below, you can see that I have left the voltage lines as they are for now, until I figure out if they are needed. Normally, I will use red wire for voltage leads and black for GND, but my wire kit that has the smaller wires, does not have black or red in the appropriate lengths. In the first image, I have added the buttons per the schematic. The first button will be the command / program button while the other buttons are set aside for memory usage at this time.

Screen Shot 2015-08-07 at 8.00.16 AM

As I mentioned above, my project wire kit does not the proper color wires in the right lengths, so I went with what I had. In the second image, I added the grounds between the buttons and connected them to a single ground point at the bottom. By doing it this way, I have cleaned up a mess.

Screen Shot 2015-08-07 at 8.00.02 AM

In the third image, it was time to add the resistors to the buttons. As this is a prototype, I wanted to hold off in cutting things down, until I was sure that this was going to work. As you can see, I connected a 10k resistor to the 5V line at the top and added 5 1k resistors in parallel between each button. Now we need to make a decision as to where the connection gets made to the Arudino Mega. I am looking at using Pin Analog 0 (A0) for this connection as I have not set it aside yet.

Screen Shot 2015-08-07 at 7.59.48 AM

I have move a pin from the 10k resistor up one hole position and connected the wire that is going to the Arduino Mega. According to the schematic, it appears that this does go between the 10k and first 1k resistor.

Screen Shot 2015-08-07 at 8.21.24 AM

This should get us some operational buttons to help test our project. In order to get the command buttons to work, you have to uncomment the FEATURE_COMMAND_BUTTONS, FEATURE_MEMORIES and the FEATURE_MEMORY_MACROS located in the keyer_features_and_options.h file. If you forget this step, it will not work. So now we want to make sure that the pin settings are set correctly in the keyer_pin_settings.h file. Below, I have chosen Analog A0 as the analog_buttons_pin. Currently, command_mode_active_led is set to a not active state. I have set this to pin 26 for the test. Once you have made the changes to the code, you can keep building or go ahead and upload to the Arduino Mega for testing. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

#define analog_buttons_pin A0
#define command_mode_active_led 26


Now we need to add an LED so that we know if the command mode is active.

As you can see, I connected the positive lead to digital pin 26 with a 220k resistor in line to protect the bulb. The negative side of the LED is connected to the ground just above it. The program is telling port 26 that when the button is pressed, it should turn the LED on as a status reminder that we are in command mode of the keyer.
Screen Shot 2015-08-07 at 10.57.57 AM


Below shows the result of pressing the first button, which is the command button. The LED which will be used, lit up when the button was pressed the first time and when off when it was pressed again. This is the expected behavior from the code changes that were made.

Screen Shot 2015-08-07 at 10.58.12 AM


Here is a schematic that I put together for the command and memory button with an indicator LED.


Screen Shot 2015-09-18 at 10.07.19 AM




Now that we have the command button in place, let’s add the speed control potentiometer to the project. There are three pins to these, a positive 5V, a ground and a wiper or analog input pin. The positive 5v pin will be on the left, the analog input in the middle and the ground on the right. Below shows the difference between the front and back of the potentiometer. The back has the notches in it where the front has the nomenclature of the potentiometer on it. Make sure that the front the potentiometer is pointing away from the buttons so that you know which is clockwise and counter-clockwise. Below is from the keyer_pin_settings.h file on a recommendation for this. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

Speed potentiometer (0 to 5 V) Use pot from 1k to 10k

Screen Shot 2015-08-07 at 12.32.36 PM

Screen Shot 2015-08-07 at 12.32.46 PM

When adding a real potentiometer for the real project, below shows the connections and where they connect to the potentiometer. Pin1 is 5v, pin2 is the input connection and pin3 is the negative or ground connection. There will be two potentiometers, so far, an LCD dimmer, and a CW speed control. If you are unfamiliar with adding a potentiometer, this URL has great information about that subject.

Screen Shot 2015-09-16 at 11.18.29 AM

As you can see from the clip of the schematic below, the potentiometer is going to be out CW speed control from 1 – 999 words per minute (WPM). I would be lucky to pick out 5 WPM at this point…lol. The left pin will connect to the 5v connection like the command button did.


Screen Shot 2015-08-07 at 12.49.14 PM


I have connected the positive lead to the 5v strip at the top. The negative side of the potentiometer is connected to the ground at the top as well. The wiper or analog input pin is connected to the Arduino Mega on pin A1. This will give us the speed control for the CW keyer.


Screen Shot 2015-08-07 at 1.06.11 PM


This should get us some operational speed potentiometer to help test our project. In order to get the command buttons to work, you have to uncomment the FEATURE_POTENTIOMETER and FEATURE_ROTARY_ENCODER located in the keyer_features_and_options.h file. If you forget this step, it will not work. If you uncomment this feature without the potentiometer in place, noise could falsely trigger WPM changes in the code. So now we want to make sure that the pin settings are set correctly in the keyer_pin_settings.h file. Below, I have chosen Analog A1 as the analog_buttons_pin. Once you have made the changes to the code, you can keep building or go ahead and upload to the Arduino Mega for testing. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

#define potentiometer A1




In order to test this project, it is a good idea to have a way to get sound to come out. In order to get the speaker to work within this project, there are no special FEATURE section for it. The only thing that came up with was going into the keyer_pin_settings.h file and changing the pin number for the sidetone_line to 48. You can use any pin you want, I chose this one out of the blue. If you forget this step, the side tones will not play. By looking at the part of the schematic that houses the speaker we can see that a 2N2222 transistor, a 0.1Mf capacitor and 2 x 100 ohm resistors are needed. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

#define sidetone_line 48         // connect a speaker for sidetone

Screen Shot 2015-08-07 at 1.33.07 PM


From what you can tell from the picture below, I have added the speaker section to the project. This includes the 2n2222 transistor, a single 0.1 microfarad capacitor, and two 100 ohm resistors.The 2N2222 transistor are standard NPN switching transistors and they need to be connected a certain way according to the schematic, in order for them to work properly. As you can see, the emitter is connecting to ground, the base is connected to a 100 Ohm resistor going to Pins 48 of the Arduino Mega. The collector is connecting to the positive side of the speaker with a .01 microfarad capacitor in between it and the speaker. From the 0.1 microfarad capacitor, we are making a connection to the Vin pin on the Arduino Mega. I have tested this circuit and even with the volume being really low, when I turn the command button on and off, I do here the on and off tones. One more thing, if you have a speaker connected and you upload a sketch, you will get tones back as a verification that everything worked.

Screen Shot 2015-08-07 at 2.59.47 PM


Revisions B on of speaker connection adding a terminal connector for easier removal. Add 1/8″ Jack for a speaker to connect to.





I pushed a little forward last night and build the keying sections of this project. There were some things that I learned from going through the documentation on the Radio Artisan Page about this. First off, don’t let the schematic fool you, the three connections called Tx Key 1 – 3 are not for adding on keys but are for connecting to multiple radio key sections. So essentially you can connect one to Kenwood, one to an Icom, and one to a Yaesu and have them all on different bands, working a contest. To me that would be confusing, but the prototype has that capability built in now. Right now as it stands when it comes to a key being added, if you look where it shows right and left paddle, that is you iambic key connections. This is not only for sending CW but for using CW to do things within the command section of the project, if wanted. In order to make sure that the keying sections are ready to go, you have to change the ports for the tx_key_line_1, tx_key_line_2 and tx_key_line_3 entries shown in the keyer_pin_settings.h file. I set mine to Digital pin 32, 34, and 36 as shown. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

#define tx_key_line_1 32       // (high = key down/tx on)
#define tx_key_line_2 34
#define tx_key_line_3 36

Screen Shot 2015-08-08 at 4.10.06 AM



In the below picture, you can see how I did a temp build using a secondary prototype board. This called for three separate 2N2222 diodes, three separate .01 microfarad capacitors, and three separate 100 ohm diodes. The 2N2222 diode are standard NPN switching diodes and they need to be connected a certain way according to the schematic, in order for them to work properly. As you can see, the emitter is connecting to ground, the base is connected to a 100 Ohm resistor going to Pins 32 for tx key 1, 34 for tx key 2 and 36 for tx key 3. The collector is connecting to the positive side of the jack with a .01 microfarad capacitor in between it and the jack.

Screen Shot 2015-08-08 at 4.29.10 AM

Screen Shot 2015-08-08 at 4.52.36 AM





The next item is fair simple and it is adding the paddles to the project in order to be able to do CW and to control the command section. Keep in mind that you do not have to use the cw key to work with the command section, you can implement the PS2 keyboard section if you want as well. From the schematic below, we can see that the only items needs for this are the left and right paddles, two .01 microfarad capacitors and two ports on the Arduino Mega. In order to make sure that the paddles will work properly, you have to change the ports for the paddle_left and paddle_right entries shown below in the keyer_pin_settings.h file. I set mine to Digital pin 42 for left and 44 for the right as shown. I would go ahead and press the compile button with the IDE to make sure these pins are set and ready.

#define paddle_left 42
#define paddle_right 44

Screen Shot 2015-08-08 at 5.02.46 AM

Revision B on Paddle key connection adding an 1/8″ jack to connect the key.





Now that we have the keying section complete, let’s look at the CW decoding section. This is an interesting section as it does not appear in the schematic above so we will be trying to integrate the circuit from OZ1JHM from their web site at The decoding is based on the Goertzel Algorithm and you can find more information at Who knew that there was math behind the decoding. ;-D

The code for the Arduino is included in this project, but the schematic, shown above in this post, appears to be for a basic build which we will be adding to. There is a file which was included with the code called goertzel.h. This takes care of all of the decode algorithm needed to make this work properly. There are some settings in which we need to make so that the Arduino Mega will work with this code. Below contains some information of interest from the goertzel.h file about the sampling frequency and bandwidth information.

Notes from the original code author, OZ1JHM (with edits from Goody K3NG)

GOERTZ_SAMPLING_FREQ will be 8928 on a 16 mhz without any prescaler etc., because we need the tone in the center of the bins you can set GOERTZ_TARGET_FREQ to 496, 558, 744 or 992 then GOERTZ_SAMPLES_INT the number of samples which give the bandwidth which can be 

(8928 / GOERTZ_TARGET_FREQ) * 1 or 2 or 3 or 4 etc 

init is 8928/558 = 16 * 4 = 64 samples                 

	try to take GOERTZ_SAMPLES = 96 or 128 ;o)    

	48 will give you a bandwidth around 186 hz            
	64 will give you a bandwidth around 140 hz            
	96 will give you a bandwidth around 94 hz            
	128 will give you a bandwidth around 70 hz  

BUT remember that a high GOERTZ_SAMPLES will take a lot of time so you have to find a compromise

As I do not have the Arduino Due, I have to comment out that part of the code and uncomment the part for the Arduino Mega, as shown below. There are setting that we need to pay attention to if the decode does not work properly here. According to OZ1JHM the Target Frequency should work with 558 hz or maybe 744 hz.

// Arduino Due (84 Mhz clock)
//#define GOERTZ_SAMPLING_FREQ 46872.0
//#define GOERTZ_SAMPLES 252 //168 //84

// Arduino Uno, Mega (16 Mhz clock)

#define GOERTZ_TARGET_FREQ 558.0  


In the snippet of schematic shown below, the SPEAKER IN will be from the radio or SDR which will go through a 100nf capacitor which connect to a 10k ohm resistor to the 5V connection and a 10k ohm resistor to ground. The circuit will connect to an analog pin on the Arduino Mega. This will allow the DSP decoder to show the inbound CW on the display.



Screen Shot 2015-09-16 at 9.37.32 AM


Screen Shot 2015-10-02 at 7.57.17 AM


Above shows the schematic that I put together for the decoder section to help break it out. As with the cw_decoder_pin, there is a cw_decoder_indicator as well. I added an LED between ground and PIN 24 connection which allows decoded flashes to be seen. This works real well in seeing what the threshold is in the tuning. There is fine tuning on the radio to start the decoding.

#define cw_decoder_pin A11 //A5 //A3  // if using OPTION_CW_DECODER_GOERTZEL_AUDIO_DETECTOR this must be an analog pin!
#define cw_decoder_indicator 24



LCD Display Add-On

As part of the CW Decoder project, you may want to add an LCD display for decoding incoming CW signals. Along with the GEORTZ DSP CW DECODER shown above, this works without an issue. There are some pinout changes that you will need to make in the keyer_pin_settings.h. This my keyer build I am using the following pinout. I am using a 4-bit 2 row LCD which is a good start.

//lcd pins
#define lcd_rs 38
#define lcd_enable 31
#define lcd_d4 33
#define lcd_d5 35
#define lcd_d6 37
#define lcd_d7 39

Screen Shot 2015-09-16 at 10.17.46 AM

In order to get the decoder to work just do the following:

  • Tune your radio to the CW portion of the HF bands. Usually the lower end of most ham radio HF bands.
  • If you want to test with beacons, go to 10 Meter, usually around 28.130 you may hear beacon stations.
  • Make sure that you have the LED connected between ground and the pin that you decided to use.
  • Tune in on a station until the LED starts flashing with their code send. You will have to fine tune  to get it correct but the LED will see the right data being sent.

Example #1 of CW Decode Test




Example #2 of CW Decode Test


I will be playing around with the above settings within the goertzel.h file to see if I can get a better decode. Correctly, the code is sensitive and there is a certain location to tune before it thinks about getting it correct, and I have noticed that if there are multiple stations close by, the decoder tries to do its best but has issues. For example, if I saw K9AJ as shown above sending his call and someone came up close by, the decoder would have issues with both and did not know what to do.

For example, last night there were multiple station around 14.039 where I assume an overseas station was located and it caused a mini pile-up on CW. I was able to tune around and decode the stations as they were sending their call signs, but when there are multiple stations at one time, the one that you are listening to seems to get lost in the decode. This is why I need to learn more code and not totally rely on the DSP decoder. This part of the project is fun to add on and fun to watch every now and then, but I can not use it as a replacement for code knowledge, which I did not plan on doing anyway.




Well, there are some more things to come, including drilling a case for the final project so that I can add the speed and LED contrast potentiometers, the power, decoder and command mode LED’s, the LCD Display, as well as the jacks for the TX keyer circuits, the jacks for the paddles and straight key (Needs Added), as well as power and USB connections to the Arduino. Still a lot to do, but I need to wait for a board or two to be built so that I can add to a case,



Links and References:



14 responses to “Arduino CW Keyer Project (Alpha)

  1. Wow. Good write up.

    I think you are confusing memory in the Atmel chips. They have three seperate pools of memory, Flash, Ram, EEprom. This page helps: and also

    There must be a dozen or more Arduino keyer programs on the internet. I looked at the K3NG code and decided it was way more than I needed. Besides I thought I had ideas for more efficient encoding of ascii to morse and vice versa so I started with KC4IFB’s iambic sketch and built from there.

  2. I hate to sound like a cheat, but do you happen to have a complete BOM for this project? I would love to build it, but my experience tends to be with kits.

  3. Thanks for the project details! I’m following along, and have ran into some things that others probably will as well.
    One thing to note is that the settings are saved in EEPROM, and aren’t cleared on upload. This created an issue while playing around with the unit as I built it as I would change features, and not be able to get it back. Once I realized what I was doing, I found a short sketch to clear the EEPROM.

    I now upload/run the clear sketch before I upload the keyer sketch. This kept me from pulling out my hair 😉

  4. This does not compile with me. It comes with a weird error which I never seen. It cannot find a .h (.cpp) file and I know is there.

    In file included from C:\Users\MyName\AppData\Local\Temp\buildeca4957436a2a35246de2c74e7b1fb67.tmp\sketch\libraries\Adafruit_RGBLCDShield\Adafruit_RGBLCDShield.cpp:17:0:

    Anyone seen this?

  5. 73,

    I started making the CW Key-er from “radio artisan” and since I wanted more features this page was recommended on their page.
    Nice project. Thanks for doing the work and changing pins and testing it.

    Couple of notes though, since I started doing this on Proteus CAD virtual environment (before I destroy real Atmega).
    – The circuit diagram with LED and command/memory buttons should not have a wire between pin 26 and 5V. That would destroy the Arduino. (It is not present on your breadboard).
    – Second, well just an observation, it is your blog after all, but when I saw the big diagram, I was taken by surprise, until I realized that it is actually Atmega2560 diagram and I will not need all those parts :). They are already on Atmega2560. Phew! Back on track.

    Thanks again.

  6. Looks like a well presented article and work.
    I used an Arduino Uno to build a Morse practice receiver and sender and basic keyer. It has lots of features for receive practice. Quite basic for sending. No switches involved. Requires usb connection to computer for receive practice but not for sending. Email me if interested in seeing the code and very simple circuit.

  7. Thank you for your efforts in this write up and project. I have bookmarked your page and I am sure that I will be coming back very often to reference your page. Your pictures and clear descriptions are greatly appreciated. Please continue with your great work and helping everyone.

  8. Some truly excellent posts on this internet site, regards for contribution. “The key to everything is patience. You get the chicken by hatching the egg, not by smashing it.” by Arnold Glasgow.

  9. Hi,
    Thank you for your detailed description and I also want to build this keyer.
    I have a question about the transmitter key connections:

    You write:

    The base is connected to a 100 ohm resistor going to pins 32 for tx key 1, 34 for tx key 2 and 36 for tx key 3.
    Do you mean the Arduino 2560 MEGA connections on the side numbered from 31 to 53?

    Hope that I get someone’s answers,
      Greetings, Cees, PA3CVI

Leave a Reply

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

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

Twitter picture

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

Facebook photo

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

Connecting to %s