Morse Generator

The Morse generator plays a message via a loudspeaker and keys P8 (pin 13) simultaneously. It repeats the message forever (beacon function). The message is as follows: CQ CQ CQ de OZ1EUO OZ1EUO OZ1EUO k. The length of the message is only limited by the memory space of the Basic Stamp EEPROM. Each morse character takes up 1 byte.

Circuit diagram


Figure 1. Morse Generator circuit diagram.

The power supply is connected at pin 24. Any voltage between 5.5 volts and 15 volts will do. Pin 23 is ground.

Audio output is at pin 12. The loudspeaker is connected via a capacitor. Any capacitor value above 100 nF will do. If an electrolytic type is being used, the positive side should be connected to pin 12.

Key output is available at pin 13. Key off is 0 V and key on is +5V. A transceiver interface can be made by adding a NPN-transistor, where the base is connected to pin 13 via a 10 kohm resistor, the emitter is at ground, and the collector is key out.

How the software works

Free development software is available at www.parallax.com. I downloaded and used the Basic Stamp Editor ver. 2.2.6.

The following text explains the most important parts of the software. Please refer to the Morse Generator source code, which can is found on the download page.

Main:
  FOR eeprom = 48 TO 81
    READ eeprom, morse     ' Copy contents of EEPROM memory (at address eeprom) into morse
    GOSUB Send_morse_char  ' Send the morse character
  NEXT
  PAUSE 1000               ' Delay 1000 ms
  GOTO Main                ' Start over again
  END

Main does its job using a FOR..NEXT loop. First, eeprom is set to 48 (decimal). This is a memory address in the EEPROM. The bit pattern of address 48 is copied into morse using READ. The character in morse is sent using a subroutine (GOSUB Send_morse_char). When done, the FOR..NEXT loop continues and sets eeprom to 49 and copies the bit pattern at that EEPROM address into morse, which is sent using GOSUB Send_morse_char, and so on. The last run is when eeprom is 81. After having sent this morse character, the processor waits 1000 milliseconds, and then starts over again.

Send_morse_char:
  IF morse = Space THEN    ' If Space then wait and return
    PAUSE (4 * Dot)        ' Word spacing is 7 dots; 3 dots elapsed already
    RETURN
  ENDIF
  DO                       ' Send one bit at the time in morse character
    IF bitToSend = 1 THEN
      GOSUB Send_dash
    ELSE
      GOSUB Send_dot
    ENDIF
    morse = morse << 1     ' shift left 1 bit, fill in zeros from the right
  LOOP UNTIL (morse = %10000000) ' the stop pattern is found, break out of loop
  PAUSE 2 * Dot            ' add 2 x dot spacing (the 3rd spacing was in Send_dot/Send_dash)
  RETURN

The subroutine
Send_morse_char is where the intelligence of the software is buried! The first part is rather simple: If morse contains a space, the processor will pause 4 dots in order to create a space between words. The length of spaces between words must be 7 dots. One dot elapsed in Send_dot (or in Send_dash) and 2 dots elapsed in PAUSE 2 * Dot.

The DO..LOOP executes the lines between DO and LOOP, and makes testing after the loop statement using UNTIL. This kind of loop will always run at least once.

Why is 10000000 (binary) called 'stop pattern'? When the MSB (leftmost bit) in morse has been sent, all bits are shifted left one position and zeroes are filled in from the right. If the bit pattern in morse then becomes 10000000 it indicates that all bits in the character have been sent. See the example below where morse is shifted left four times before the 'stop pattern' is detected: 
UNTIL (morse = %10000000)

1

0

1

0

1

0

0

0

Step 1. Send dash, shift left

0

1

0

1

0

0

0

0

Step 2. Send dot, shift left

1

0

1

0

0

0

0

0

Step 3. Send dash, shift left

0

1

0

0

0

0

0

0

Step 4. Send dot, shift left

1

0

0

0

0

0

0

0

Stop pattern (end  of character) 

Table 1. How the letter C in morse is processed.
Yellow indicates the bit to send (bitToSend). Orange indicates bits that are never sent.

Send_dot:
  Key = KeyOn
  FREQOUT Spkr, Dot, Pitch
  Key = KeyOff
  PAUSE Dot
  RETURN

The subroutine Send_dot turns the key pin on (Key = KeyOn). The built-in sine wave generator is then activated for Dot milliseconds. The Pitch is set and the output is sent to the Spkr pin. When done, the Key pin is turned off (Key = KeyOff). The subroutine waits Dot milliseconds before it returns to where it came from; that is the Send_morse_char routine. The relation between  morse speed and dot length is as follows: 

Send_dash:
  Key = KeyOn
  FREQOUT Spkr, 3 * Dot, Pitch
  Key = KeyOff
  PAUSE Dot
  RETURN

The subroutine Send_dash works nearly in the same way as Send_dot. The only difference is the duration of KeyOn, which is 3 times longer than the dot.

Morse characters in EEPROM 

The EEPROM part of the BS2 memory is written to using WRITE.

' Write to EEPROM:
'              c           q                   c          q
  WRITE 48, %10101000, %11011000, Space, %10101000, %11011000, Space
'              c           q                   d          e
  WRITE 54, %10101000, %11011000, Space, %10010000, %01000000, Space
'              o           z         1         e          u          o
  WRITE 60, %11110000, %11001000, %01111100, %01000000, %00110000, %11110000, Space
'              o           z         1         e          u          o
  WRITE 67, %11110000, %11001000, %01111100, %01000000, %00110000, %11110000, Space
'              o           z         1         e          u          o                 k
  WRITE 74, %11110000, %11001000, %01111100, %01000000, %00110000, %11110000, Space, %10110000

All morse characters (letters and numbers) are listed in the source code.

Space is a constant, which is defined like this:

Space     CON     32

Morse speed calculation 

The morse speed can be calculated using this formula ("The 1987 ARRL Handbook for the Radio Amateur", page 19-4):

speed (WPM) = 1.2 x clock_frequency

where clock_frequency =  1/Dot

In our case, the calculation goes like this:

clock_frequency = 1/Dot
clock_frequency = 1/(75 ms)
clock_frequency = 13.33 Hz

speed (WPM) = 1.2 x clock_frequency
speed (WPM) = 1.2 x 13.33 = 16 WPM

Speed 16 WPM is equal to 80 characters/minute.


Created 27-12-2009 by OZ1BXM Lars Petersen.

Go to my Basic Stamp experiments page