Simple Morse beacon keyer

News: firmware updated 2018/06/25

This article describes a simple beacon keyer with a range of speeds, including QRSS rates, and configurable beacon message.

With the growing use of synthesisers based on very high stability standards (eg Rubidium, GPS) for both transmitting and receiving stations, the prospect of receiving low speed Morse transmissions in very small bandwidths opens up new possibilities.

The implementation comes in three platforms:

In all cases, a range of speeds is available based on three speed select pins. In the case of the ATtinyx4 and ATmega168, a selection can be made from up to 8 stored messages. The ATtinyx5 platform will suit where fewer messages are needed.

Message content is stored in EEPROM, and is field upgradeable using an inexpensive AVR ISP programmer.

The chip provides both a KEY output to key a Morse code transmitter, and an auxiliary output which can be used for a square wave 800Hz audio sidetone output.

The circuit is intended for use on a nominal 12V supply but will operate directly from 5V down to 3V if the series regulator is bypassed (ie R1=0, D1 not fitted).

Fig 1:

Fig 1 shows the circuit diagram using an ATtinyx4(A) chip. The chip pinout is different for an ATtinyx5, see Table 1.

Table 1: AVR pinout
MCU ATtinyx4(A) ATtinyx5 ATtinyx5x ATmega168 Comments
Vcc 1 8 8    
GND 14 4 4    
/RESET 4 1 1    
Speed[0] 13 NA NA PD3 (D3)  
Speed[1] 12 NA NA PD4 (D4)  
Speed[2] 11 NA NA PD5 (D5)  
AUX 5 5 NA PD6 (D6)  
TX 6 3 7 PB5 (D13)  
Msg[0] 10 6 5 PB0 (D8)  
Msg[1] 9 7 6 PB1 (D9)  
Msg[2] 8 2 NA PB2 (D10)  
XTAL (if used) 2,3 NA 2,3    
ESync 7 NA NA PD2 (D2)  

Pin designations in parenthesis for ATmega168 are Arduino designation. ATmega168 physical pins depend on the package.

Internal weak pull-ups are used on the Speed and Msg input select pins, a switch or shunt to ground will control these pins.

Speeds are 12WPM, 6WPM, QRSS1, QRSS3, QRSS6, QRSS10, QRSS15, QRSS30, so 0x4 selects QRSS6. In the ATTinyx5 implementation, speed must be selected from within the message.

The AUX output pin can be used to drive a speaker through a 500/8 transformer, or a PCB speaker such as the StarMicronics QMB-111PC, see the options settings. (QRSS1 is 1.1WPM.)

The KEY  and AUX outputs are intended to drive a 2N7000 driver for a /KEY output (ie ground for key down condition) and /AUX when the chip is operated from 4.5 to 5V. A bipolar transistor could be used with a 1k series resistor (R2 ,R3) to the base for operation on lower voltages. If the module is to drive other TTL / CMOS loads, the driver transistor can be omitted and a wire link inserted from gate to drain, changing the sense of the output pins to KEY and AUX.

Table 2: Components
Component Value Comments
C1  1µF   
D1  1N751   
IC1  ATtinyx4x   
J1 2x6 shrouded HDR ISP jack.
Q1 2N7000  Alternative bipolar eg BC337, BC548.
Q2 2N7000  Alternative bipolar eg BC337, BC548.
R1 470R R1=(Vdc−5.1)/10kΩ.
R2 0R0 2k2-1k0 if bipolar used for Q1.
R3 0R0 2k2-1k0 if bipolar used for Q1.
TB1 Terminal block 5.08mm pitch  

Table 2 is the component list.

Table 3: TB1 pinout
Pin Use Comments
1 GND  
2 +12V  
3 /RESET  
4 /AUX  
5 /KEY  

TB1 pinout is shown in Table 3.

Clocks for more accurate timing

A crystal (or external clock source) can be used with the ATTINYx4x chips and with a special build for the ATTINY45 for more accurate timing.

Crystal / external clock

Note that low level external clocks (eg those with 1Vp-p) may work better with the low fuse set for an external crystal (0x60) and a 10k R to ground, the input circuit is more sensitive.

The options bits [8-10] must be set appropriately.


EEPROM holds the configuration data, including the messages. The EEPROM image is field replaceable.

Developing the EEPROM image

The EEPROM data structures are moderately complex to provide for flexibility, present and future, in use.

The EEPROM image is created using the following online generator.

EEPROM hex file image generator

u16 types are stored backwords or little endian in the EEPROM.

Message texts can be inserted into the form below to generate an Intel Hex format EEPROM data file for download for a device programmer (eg AVRDUDE).

Up to 8 messages can be specified. The first blank message ends the message set. The skip variable sets the number of characters in the message to skip when not performing the periodic full speed ID. If you specify skip greater than message length, it will be set to 0.

Note that the 8 pin ATtinyx5 series chips can only access message 0, there are no message select pins.

Table 4: Options bits
Bits Description
0 invert msg and speed selection pins
1 msg selection in Gray code
3:2 0: AUX pin is square wave audio out;
1: use AUX pin to indicate high speed ident in progress;
2: AUX controlled by _A0 _A1 in message;
3: reserved.
7:4 Time in minutes between full speed ID, 0=none.
10:8 Crystal / external clock frequency:
0: 8.192MHZ
1: 18.432MHz
2: 12.800MHz (not supported on ATTinyx5)
3: 10.000MHz (not supported on ATTinyx5)
4: 8.000MHz (not supported on ATTinyx5)
5: 16.000MHz (not supported on ATTinyx5)
6: 15.600MHz Kenwood SO-3 TCXO (not supported on ATTinyx5)
14:12 Address offset

Above is a definition of the options bits. The options bits are specified as a four character hex string.

Invert facilitates use of DIP switches from select pins to ground, and if inverted, switch ON means logical 1 in terms of the inverted bits used to select a speed or message.

Some crystal frequencies are not supported on the ATTinyx5 chips as its Timer1 is only eight bits.

Insert message details here:
MsgNo Message text (max 120 symbols) Skip

Options:   ISync:   ESync:

Permitted characters are alphabetic, digits, space and the symbols @ , ? : .'-/()"=+ from ITU-R M.1677. Additionally _1U and _1D can be used for 1s of key up or key down condition. The character | will stop sending and put the MCU to sleep requiring a reset or power off/on cycle to restart the keyer. Messages can be up to 50 Morse symbols, _xx sequences occupy 1 symbol. Leading and trailing spaces are significant.

The Sync value is a 16bit hex value which period in tenths of a second of a rolling clock. An _YU character is the message (eg "VK0ABC =_YU") will cause the keyer to wait (key up) until the next rollover of the sync clock. So for example crystal timing was used and sync is set to 0x1770 (6000 tenths of a second), then a _YU character at the end of the message will cause the keyer to wait (key up) until clock rollover to go back to the start of the message and so the the messages. If the message had taken 9 minutes from powerup, then the next message would start at exactly 10 minutes from powerup, and the next message, 10 minutes later. This feature allows alignment of id messages with common 10 minute grabber cycles. (For RC clock, Sync is 1799 for 10 minutes, but the RC clock is not as stable or accurate as a crystal.) Similarly, a _YD will wait key down until the next rollover of the sync clock.

It is also possible to encode an arbitrary symbol of up to 5 elements by inserting the sequence \hh where h are hex representation of an 8 bit word. The format of the word is as follows: from MSB to LSB, padding 1 bits, a 0 bit, followed by the Morse Code representation of the character in, with a 0 indicating a dot element and a 1 indicating a dash element to make 8 bits in total. For example \C8 (1100 1000) would represent the AS (wait) pro-sign. Codes 0x10xxxxxx are reserved.

Special characters to change speed can be inserted in the message, their format is _Sn where n is the index of the speed list. For example "XX5YY_S4 YY" would change speed to speed 4 or QRSS6 after the second Y and send a space and YY at that speed. The speed switches are read at each start of the message, so on repeat this will start at whatever the speed switches select.

If options bits 4:3 are 10, special characters _A0 and _A1 can be embedded in the message to make AUX=0 and 1 respectively.

Table 5: Special message characters
Special character Description
_KUhh key up for hh seconds (hh two hex digits)
_KDhh key down for hh seconds (hh two hex digits)
_1U key up for 1s
_1D key down for 1s
_YU key up until sync
_YD key down until sync
_EU key up until external sync
_ED key down until external sync
_A0 AUX pin low
_A1 AUX pin high
_Sx set speed index to x for x=0..7
_NO no operation, 100ms delay

Table 5 is a summary of the special message characters.

_A0, _A1, _Sx, and _NO take 100ms to process.

This generator is a support tool for this specific project. It does not do a lot of checking of input data, if you get garbage out, check your input. The current version creates messages with a version marking which requires the current firmware version.

EEPROM usage is 23 bytes, plus 2 bytes per message, plus one byte per symbol in each message. Restrict each message to no more than 50 symbols, and the total configuration to fit in available EEPROM (128 to 512 bytes, depending on the chip size chosen).

Programming the chip

There are many programmers available for the AVR microcontrollers. This section describes an inexpensive and easily obtained programmer, free software, and a programming example.

Fig 2:

Fig 2 shows an example inexpensive implementation of a 5V/3.3V USBASP programmer for AVR chips. A R0 link at the lower edge of the underside can be removed for 3.3V operation instead of 5V. Some implementations have a link to enable powering the target from USB, the one pictured above does not and the track should be cut adjacent to pin 2 (labeled VCC above) of the 10 pin connector OR no connection made to pin 10 on the target board if you do not want to power the target. It is a good idea to NOT power the target from the programmer without good reason.

These type of programmers can be found on Ebay for less that $4 including a cable and post. The programmer plugs into a USB port and a 10 pin ribbon cable connects to the in system programming connector on the target. If the target uses a 6 pin ISP header, 10/6 pin converters are available on Ebay. If the target uses a 3.3V supply, configure the programmer for 3.3V (usually a link or solder bridge, see the programmer documentation). Don't supply power from the programmer to the target (again a link on some programmers, see the programmer documentation).

Adapters from 10 pin to the newer 6 pin ISP configuration are readily available at low cost on Ebay.

@echo off
if *%1==* goto usage
set id='$Id: prg.bat 679 2011-12-12 06:00:52Z owen $';

echo Processing %1
set PRG=usbasp
set PORT=usb
set OPTS=-B 5
set DEVICE=t44

if *%2==* goto eeprom
echo program flash (%2.hex)...
avrdude %OPTS% -c %PRG% -P %PORT% -p %DEVICE% -U flash:w:%2.hex
sleep 1

echo program eeprom (%1.hex)...
avrdude %OPTS% -c %PRG% -P %PORT% -p %DEVICE% -U eeprom:w:%1.hex 
sleep 1

if not *%3==*fuse goto lock
echo program fuses ...
avrdude %OPTS% -c %PRG% -P %PORT% -p %DEVICE% -U hfuse:w:0xD4:m -U lfuse:w:0x62:m 
sleep 1

if not *%4==*lock goto cleanup
echo program lock (after everything else) ...
avrdude %OPTS% -c %PRG% -P %PORT% -p %DEVICE% -U lock:w:0x0:m 
goto cleanup

echo usage: prg eepromfile flashfile fuse lock
goto end


Above is a batch file (prg.bat) to program an ATtiny44 using AVRDUDE. Though this is a Windows batch file, the programmer and AVRDUDE work also on Linux.




Fig 3:

Fig 3 shows a prototype keyer using an ATtiny24. The prototype has a power supply regulator onboard, output FET and uses a crystal for more accurate timing. (Output connector GND, /KEY, KEY, AUX.)



Fig 4:

Fig 4 shows Another simple Morse beacon keyer - basic, but accurate , crystal timing for accurate message cycles, and ATB for firmware and message updates.


Fig 5:

Fig 5 shows an Arduino Nano which can be purchased ready made for around $10. The ATmega168 code runs on this and other Arduino boards with ATmega168/328 chips with 16MHz crystal. Though the Nano might look over-equipped with the USB interface, it is a 16MHz ATmega328P with provision for onboard ISP header. Any prototyping board with ISP connector, 168/328 chip and 16MHz clock is a good candidate.

 If the application is for a simple single message keyer with TX out, the board can be powered (5V) and TTL level TX signal all obtained at the 6pin ISP header. Note this is NOT Arduino code, and it does not use an Arduino bootloader, it is programmed using an ordinary AVR ISP programmer connected to the 6pin header. Other Arduino compatible boards with prototype areas may be interesting.

An example AVRDUDE command line to program the Nano follows.

avrdude -B10 -F -P usb -c avrisp2 -p m328p -U flash:w:%FFILE% -U eeprom:w:%EFILE% -U lfuse:w:0x7f:m -U hfuse:w:0xD4:m -U efuse:w:0x07:m

The outputs on the Nano board are TTL, a buffer is typically required to drive the transmitter (see the circuit at Fig 1 for a suitable buffer using a 2N7000).

Getting the QrssKeyer

The flash memory code can be downloaded for the different chip types from links below.

The EEPROM contents are created using the conversion tool in this article.




Version Date Description
1.01 03/02/2012 Initial.
1.02 18/06/2012 Added sync facility, V2 EEPROM format, crystal option.
1.03 12/07/2012 Various revisions and crystal choices implemented.
1.04 23/09/2012 V3 update (_Sx, _Ax).
1.05 24/09/2012 V4 update.
1.06 09/11/2012 Added 10MHz external clock option, Esync facility.
1.07 26/12/2012 Changes for aux switching, more crystals completed, x5 pins revised for msg select.
1.08 19/01/2013 Changes for 120 symbol message limit.
1.09 01/02/2013 Gray code option.
1.10 30/06/2014 Address offset added.
1.11 26/07/2020 16 bit values in calculator entered in LE format.


© Copyright: Owen Duffy 1995, 2021. All rights reserved. Disclaimer.