Simple Keyer

Here's a fun project. Not only is it easy to build and cheap, it's versatile and is a dream to operate. Many new QRP rigs have no keyer so won't operate with a paddle but this unit is small enough to install within most any enclosure. If you want, you can use it as a stand-alone unit. You can build it for under $2 with all new parts or, since it is easy to modify, make it as fancy as you want.

I used a Microchip® 12F675 micro-controller, my favorite. Like the 2N2222 and the LM555 they are common, cheap (less than $1 in single lots), and versatile as the dickens. Among other features, they have an internal clock oscillator, Analog-to-Digital converter, a programmable comparator, two sets of timer/counters with prescalers, and six input/output pins! All in an 8-pin plastic package like the '555.

To make matters even easier I wrote the program in Assembly. A mere 43 bytes. Not Megabytes, not Kilobytes, but just bytes. Straightforward, small, simple. Assembly language is simpler than any other and is so close to the machine code that the processor uses that you don't even need a compiler program. It consists of mnemonics as commands that help you read the source code and which translate directly to machine code. You are working down at the level where things are getting done. Just what home-brew is all about, right? This is where logic reigns. Nothing hidden behind the curtain. There is no programming language faster or more compact than Assembly.

Why not program it in C? Most everything is now done in that programming language or its variants. The plain answer is that I have never been able to learn C to where I could do projects like this. Object Oriented Language confuses me. Sorry. As a result, all of my projects are simple.

For the last ten or fifteen years (who's counting?) I've been using the Microchip® IDE (Integrated Development Environment) , MPLAB® which came with my PicKit 1™ programmer.[1] It's a free download, too.[2] In it is are all the tools you will ever want. I have no idea what most of them are, no need.

Instead of using the convenient internal system clock oscillator, I chose an external R/C (resistor and capacitor) control. By using a small fixed capacitor and a variable resistor I can adjust the keying speed smoothly and simply, at the twist of a knob. No menus. Just reach up and turn. But wait! There's more! Since that control is actually changing the micro-controller clock speed it also changes the sidetone audio frequency. As the speed increases, so does the sidetone frequency. It makes it easy for me to instantly intuit the keying rate.


The source code, “Keyer.asm”, is just a text file. You can open and edit it with any text editor if you wish. Comments begin with a semi-colon and are ignored by the assembler program. I use them to organize the code, explain things, and to separate it into sections for better clarity.

You can download it by clicking HERE.

The first block is program notes. The second is a block of directives for the assembler, identifying the micro-controller type, telling it to include a file containing a host of variable definitions that accompany that micro-controller, telling it to suppress some error messages that I don't need, and to apply the device configuration for this project.

To save time and effort I make up an “empty” source file template for each type chip. It has the block of directives, including the “Configuration Word” text string which I edit as needed, and other blocks empty and waiting to be filled. Very similar to making an outline for an article and then filling it in: Once you have it filled in, then your program is written! Magic.

The “Definitions” block tells the assembler what addresses are to be associated with which labels I have created and notes to clarify which pins and such to which I am referring.

The “ORG” command tells the assembler where in program storage to start putting the machine code. This is where the micro-controller will actually start doing things when first awakened. This is the starting point.

The “INITIALIZE” block of code clears registers (memory locations) just in case there is anything accidentally left in them that might interfere with what we want to do. We then turn off the internal comparator functions to conserve power and we enable the Weak Pull Up function on the two paddle inputs. This takes the place of external resistors to supply voltage, so the pins have a “high” state waiting to be pulled “low” by the paddle contacts. After disabling the internal voltage reference to further save power, we then configure all input/output pins as digital since we don't need a high impedance nor any A/D operation. Finally we set up the two output pins as outputs, the rest as inputs. Yes, you have to tell it EVERYTHING. It's not smart but it is fast and reliable.

Now the Main portion of the program. TaDah! Five whole lines. We look for a low on the “dah” pin and if there is one then we jump to the routine that makes a dash. If the “dah” pin isn't low then we look for a low on the “dit” pin. If there is a low there then we jump to the routine that outputs a dot. If not, then we just do it all over again. My kind of program.

The “DOT” and “DASH” routines start with sending a state change to the OUTput pin to provide keying to a transmitter (if you have one connected). Then they load the proper timing constants and jump to a subroutine that produces a side-tone for the SPKR pin, returns the OUTput pin to the idle state (to unkey the transmitter), and adds a delay for that element.

Download the datasheet on the 12F675 [3] and go to the Instruction Set Summary to see what those assembly commands mean. Notice that I don't use many of them, there are only 35 available and I didn't need but a third of those. Simpler than BASIC.

Follow the directions included with whatever assembler and programmer that you have so as to first assemble the machine code and then upload it into the chip. I always like to verify the load just to make sure that I did everything correctly. The chip is now ready to use.


Before installing it on a circuit board you might wish to test it on a “whiteblock” style solderless prototyping board. Yes, this will work nicely since this isn't RF and the stray capacitances of the board don't matter here. Test your parts and experiment before commiting to solder. I usually install a socket in my project. That way I can experiment with it later without de-soldering. Who knows? I might want to add features.

It may not be needed but I find that a .1 uF bypass capacitor (C2) between pin 1 (VCC) and pin 8 (GND) is generally a good idea. Also R1, although optional, will set the maximum code speed and keep the user from accidentally shutting down the oscillator. R1, R2, and C1 set the speed but you can also change the three values in the source code. Notice that the “DASH” value is three times the “DOT” value. Like I say, logical. Adjust the element spacing to suit, it has timing differences involved, so just use a bit of trial-and-error to fine-tune it.

The sidetone output doesn't usually need C3 to block the DC but it is good practice to put one there. R3 is optional. You might not even want to use the sidetone output, just that of the rig that you are driving. Or, perhaps, you might want to mix it into the audio of whatever you are keying. I have used it to drive a speaker directly in a code practice oscillator (discussed later).

The output pin, #7, drives a 2N7000 or some other NMOS FET like a BS170. Or, if the rig that you are keying requires less than 20 milliamps and low voltage, you could eliminate Q1 entirely. If it requires a “low” state to key, then invert the logic to the OUTput by changing “BSF” in the DOT and DASH routines to “BCF” and changing the “BCF” at the fifth line of the element sending subroutine “ELSND” to BSF. This program is both simple and flexible.

Power it with two to five volts. I usually use a couple of AAA cells if used as a stand-alone or run it off of an existing 5 volt bus or a 78L05 within a rig. It draws very little current depending on what you are driving with it.

Aside from installing this keyer in home brew rigs, I usually keep one around that is in an Altoids® tin (what else?) with batteries, a speed control pot with power switch, and 3.5 mm jacks. Works fine as a temporary keyer when I need one.

I also installed one in a wooden craft-store box for a friend. He uses it for off-air practice and as a temporary keyer. It just has more class than the Altoids® tin. That, and a speaker out the bottom

There you have it. It's smaller, cheaper, and simpler than an Arduino®. A bit harder to program but once you have the programmer set up then you can knock off several of them in a few minutes for friends or club members. There are so many things that you can do with PIC chips that you will never regret familiarizing yourself with them. Then share what you find with the rest of us. Much too much fun.

de ND6T

[1] A link to a PicKit 1 seller:

[2] The link to MPLAB® download:

[3] The link to the 12F675 datasheet:

Return to Home