Posts Tagged ‘ morse code ’

Arduino Iambic Keyer 2016 – Part 1: Hardware

Third Generation:

Arduino Iambic Keyer - Top

Arduino Iambic Keyer – Top


Arduino Iambic Keyer - Left Side

Arduino Iambic Keyer – Left Side


Arduino Iambic Keyer - Right side

Arduino Iambic Keyer – Right side


In a Chicago winter it’s way too cold in the garage for woodworking, so I turn to coding to pass the time. In 2014 I built an ATTINY85 Morse Code keyer in an Altoids Small box and in 2015 I expanded that with an Arduino Pro Mini based keyer in a regular Altoids tin. It was a lot of fun and consumed pretty much the whole winter. I’ve written down a few ideas for enhancements and in this year’s model some of those are implemented. The hardware wish list (so far):

  1. Battery power, enabling stand alone operation > 24 hours
  2. LCD display 16×2 minimum
  3. Real Time Clock, Local and GMT
  4. More memories (7 or 8 buttons)

Batteries and LCD won’t fit in an Altoids tin. I found a metal Crayola box at Tuesday Morning. It was made by the Tin Box Company, who produce many designs that would make interesting project enclosures. It is 3″ x 5″ x 1.5″, about three times the volume of an Altoids box, the metal is slightly sturdier than Altoids but still flimsy enough to be difficult to work without distortion. I found the inside surface was coated with a thin layer of something which repelled solder unless sanded a bit first. I don’t see this particular box available any more but there is a slightly larger version. My experience indicates that the time to complete a project is inversely proportional to the size of the enclosure (maybe to the fourth power).

Unmodified Crayola Box

Unmodified Crayola Box


These days “Arduinos” come in many shapes and varieties. The latest official 1.6.7 IDE is almost 100 megabytes, expanded to accommodate different versions.  I wanted to try processors other than the standard ATMEGA328, so last summer bought a Teensy2.0 (32u4) and a TeensyLC (ARM Cortex M0) made by PJRC. Both promise built in USB client support. The PJ in PJRC is Paul Stoffregan, who has contributed a great deal to the Arduino community. There’s an IDE add-on “Teensyduino” that must be downloaded from the PJRC site to use Teensy boards. Teensyduino installation is dead simple and includes Teensy versions of most familiar Arduino libraries plus a few useful additions from Paul.

Last summer I worked with the Teensy2.0 a bit, wanted to see if the DDS sine wave generation function I used in the 2015 design would work. The port was successful, the 32u4 required only a few minor tweaks, and I even got Fast PWM working as described in Atmel’s documentation. PJRC has a forum where you can brag about your accomplishments so I wrote something on the 32u4 DDS sketch thinking it might be useful to others. Paul Stoffregan replied suggesting I consider a Teensy3.2 as it has an integrated Digital-Analog Converter which would produce a cleaner waveform. I fired up the similar TeensyLC and used Paul’s suggested method. DDS on the TeensyLC was also successful so I built a breadboard version of last years keyer using the LC.  Everything worked with PJRC’s libraries including DDS side tone, the PS2 keyboard, and lcd.prints added for the display.

The small module at the upper left of the breadboard is an Adafruit PAM8302 audio amplifier. Last year I struggled with a 1 transistor class A amp for the speaker, gave up on that and built an LM386 design. The PAM8302 amp at only four bucks is clearly a winning choice. The only problem I had was later on I discovered the Output side did not like being grounded and I had to insulate the external speaker jack.

First Breadboard - TeensyLC

First Breadboard – TeensyLC


TeensyLC has one serious limitation for my application. Because the ARM chip handles flash differently than the MEGA328, TeensyLC has only 128 bytes of emulated EEPROM. That meant limiting stored button memory to four messages only 30 characters each. At that time I was thinking about adding a Real Time Clock so looked at getting Adafruit’s FRAM breakout and their DS1307 RTC. But for less money than these two modules plus a TeensyLC I could get a Teensy3.2 module with a Cortex-M4, lots of memory, built in RTC, and 5 volt tolerant inputs. I sent off an order to Adafruit (10% off if you watch “Ask An Engineer”).

Teensys have lots of I/O pins, same spacing as the LCD modules, so I elected to mount the Teensy board directly on the LCD.  One 3 pin header and one four pin header is needed. In the next photo you can see the headers with two short gray spacers to separate the PC boards. I had to flatten one of the LCD bezel mounting tabs for clearance but the mount is very compact and rigid. Note to self: make sure you don’t need any more connections to the bottom of the board before soldering down the headers.

I had the idea to use a software driven flashing LCD back light to indicate a flat battery. ARM I/O pins are limited to 9 milliamps each, not enough for an LCD back light so a 2n2222 transistor was glued in to act as back light current switch. The trim pot on the right is for adjusting LCD contrast. It is across the back light LED pads, did not work out well, as later in development I am PWMing the 2n2222 to get adjustable back lighting. So the trim pot has been moved up on the LCD board, epoxied in place, and hard wired to ground and +3.3 volts.

Teensy3.2 Grafted on to LCD

Teensy3.2 Grafted on to LCD


The two wires leading off the right end of the Teensy go to a CR2032 backup battery for the Real Time Clock, and you can just see the Adafruit 32KHz crystal added on the bottom of the Teensy. With this minimal configuration I was able to test and experiment with the built in RTC using the example program furnished with the PJRC Time library, modified with LCD prints.  Initially setting the clock was a problem, you need to send a “T” followed by Unix time (seconds since 1970) into the serial port. I worked out this Linux incantation to get the proper format for Central Standard Time:
echo T$[`date +%s` – 6 * 3600]

Then copy “T1453151560” and paste into the Arduino serial window.  Once the clock has been set it takes care of itself though I’m not sure how. I believe it reads and sets time from code uploaded from the compiler. The Time library is more than a little obscure.

Clock Testing Processor/LCD Sandwich

Clock Testing Processor/LCD Sandwich


Of course many wires have to be added to interface Teensy with the rest of the keyer. It’s not so neat looking now, I’m using nearly every I/O pin plus power from the built in 3.3 volt regulator. I use mostly 24 gauge wire, solid if connecting to other points on the lid, stranded if routing to points below. I have an old Ungar fine tipped soldering iron plugged into a Variac set to about 70 percent.

Processor/LCD With Necessary Wiring

Processor/LCD With Necessary Wiring


There are three auxiliary perf boards in the design, One mounts seven memory switches, another holds volume control, transmit LED, and the Function button, the third has clock battery and an optoisolator for transmitter keying. These boards were carefully laid out on paper, then cut out and marked up so mounting holes could be located. Working with a hinged lid box you have to be careful to leave extra clearance for the lid to close. I did have to file a bit off the button board and the speaker.

The box needs a couple dozen holes to mount parts. Blue tape was applied to all surfaces, a layout drawn on the tape, then all holes center punched.  I start with my smallest drill bit in a drill press then enlarge 1/64 at a time to final size.  A few holes required fine tuning with a tapered reamer.  I made a rectangular cutout for the LCD bezel by using a wooden template screwed to the lid, then cutting with a 3/16 carbide router bit surrounded by a 1/4″ collar. Mounting hardware is mostly 2-56 with a few 4-40 spacers.

Crayola Lid Drilled

Crayola Lid Drilled


I had a pair of paralleled 18650 cells taken from a cell phone charging pack. These are fastened in the box by a strip of tin can metal soldered in, and restrained by an angle bracket soldered at one end. The small speaker was taken from a defunct IPod dock. In the next photo, most of the lid components are mounted. The small audio amp board goes on the two screws at right center of the lid, mounted mezzanine style.

Box Lid Components Mounted

Box Lid Components Mounted


Next is a close up of the batteries with 2 amp fuses soldered in both plus and ground leads. Also see three stereo jacks at the right side for Key/Audio Out, External Speaker, and Paddles In. You can see in the bottom three long #2 screws for mounting the third perf board and Adafruit boost/charger. Most board mounting screws have three nuts; one to secure the screw, one to support the bottom of the board at the proper height, and a third to secure the board against the second. Thank heaven I still have a Heathkit nut starter.

Mounted 18650 Cells with Fuses in Both Leads

Mounted 18650 Cells with Fuses in Both Leads


At the right side of the box there is a power switch, PS2 jack, and a micro USB jack breakout. The power switch does not actually switch power, it grounds the Enable pin on the charger board which turns off the boost converter.  That allows charging to continue while the rest of the unit is off.  Later in debugging the hardware, I added bypass capacitors to that switch and a separate wire to the Enable pin on the audio amplifier which suppresses a weird sequence of sounds from the speaker on powering off. The PS2 jack leads wouldn’t reach the processor board so they route to the third perf board and get jumpered there to stranded wire headed for the Teensy.  It’s getting hard to find a real PS2 keyboard but the software works fine with a USB keyboard plugged into a USB/PS2 adaptor.

Power Switch, PS2, and USB Connectors

Power Switch, PS2, and USB Connectors


This is a good place to register a complaint. I bought the Adafruit PowerBoost 500 board to manage the battery. It charges from 5 volt USB in and boosts from the 3 volt battery, seamlessly switching sources when you pull the USB connection. It does NOT however pass through or even break out the two USB data pins from the micro USB input jack. The only way to actually use USB while charging the battery is to wire out the D+ and D- leads outside the board. Adafruit support suggested doing this by cutting up a USB cable. I was able to route the micro USB breakout data leads (Green in the next photo) to the processor and the incoming positive and negative supply leads to the PowerBoost using a plug from an Adafruit micro USB connector (red and black in the photo). An extra $2.50 in parts that wouldn’t have been needed if Adafruit had only provided pads on the PowerBoost for D+ and D- or better, added two traces to route the data signals from the input connector to the output connector.

Detail of the Hacked USB Connection

Detail of the Hacked USB Connection


One more issue with the PowerBoost. It has a nice pair of status LEDs (where it says CHRG) yellow when charging and green when fully charged. These operate from a single pin on the charger chip but that pin is not broken out and you can’t of course, see the LEDs when the box is closed. I added a wire (gray, leading off to the right in the photo) to the common side of the LED dropping resistors so I could have the Teensy display charging status on the LCD.  Not difficult but would have been nice to have official access to that chip pin.

The keyer has four monitoring leads between the PowerBoost and the processor. Besides the status signal mentioned above, I wired up the LowBattery pin and USB (power).  USB activates the Status signal which is only valid when USB is plugged in and receiving power from the host.  LB goes low when the battery is REALLY flat (3.25 volts I think). I also wired the BAT pin to the Teensy A10 analog input through a 10k calibration pot so software can read and display the battery voltage. You can see the calibration pot at the bottom of the board in this photo.

TX board, PowerBoost with Voltage Cal Pot

TX board, PowerBoost with Voltage Cal Pot


The next photo shows how I insulated the External Speaker jack by opening up the mounting hole and screwing a small piece of Lexan to the box. The plastic had to be counterbored so the jack mounting nuts would fit.

Output Jack Insulation

Output Jack Insulation


Here is a close up of the box lid interior. You can see the LCD contrast pot which is glued to the LCD, perfboard for the LED, volume control, and Function button. Two screws and a couple of spacers mount the PAM8302 audio amp on top of the LED board.

LCD Contrast, Audio Amp

LCD Contrast, Audio Amp On Top of LED Board

Here is the completed keyer opened up. Clockwise from top left, I/O stereo jacks, 18650 batteries, memory button board, Teensy3.2 processor on top of 16×2 LCD display, LED board, speaker, on/off switch, PS2 keyboard jack, USB input jack, PowerBoost charger/boost converter, and the transmit interface board.

Keyer Internals

Keyer Internals


An Eagle schematic diagram of this project can be downloaded from:

Keyer 2016 Schematic Version 1

Keyer 2016 Schematic Version 1


Revision History

February 25, 2016       MemoryKeyerTeensy3.2_V1.0    Initial sketch
March 9, 2016             MemoryKeyerTeensy3.2_V1.1.0  Rework battery alarm logic, bug fixes.
March 16, 2016           MemoryKeyerTeensy3.2 V1.1.1   Workaround fix LCD does not have backslash in its font.

Arduino Iambic Keyer 2016 – Part 2: Software


The 2016 version keyer hardware has four additions that require software support; more memory buttons, stand alone battery operation, Real Time Clock, and the biggest change a 16 character 2 line Liquid Crystal Display.

Additional memory buttons need:

  • Expansion of button scanning while in operation
  • Expansion of button programming
  • Addition to default messages
  • Consideration of potential uses while not in operation

Battery and associated (PowerBoost 500c) charger/converter need:

  • Charge status monitoring
  • Discharge status monitoring and alarm
  • Work out how to turn the unit off while charging

The Teensy3.2 built in Real Time Clock will need:

  • Ability to read hardware clock and convert to display friendly form
  • Ability to set hardware clock when in stand alone mode
  • Display GMT and Local time and date
  • Desirable: sync hardware clock over serial from PC

Stand alone operation requires all information displayed on the LCD as well as the serial port.
This will require:

  • Battery charge/discharge status
  • Keyer parameters, speed and side tone frequency
  • Time and date
  • Desirable: manage the LCD backlight

A link to my sketch is at the end of this article.

Following is a description of some things I learned writing this code.

Event Loops

When I first looked at KC4IFB’s Iambic code I couldn’t see how it worked. But after a fair amount of study and experimentation (see my instrumented version) I now understand and use event loops often, avoiding delay() whenever possible.  In an Arduino sketch loop() is an event loop. It just spins forever waiting for something to do. Code entered within loop() is repeatedly executed, like scanning an input pin for a button press which sends in a ground.

Why avoid delay()? Because it stops all sketch processing until it times out. Better to use the timer to trigger an event asynchronously at the current time plus a delay interval. Let loop() continue to spin, watching over the rest of your code. An example might be:

unsigned long trigger1k;
unsigned long trigger5k;
unsigned long currentTime;
void setup() {}
void loop() {
currentTime = millis();
if (currentTime > trigger1k) {
   < do stuff every second >
   trigger1k =trigger1k + 1000;
if (currentTime > trigger5k ) {
   < do stuff every five seconds >
   trigger5k = trigger5k + 5000;

This would not work well with delay(1000) and delay(5000) in place of the time triggers.

You can roll your own event loops. I’m doing this often in the keyer sketch. Just set up your own infinite spinner:

while (true) {
  < code executed until a break; is seen >

The C statement break: exits the while loop. You can make event loops inside of event loops but more than two levels gets very difficult to debug.


Stupid Switch Tricks

I used the “C” switch statement a lot in this years update and thought I would document some of the ideas.

Leading Zeros

This is a function to print 2-4 digit numbers with leading zeros. It can also be used to right justify a number by changing “0” to ” “. Note there are no break statements in the switch, it is entered at a point determined by “digits” then falls through all succeeding statements.

 Just to get leading zeros on up to four digit integer
 arg k is variable to print
 arg digits is # places to use
 void lcdPz(int k, int digits) {
 switch (digits) {
   case 4:
     if (k < 1000 ) lcd.print("0");
   case 3:
     if (k < 100  ) lcd.print("0");
   case 2:
     if (k < 10   ) lcd.print("0");


Building a Menu with Switch

I gave a lot of thought and time to how I could do stand alone update menu system.  The menu loop is entered if the “FUNCTON” button is down when the processor boots up. Teensy3.2 does not provide easy access to the reset pin so my workaround is just switching power off and on.

In this bit of pseudocode, the switch statement just displays menu options. Pressing the “ENTER” button while a specific item is on the LCD selects that menu item for updating. I use a separate function to actually implement specific item updates but that could be done in line.

while (true) {             // Event loop
  Mtime = millis();
  if (MTime > nextMenuTime) {
  nextMenuTime = MTime + 1500; // New menu item trigger  whichMenu = (whichMenu + 1) % 8; // Counts 0 to 7
  switch (whichMenu) {
    case 0:
      < display first menu item >
    case 1:
      < display second menu item >
etc. etc.
    case 7:
      < display seventh menu >
  }        // End of switch statement
if ( < SELECT button is pressed > ) {
 < menu item# whichMenu is selected,
    do something about it  >
}           // End of while() loop


Selecting Columns to Update

One particular problem was how to update the clock time and date. Time is displayed on the LCD as HH:MM:SS so how to click through that and change individual digits? I decided to only increment or decrement the ones digits so the second “H”, the second “M”, and second “S” digits are the only targets. I can skip everything else. Two buttons were designated as “up” and “down” and I wrote a function that returns 1 if “up” is pressed, -1 if “down” is pressed, zero if neither.

Using switch() to select the appropriate digits on the LCD easily allows skipping over columns.

case 3:                            // Set GMT time

 Ltime = now();                    // System time snapshot
 // Convert snapshot into simpler variables for display
 Lhour = hour(Ltime);              // Need the date as well
 Lmin = minute(Ltime);
 Lsec = second(Ltime);
 cursorPos = 0;                    // Start at first position
 lcd.cursor();                     // So you can see where you are
 lcd.setCursor(0, 1);
// Walk the cursor down the displayed time
 while (true) {                    // Start event loop

   Action = upDown();              // Up or Down pressed?
   if (Action != 0) {
     delay(150);                   // limit speed of change
     Changed = true;               // Flag something was changed
switch (cursorPos) {
   case 0:                       // Hours tens digit
     cursorPos += 1;
   case 1:                       // Hours ones digit
     Lhour = (Lhour + Action) % 24;
   case 2:                       // Ignore the colon
     cursorPos += 1;
   case 3:                       // Skip Minutes tens digit
     cursorPos += 1;
   case 4:                       // Minutes ones digit
     Lmin = (Lmin + Action) % 60;
   case 5:                       // Ignore the colon
     cursorPos += 1;
   case 6:                       // Skip Seconds tens digit
     cursorPos += 1;
   case 7:                       // Seconds ones digit
     Lsec = (Lsec + Action) % 60;
 }                               // End of switch
if ( < ENTER button pressed > ) { 
   cursorPos = (cursorPos + 1) % 7;//  Move to next digit
if ( < EXIT button pressed> ) {
  < Write changed time to the system clock >
  break;                         // Jump out
  <  redisplay the time on LCD >
 break;                        // Exit the while()

Revision History

February 25, 2016      MemoryKeyerTeensy3.2_V1.0  Initial software
March 9, 2016            MemoryKeyerTeensy3.2_v1.1.0 Rework battery alarm logic, bug fixes
March 16, 2016           MemoryKeyerTeensy3.2 V1.1.1   Workaround fix LCD does not have backslash in its font.

Arduino Iambic Keyer 2016 – Part 3: Operation

Memory Keyer 2016

Arduino Iambic Keyer - Keyboard and Paddles

Arduino Iambic Keyer – Keyboard and Paddles


This describes the operation of an Arduino sketch and appropriate hardware that serves as an iambic morse code keyer. This version runs on a PJRC Teensy3.2 board and libraries. It will not compile to an Atmel (traditional Arduino) processor without major changes. I chose the Cortex M4 based Teensy because it has built in Real Time Clock, a real DAC, built in USB, and lots of memory. I added a 16×2 liquid crystal display and batteries for stand alone operation.


  1. Characters to be sent are buffered in an asynchronous circular queue so memory buttons or keyboard characters can be “typed ahead”.
  2. PS2 and serial terminal keyboards supported.
  3. Paddle generated morse is interpreted and printed as ASCII text.
  4. Seven 50 character memories. Each is programmable from keyboards or from paddles.
  5. Random code practice modes, letters only, letters and numbers, letters numbers and punctuation.
  6. Sending speed settable 10 to 45 WPM. Limits can be changed by recompiling.
  7. Sidetone frequency settable 100 to 1200 Hz. Limits can be changed by recompiling.
  8. Synthesized sine wave sidetone with leading and trailing edge envelope shaping.
  9. Memories and operating parameters stored in EEPROM, are easily reset to defaults.
  10. Stand alone operation from batteries. Based on tests, a 4400 MAH battery will last at least 36 hours.
  11. A Liquid Crystal Display.

Outside the Box

This keyer has five I/O connectors:

  1. A 3 conductor jack for the paddle or straight key.
  2. A 3 conductor jack for transmitter keying with an optocoupler open collector output on the tip. Line level sidetone audio is connected to the ring.
  3. An external speaker jack connected to a 2.5 watt audio amplifier.
  4. A mini DIN connector for PS2 keyboard. USB keyboards will work with an adapter.
  5. A micro USB port for programming and serial terminal connection. This also powers the unit and charges the battery.

There are eight push button switches, a volume control, and an LED:

  1. A Function button.
  2. Seven push buttons to activate individual memories.
  3. The volume control feeds a Class D amplifier for the speaker. It does not affect the level on the line output connection.
  4. The LED follows the transmit keying signal.

There is an on/off switch that also serves to reboot the processor into setup mode.

Liquid Crystal Displays have a limited space for messages so information has to be presented sequentially. Switching on power displays clock status then “Keyer Ready” is displayed on the LCD and on the serial port. The unit is then ready for normal operation.

Straight Key Operation

On power up, if the unit senses a two conductor plug in the paddle jack, it will go into Straight Key mode and just pass keying through to the transmit circuit, with side tone. Memories and other features are not available as the morse engine is never started.

Normal Iambic Operation

The dual paddle jack is wired dit paddle on tip, dah paddle on ring of the mini stereo connector. The external speaker jack will work with stereo headphones or a speaker. On the transmit jack, there is an open collector optocoupler connected to tip and line level side tone on the ring.

Software will attempt to translate paddle sent morse into ASCII which will display on the LCD and is also sent to the serial port. Decode success depends on how good your fist is. The keyer cannot decode morse received over the air.

Keyboard Operation

The keyer will accept and send characters entered from a PS2 keyboard or from a terminal emulator program such as PuTTY, or even the Arduino IDE serial window. It’s better to use an emulator that supports line at a time transmission as that gives you an opportunity to fix typing mistakes. Opening a terminal window on a USB connected PC also lets you view and log status messages sent from the keyer. PS2 support also works with a USB keyboard and appropriate USB to PS2 adapter.

All characters in the Wikipedia morse code table are supported except the underscore and the dollar sign. From either serial or PS2 keyboards, enter normal text in lower case. Entering text in upper case will suppress the next intercharacter gap, thus running two characters together. This can be used to send prosigns. For example, As (wait) or Sk (end of contact). Message text entered from the paddles will always be treated as all lower case.

Serial or PS2 keyboards use a one at a time command mode, activated by typing a back slash followed by a single character. Keyboard commands are:

  1. \+ or \= increase sending speed one Word Per Minute
  2. \- decrease sending speed one Word Per Minute
  3. \u increase sidetone frequency by 5%
  4. \d decrease sidetone frequency by 5%
  5. \w save current sidetone frequency and WPM to EEPROM memory
  6. \1, \2 … \7 send stored text as though a memory button was pressed.


Seven programmable 50 character memories are available by pressing buttons. The sketch uses a 64 byte circular buffer to queue sendable text from either keyboard or from EEPROM memory, the buffer is asynchronous so memory messages can be stacked with interspersed keyboard text. Memory messages are read as needed from EEPROM so each consumes only a single byte of circular buffer space. Memories can also be queued from the keyboards by entering commands \1 … \7.

Message memory can be programmed from compiled defaults, from either keyboard, or directly from the paddles if your sending is good which is useful in stand alone operation. To program a message into memory, press and hold the Function button, then press and release the desired memory button, then release Function. Enter your text from paddles or keyboard, then exit programing mode by clicking Function again.

Normal Operation Display

Operating parameters can be viewed on the LCD by holding the Function button. Parameters also print to the serial port. The rotating menu display will show:

  • Time and date both GMT and local
  • Sending speed and side tone frequency
  • Battery status
  • The first 16 characters of each programmable message.

Each item will be on the LCD for one second. Releasing Function stops menu rotation but does not erase the LCD which allows more time to read a particular display.

Changing Words Per Minute

Since speed may need to be adjusted according to conditions, there is a provision to change WPM on the fly. Just hold the Function button down and close a paddle. Dits increase speed, dahs decrease. On releasing Function, the changed speed writes to EEPROM.

You can also change speed from the keyboards by entering \+ to increase or \- to decrease. Entering \= will also increase WPM if you forgot to shift. If adjusting by keyboard, you must enter \w to write the new setting to EEPROM.

Changing Side Tone Frequency

This can be done from the keyboards by sending \u to raise frequency or \d to lower frequency. As with WPM, enter the command \w to save the change. Tone frequency can be set in stand alone operation from the Startup Menu described below.

Battery Status

Software constantly monitors battery voltage and the PowerBoost charger status signals. These can be seen in the operating display. Voltage is shown in hundredths with no decimal point. A fully charged battery will show about 4.20 volts, if the battery drops below 3.40 volts “LOW BATT” will show on the battery status and the LCD back light will flash. If voltage drops below the boost regulator LB threshold, about 3.25 volts the status display will show “DEAD BATT”.

Startup Mode

Arduino sketches have a separate startup() section for initializing things. It is executed once when the processor resets, just before entering the main event loop(). This keyer takes advantage of separate startup to recall and optionally change important system parameters. A normal power on sequence copies the following items from EEPROM to RAM:

  • Words Per Minute
  • Side Tone frequency
  • LCD Back light brightness
  • GMT – Local time offset

Memory messages are also stored in EEPROM but are not read into RAM. Startup then reads the Real Time Clock into the system clock.

Startup then checks to see if Code Practice mode (see below) is requested, if so, Code Practice begins as soon as the memory button is released.

Startup Menu

If Startup sees the Function button held down, it enters Startup Menu mode. Eight parameters rotate on the LCD, seven of these can be entered and changed.

  1. Sending speed Words Per Minute
  2. Side Tone frequency
  3. LCD Back light brightness
  4. System clock time (GMT)
  5. System date (also GMT)
  6. GMT – Local offset in hours
  7. Reset all stored parameters to defaults
  8. Display battery voltage and charge status

For Startup Menu purposes, three of the memory buttons are redefined. M5 is Enter, M6 is Up, M7 is Down. Click the Enter (M5) button while a menu item is on the display to activate change mode for that item. For the first three menu items and for GMT offset, Up (M6) and Down (M7) act directly on the displayed number.

Once entered, Time and Date can be set by repeatedly pressing the Enter button until the cursor is beneath the digit needing change. Once there Up and Down operate as expected. The RTC will be updated when the Time or Date menu is exited.

After a change, exit the menu item by pressing and holding Enter (M5) for longer than 2 seconds. Menu rotation will continue where it left off.

Entering menu 7 will reset all EEPROM stored parameters including the seven memory messages to defaults specified in the file “canned.h”. You can change these defaults by editing that file with the Arduino IDE and recompiling. Canned.h appears as one of the tabs at the top of the Arduino editor window.

The last Startup Menu display shows the current battery voltage and charge status. This information is also sent to the serial connection, at the menu rate of rotation, about five times per minute. A terminal emulator program like PuTTY or Minicom on the PC, can log these battery messages in a text file, you can later load the text into a spread sheet and with some amount of fussing create a charge or discharge curve for the battery. To get a discharge curve though you have to disable charging through the USB connection by cutting the red wire in the USB cable.

Startup Menu mode is exited by clicking the Function button again. Changed parameters will write to EEPROM and normal operation starts.

Synchronize the Real Time Clock

Internal system time is maintained by software in the PJRC libraries. System time is initialized at bootup from the crystal controlled, battery backed Real Time Clock inside the processor chip. You can hack set the RTC from the Startup Menu, but there is a way to synchronize the RTC with a PC clock over a USB serial connection. If the PC is itself synchronized with an Internet NTP server, the result will be within 1 or 2 seconds of WWV.

Accurate clock synchronization requires the Arduino sketch be ready to accept and process a time update at the exact moment the PC sends it. Connect the keyer to the PC with a USB cable, power up the keyer while holding the Function button down, then while the LCD displays “Enter Setup Mode”, paste the following Linux command into a shell;

date +T%s\n > /dev/ttyACM0

Release the Function button and the RTC synchronizes. There is a processing sketch included with the PJRC Time library that can be used to synchronize the clock from a Windows computer.

Code Practice Mode

Holding one of the first three memory buttons down on boot up puts the keyer in Code Practice Mode. Characters generated are based on tables in the Wikipedia article on Morse Code.

  • M1 Send letters only
  • M2 Send letters and numbers
  • M3 Send letters, numbers, and punctuation

Characters are sent in groups of five. If a serial terminal window is open it will display the sequential group number as well as the ASCII characters themselves.

Practice Mode Commands

In practice mode, the first four memory buttons adjust the delay between characters in increments of two element (dot width) times. M1 adjusts by zero, M2 by two, M3 by four, M4 by six elements giving a listener additional time to decode the sounds. Each step slows the average WPM by about 10 percent.

Pressing the M5 button pauses practice and the display back light will begin blinking. Pressing M5 again resumes but will likely have mutilated any character that was in progress. M6 increases sending speed and M7 lowers sending speed, one WPM per click. The changed speed is only effective until the keyer is reset, it is NOT written to EEPROM.

Display Mode

Normal Operating Displays are also available in Code Practice mode by pressing Function. The display will not start until the current five letter code group is completed.

Battery Status

If the battery voltage drops below 3.40 volts, the display back light will begin flashing.


Many thanks to Richard Chapman KC4IFB whose September 2009 QEX article provided the inspiration and base code for this sketch. His iambic keyer code feels exactly like my original WB4VVF Accukeyer. Also see Rarons Blog for a discussion of the tree method for decoding and encoding morse characters. It was very helpful in building efficient translation tables. The circular queue was implemented with help from examples at Paul Stoffregen encouraged me to try the Teensy3.2 on the PJRC forum.


Revision History

February 25, 2016       MemoryKeyerTeensy3.2_V1.0    Initial sketch
March 9, 2016             MemoryKeyerTeensy3.2_V1.1.0  Rework battery alarm logic, bug fixes.
March 16, 2016           MemoryKeyerTeensy3.2 V1.1.1   Workaround fix LCD does not have backslash in its font.


More Fun With Direct Digital Synthesis: 32u4 and Fast PWM

32u4 Port

My 2015 winter project will be an expanded version of the Morse Code keyer I built last year. I now have a PJRC Teensy 2.0 controller board (from Sparkfun) to use. The Atmel 32u4 based Teensy 2.0 is even smaller than the Pro Minis I have been using. It is attractive because it has USB built in for program loading and serial transmission. And there’s lots of I/O pins available which will make an LCD easy to connect. I note that everybody making a 32u4 “Arduino” is defining a different pinout from the chip. The Adafruit Feather is quite ambitious, has it’s own IDE addon and can be bought with Bluetooth or WiFi  included.

This breadboard photo shows the Teensy 2.0 at top left, Sparkfun Pro Mini at center, Sparkfun RedBoard top right, and a MicroCenter Pro Mini clone at bottom right.



PJRC has ported many of the standard Arduino libraries to their 32u4 Teensy form factor and these are included in your Arduino IDE when you download and install the Teensyduino addon. But my keyer sketch uses Direct Digital Synthesis to form a nice sine wave side tone which requires direct setup of a Pulse Width Modulation timer inside the AVR chip. My implementation is based on code from Jeff Whitlatch, KO7M.  I used timer 2 in last winters UNO based keyer as that’s the timer that does tone() in the Arduino UNO and I completely superseded that function. Reading the data sheet on 32u4 shows that it doesn’t even *have* a timer 2. It has timer 0 (8 bit), timers 1 and 3 (16 bit), and timer 4 (10 bit). Digging into the Teensy Arduino libraries shows that PJRC is using timer 3 for tone() so I needed a port that just changed the timer used. Comparing the 32u4 data sheet with the Mega328 data sheet showed that the only difference besides the timer number would be in the Waveform Generation Mode bits. 32u4 has four WGM bits, Mega328 has 3. I used a mode setting that turns the 16 bit 32u4 timer 3 into an 8 bit timer and Success! The port was working in my test program.

Fast PWM

Phase Correct PWM in an AVR processor uses the timer in a manner that has it count from 0 to 255 then count back down to zero for each interrupt cycle. The PWM signal goes high on the way up and low on the way down. For an 8 bit counter, that’s 510 counts per cycle (read the data sheet to find out why it skips two) so with no clock scaling the sample rate is 16 MHz/510 or 31.4 KHz. In Fast PWM mode the timer counts from 0 to 255 then rolls over back to zero. A PWM wave on the output pin goes high on the way up and low on overflow. This results in some jitter on the PWM pulses but the sample rate is twice as fast, 16 MHz/256 or 62.5 KHz. I decided to try Fast PWM in the test program. It required only a change in the math that calculates the sample rate, and a slightly different set of WGM bits.

The following images show comparisons of the 31.4 KHz (Phase Correct) and the 62.5 KHz (Fast) rate tone waveforms from the test program. The PWM signal is filtered by a single 10k resistor and a 0.01 ufd capacitor to ground at the scope connection.

Comparison of Phase Correct PWM with Fast PWM

Comparison of Phase Correct PWM with Fast PWM at 100 Hz


Comparison of Phase Correct PWM with Fast PWM at 1000 Hz

Comparison of Phase Correct PWM with Fast PWM at 1000 Hz


Comparison of Phase Correct PWM with Fast PWM at 5000 Hz

Comparison of Phase Correct PWM with Fast PWM at 5000 Hz


Comparison of Phase Correct PWM with Fast PWM at 10000 Hz

Comparison of Phase Correct PWM with Fast PWM at 10000 Hz


There is a clear improvement at the higher sample rate in the amount of “fuzz” on the waveform. The fuzz is at the sample rate and is the result of the 0.01 ufd capacitor integrating the PWM square wave. At twice the rate, the capacitor has half the time to charge or discharge. You can see at 5 KHz, the Fast PWM signal is much closer to a sine wave than Phase Correct. At 10 KHz, both are falling apart. A better output filter that cuts off the sample frequency would help but for morse keyer side tone from a tiny speaker, the average amateur radio operators ear won’t know the difference. I may try a switched capacitor filter some time in the future just to see. Watch this space.

Revision History

2015/12/08   The photos above are all from the 32u4 port. The program uses quarter wave symmetry to reduce the table size by a factor of 4. Two sketches, one running on UNO or other Mega328 controllers, the other for the PJRC 32u4 Teensy are at:

I also back ported the changes to an earlier sketch that did not take advantage of symmetry. Scope traces were identical to the 32u4 port. Since the complete 360 degree cycle is specified, the code may be modified to generate arbitrary non-sinusoidal waveforms by manipulating the tables. Download at:

Each of these zip archives has a copy of the spreadsheet I used to construct the sine tables.



Worlds Smallest Iambic Keyer Paddles

I’ve done a couple of homemade dual lever paddles but recently I wanted to demonstrate my Tiny85 Arduino based keyer project at a local Maker Faire, so wanted something I could put in my pocket. In a few minutes, I made this. It’s a standard 3.5mm (1/8 inch) stereo plug. You can’t get any more portable than that.



Unscrewing the plastic shell reveals the secret sauce.



This is the dash paddle side. Just a tiny bit of thin copper soldered to the plug terminal. For those readers needing details, the copper came from the band around a Basil Hayden’s whiskey bottle.  We recycle!



Here is the dot side.



A  bottom view, you can see the two copper strips and how the sleeve (ground) contact was bent to form the common contact. A little careful tweaking left a thick sheet of paper’s worth of space between each copper strip and the common contact.



And the top side.



I was surprised to find it actually works. Could be useful on a QRP mountain top expedition. Have a look at this YouTube video.

Home Made Iambic Paddles

I have two homemade paddles to use with the Iambic Keyer Project.

This first example was made in the late 70s or early 80s, can’t remember exactly. I mentioned to a friend who worked in maintenance at a steel mill that I was looking for a heavy piece of metal to make paddles that wouldn’t scoot around on the desk.  We discussed some ideas and a few days later he produced the frame (all the blue parts) you see in the photo. It weighs over five pounds, it only moves if you want it to.

The arms are plexiglass fastened to short pieces of tubing. The tubing is flared at each end and each flare receives a bearing ball. Cup tipped Allen screws in the top frame and in the base capture the balls. With careful adjustment leaving a small amount of play, these bearings work well.

The rest of the paddle hardware is made of scraps from my junk box. Simple contacts made from machine screws work, but are noisy. Noise however does not bother the keyer much, as once an element is started, the paddle input is effectively debounced by dot/dash timing in the software.

Paddles Home Made About 1978

Paddles Home Made About 1978


My second example was made recently. I decided the blue paddles were not portable enough so I made something smaller. This set has a base of two inch steel Aux Bar scrounged from a telco installation project. The next photo shows the first iteration.

For pivot bearings I used brass thread inserts from Woodcraft. They have a 1/4-20 inside thread and a very coarse outside thread, intended to screw into a woodworking project. I filed the coarse threads off two sides of the inserts and soldered them to a strip of PC board material to form the paddle arms. The bearing for the arms is then the threads of the screws which go into threaded holes in the base plate.  Contacts are bent paper clips screwed to half inch nylon standoffs.  This works but has a terrible feel due to slop in the 1/4-20 threads.

I put a square of sticky silicone mat under the base and it stays put pretty well. The square was cut from a large mat intended to hold a wood work piece in place while you use a router on it’s edges.

Paddles Home Made February 2015

Paddles Home Made February 2015


The second iteration of the Aux Bar paddle is an attempt to remove some of the annoying backlash in the screw thread pivot bearings. I thought longer threads would help and got two threaded sleeves from the hardware store. These are made for joining two lengths of threaded rod. They have a #10 thread and are about an inch long. Two new paddle arms were constructed, this time with the bearings on the outside of the PC board as the sleeves are larger than the brass inserts used in the first model.

I inserted three sets of small screws into the arms to capture the tension spring which allows some adjustment. The spring shown in the photo is from an old IBM keyboard. If you part out one of those old Model M’s you have enough springs to last a lifetime. A second spring directly between the pivot points takes up some of the backlash remaining in the threads. Also the two #10 pivot screws are epoxyed into the base to eliminate that small bit of wobble. At the back of each arm where the paper clip touches, I added a drop of silver containing solder to make a better electrical contact.

This iteration has a very light touch but still too much slop in the bearings. I think with some tuning of the springs it will be very usable.

Paddles Home Made March 2015

Paddles Home Made March 2015


 Update 5/11/2015

Added a spring directly centered between the two pivot points. This spring is stronger than the small one separating the paddle arms, and it’s function is to take up backlash in the sloppy threads on the cheap pivot screws. I soldered cut down copper carpet tacks to the inside of the paddle arms to keep the new spring in place. The spring force is directly between the pivot points, so it does not contribute to the effort required to close the paddles unless you press hard enough to overcome it’s higher tension. It improved the feel of the Aux Bar paddles a lot.

Pivot Spring Added

Pivot Spring Added

Arduino Based Iambic Keyer(s)

Version 1.0 – ATTiny85 Port

Richard Chapman KC4IFB published an article in the Sep/Oct 2009 QEX magazine (subscription required) for constructing an Iambic Keyer on the Arduino platform. I downloaded his code from the QEX web site (ARRL membership required) and found it worked well.  I have not been active in Ham Radio for years and my morse code is seriously rusty, so I decided to build a keyer for practice purposes and maybe to use on a real radio some day when I figure out how to get an antenna up on this small lot.  I have a WB4VVF Accu-Keyer I used with my homemade paddles long ago.  I bought the PC board from WB4VVF himself at the Dayton Hamvention.  Chapman’s keyer implementation on the Arduino Uno felt exactly the same and I had no problem getting used to it.

I wanted to see if this code would run on an ATtiny85 chip. These are beautiful little microcontrollers in an 8 pin DIP package. They have 8K of internal flash memory and with a minor bit of library downloading, are programmable via the Arduino IDE.  There is a catch though, tiny85 does not normally have bootloader code like a formal Arduino does so you need additional circuitry to burn your sketch onto the little chip. In July 2013 Jim Williams from Workshop 88 in Glen Ellyn conducted a class in tiny85 programming which I attended. At the end of the class we all had our own Arduino ISP adapter board and could burn a tiny85 by using an Arduino UNO as an intermediary.

I amped up my ISP adapter by adding a ZIF socket. It also can program the ATMega328 chips by moving five jumpers.

ISP programmer for ATtiny85 and ATMEGA328 microcontrollers

ISP programmer for ATtiny85 and ATMEGA328 microcontrollers

With the ISP programmer working, I was ready to work on the tiny85 port.  I found Chapman’s code worked but there was no side tone generated.  After a few hours debugging I noticed Chapman’s code was turning the tone on in every iteration of loop(). The tiny85 did not like that. I just added a flag so tone was turned on once, then left on, and the tiny85 port was working 100%. In the end, a very minor change.

I wanted SMALL so I added code to eliminate the speed potentiometer. In my version, you hold both paddles closed for 5 seconds and it goes into speed set mode. Dots increase the speed and dashes decrease.  Another five second Iambic squeeze and it goes back to normal mode.  Also I added a Straight Key mode. If a two conductor instead of a three conductor plug is inserted in the paddle jack it will just beep out what it sees on the dot paddle.  Good for code practice with my J38 if I can remember where I put it.

Source code for the ATtiny85 port is here. This is the finished Keyer in the mandatory Altoids enclosure (but note SMALL Altoids):

Atmel ATtiny85 based Iambic Keyer

It was a challenge to get everything in there and still have the lid close.  The speaker is from a defunct greeting card but rest of the parts were purchased from Jameco. In the end, the most expensive single component was the Altoids mints from the drug store.  The ATtiny85 chips are less than a dollar if you buy ten.

There are these few parts required:

  • speaker and 22 ohm resistor
  • 2032 battery and holder
  • two 3.5 mm jacks, one output, one paddles
  • three bypass capacitors
  • Dropping resistor and LED
  • Power switch
  • ATtiny85 chip and 8 pin socket
Interior of ATtiny85 Iambic Keyer.

Interior of ATtiny85 Iambic Keyer.

There is a short video of the keyer in action here.  So now if I spend a few minutes every day practicing I might get back to the 13 WPM I had to do to get my current license.

Version 2.0 – ATMega328 with Memories

Richard’s QEX article suggested several possible enhancements. I thought adding memories would make the device much more useful so began another journey into Arduino programming. Yes, I know there are already Arduino keyers out there. The K3NG implementation has a ridiculous number of options, but I wanted to do my own based on Chapman’s sketch in the most efficient manner possible. A schematic drawing of my completed keyer is available, and I have written a description of the functions. Source code for the sketch is here.

The PS2 keyboard requires +5 volts so I designed around a five volt Sparkfun Pro Mini board. Only ten bucks! Available here or here. The Pro Mini has an on board 150 milliamp capacity 5 volt regulator if you use a 7-12 volt power supply.

Features in the keyer sketch now include:

  1. Memory or keyboard characters are buffered in an asynchronous circular queue so memory buttons or keyboard characters can be “typed ahead”.
  2. PS2 and serial terminal keyboards supported.
  3. Paddle generated morse is interpreted and printed as ASCII letters on the serial terminal.
  4. Four programmable memories with 50 character capacity each.
  5. Memories programmable from the keyboards or from the paddles.
  6. Random code practice modes, letters, letters and numbers, letters, numbers, and punctuation.
  7. Sending speed settable 10 to 45 WPM. Limits can be changed by recompiling.
  8. Sidetone frequency settable 100 to 1500 hz. Limits easily changed by recompiling.
  9. Commonly changed default settings are in a separate header file (Canned.h).
  10. Message strings, sending speed, and sidetone frequency are stored in EEPROM and easily reset to defaults.

The sketch requires five I/O connectors:

  1. A 3 conductor jack for the paddle or straight key. Connect dot paddle to tip, dash paddle to ring. Use a 2 conductor plug for a straight key in the same jack.
  2. A 3 conductor jack for transmitter keying. A 2N2222 open collector output is on the tip. Line level sidetone is connected through a 5k resistor to the ring so you can connect an external amplifier if you need louder audio.
  3. A power jack for either a 5 volt or 7 -12 volt wall wart supply. Consult the Sparkfun documentation for which Pro Mini pin to use for power.
  4. A six conductor mini DIN connector for the PS2 keyboard. See Canned.h for information on the four leads needed.
  5. A connection for programming, and TTL serial terminal through an FTDI adapter. This can also power the unit instead of the wall wart.

There are six push button switches and a volume control needed:

  1. A reset button for the Arduino.
  2. A Function button.
  3. Four push buttons to activate individual memories.
  4. The volume control feeds a one transistor buffer for the internal speaker. It does not affect the level on the line output connection.


Pressing reset momentarily has different effects depending on what other switches are closed. A processor reset normally takes a few seconds, when finished three mid tone beeps will be heard.

  • Press the reset button alone to restart the Arduino. This is also the only way to exit code practice mode.
  • Press the reset button while holding the function button down until three low tone beeps sound will restore the four message memories and code speed to defaults. Default messages, speed, and sidetone frequency are set at compile time from the file canned.h. You must do this action when loading the sketch for the first time into a new Arduino to initialize the EEPROM.
  • Press the reset button with a 2 conductor straight key plug inserted and the keyer enters straight key mode where the sketch generates tone and output simply follows the key closures.
  • Press the reset button while holding down one of the memory buttons starts random code practice. Characters will be generated in five character groups and echoed on the serial port.
  1. Memory 1: letters only
  2. Memory 2: letters and numbers
  3. Memory 3: letters and numbers
  • Pressing reset while holding Memory 4 enters sidetone frequency set mode. The dot paddle increases frequency, dash paddle decreases. Press M4 again to exit set mode.

The function button has three duties:

  • Reset to default messages as mentioned above. You must hold the function button down until you hear 3 low tone beeps.
  • Holding function alone down triggers speed change mode. While function is held, the dot paddle increases speed, dash paddle decreases speed.
  • Holding function down and then momentarily pressing a memory button allows programming that memory. After programming, press function again to return to normal.

New memory messages may be entered from the PS2 keyboard, the serial port keyboard, or from the paddles.

Pressing a memory button by itself transmits the programmed message.

Serial or PS2 keyboards have a command mode, entered by typing a back slash followed by a single character. Commands implemented are:

  1. \+ increase sending speed one Word Per Minute
  2. \- decrease sending speed one Word Per Minute
  3. \u increase sidetone frequency by 5%
  4. \d decrease sidetone frequency by 5%
  5. \w save current sidetone frequency and WPM to EEPROM memory
  6. \1, \2, \3, \4 send a message as though a memory button was pressed.

The keyboard translation table (AtoM.h) includes all the characters shown in the Wikipedia article on Morse Code except the underscore and the dollar sign. Typing an unsupported character echos “x” on the serial port and will be ignored by the morse interpreter.

Version 2.0 Hardware Implementation

Here is a photo of my 2.0 construction. There are three jacks on the left for power, paddles and transmitter keying. PS2 keyboard jack on the right, small volume control and send monitor LED on the front. Not visible is the six pin serial connector on the rear.

On the lid of the S.A.E. you can see a small speaker through the holes around the center. Round holes were made with a heavy duty paper punch. For buttons, I used 6 mm square through hole PCB mount switches with four pins, the kind everybody uses on their solderless breadboard. I bent the pins on one side back so they could be soldered directly to the Altoids lid. Quarter inch square holes for the buttons were punched with a hollow chisel mortiser bit which worked quite well.  I made labels by placing the lid in a scanner, adding text to the scan in GIMP, then printing a 1:1 image of the labeled lid on photo paper. I cut the letters out and glued them to the Altoids lid. This technique produces text labels with the original Altoids artwork underneath. I coated each label with clear nail polish for protection.

Arduino Memory Keyer Exterior

Arduino Memory Keyer Exterior

With the box opened you can see the small Sparkfun Pro Mini board. It is mounted by a pair of L shaped wires cut from a paper clip. These are soldered in the Mini’s two ground pins and then soldered to the Altoids tin. A rectangular hole in the back of the tin provides access to the six pin serial connector. All the in use Arduino inputs have 9.8 k pull up resistors added, and are bypassed at the switch with a small capacitor. The outer end of the pullup resistors are soldered to a narrow bit of PC material wired to Vcc.

Three jacks on the left are epoxyed in place. The PS2 jack on the right, which was salvaged from a defunct USB-PS2 adaptor, is held by a narrow copper strap soldered to the jack and to the Altoids tin. A small perf board at the front holds most of the ancillary components for keying and the audio control. I mounted the perf board using more stiff wire cut from the paper clip.

There is a strip of thin PC material laid across the button switches to add more physical support. The two switch pins not soldered to the Altoids lid are bent over the strip and soldered. Notches filed in strategic places across the copper isolate each switch, and I added the necessary 0.1 uFd capacitors at this point.  The speaker is tucked under one of the PC strips and epoxyed in a couple of places. A short piece of flexible solder wick bonds the box lid to the bottom.

Arduino Memory Keyer Interior

Arduino Memory Keyer Interior

Future Enhancements

Add a FTDI USB to Serial adapter inside the box. It would allow a more graceful connection to a host computer running a serial communication program. Or build another unit with a USB integrated chip.

Add a 16×2 LCD display. Code would be trivial, but will probably have to find a bigger box.

Expand to six or eight memories. My sketch is compiling in about 13 k of flash, and has over 1500 bytes of ram free plus the Pro Mini has eight analog inputs so easily done. But how many memory messages can the average ham keep track of? I think four is a good number and I love the Altoids tin paradigm.



Many thanks to Richard Chapman KC4IFB whose February 2009 QEX article provided the inspiration and base for this sketch. His iambic keyer sketch feels exactly like my original WB4VVF Accukeyer. A version of his sketch with instrumentation added so you can see the state changes is here. Also see Rarons Blog  for a discussion of the tree method for decoding and encoding morse characters. Would you believe 300 WPM full duplex?  I did not use his library but his work was very helpful in building efficient translation tables. The circular queue was implemented with help from examples from the Embedded Systems Journal.


Revision History

V2.0.0 Initial coding to implement fully asynchronous event loop.
All delay() and spin waits removed from the main loop path.
Remove numbers only practice. Change eeprom order. Add change sidetone.

V2.0.1 Minor tuning space generation in doIambic.

V2.0.2 Converted sidetone generation to DDS/PWM sine wave with help from

Quarter Wave Symmetry

Quarter Wave Symmetry
1000 Hz 256 Step Table

V2.0.3 Changed sine table to half step offset. Saves one byte.

V2.0.4 Added sidetone envelope shaping. Required several other changes.

Shaped Dits at 45 WPM

Shaped Dits at 45 WPM

V2.0.4.1 Bug fix was dropping dits on a long string of upper case “H”s. Disable interrupt while changing sine tables.

V2.0.5  Changed AtoM table from prog_uint16_t to char to save memory, which created bug where setup does gratuitous write to A6 and A7. Fixed problems when compiling under Arduino IDE 1.6.1, did not accept typedefs in pgmspace.h. Fixed bug in initByte, 1.6.1 did not like  aaByte = aByte -= 0x20;  Compiled size is 2k smaller in 1.6.1 and no more bogus compiler warnings!

April 30 – Have not changed the V2.0.5 sketch but did redo the audio section of the Altoids keyer. I found the single transistor audio buffer was not satisfactory, distorting badly when driven by a sine wave. Also it was drawing 50 milliamps at idle. I removed the transistor and connected an LM386 amplifier – much better sound and very little current draw when idle. A revised schematic is at:


20 March 2015  —  The keyer sketch was developed with Arduino 1.0.6. Recently I downloaded the latest Arduino IDE 1.6.1 and discovered the keyer sketch will not compile. It appears the newer version of GCC will not accept the typedefs used in the pgmspace.h library. I will upload a 1.6.1 release as soon as I figure out what’s going on. FIXED see V2.0.5 above.

24 March 2015  — Was shopping in Frys and bought an inexpensive (< $3) adaptor, is USB A female to PS2 male, is about the same size as the two connectors placed end to end.  It was made by Shaxon Industries in guess where. To my complete surprise it works. Using the adaptor I can connect any USB keyboard to the keyer which is good news, as PS2 keyboards especially compact ones, are getting hard to find. I measured power supply current with the adaptor, it does not add significant drain over the 25 Ma the keyer itself draws. The small USB keyboard I tried added only about 3 milliamps when not typing. I did find the transistor I used to buffer the speaker draws 25 milliamps itself, will have to find a more efficient amplifier.