PICAXE-08M2 Simplified Morse Code ID/Beacon Generator
The ease at which to program the PICAXE is truly astounding. I thought a Morse code generator would be a "NO BRAINER" but was caught off guard. There are so many different ways to create this type of code.
Most programs need the user to map the ASCII to a binary code to create the data string. "That hurt my head." I just wanted to enter a string of ASCII and let the MCU handle the mapping.
This was cobbled together from some interesting snippets of code found by scanning around the forum and READING all things of interest.
QUOTE: mrburnette: "It is by evolving concepts and existing code bases that code evolution occurs"
Discovering new ways to optimize my code to fit in a restricted microcontroller environment like the PICAXE has helped me to become a better programmer.
The RC network you see on the breadboard acts as a low pass filter to remove the harmonics and is just to soften the harsh tone from the piezo transducer.
To copy code:
Hover over the right top corner of the code panel.
Click COPY button, the code will be COPIED to the clipboard.
#REM
-----------------------------------------------------------------------
PICAXE-08M2 Simplified Morse Code Generator - rhb.20230913
NOTE: Only alpha and numerals are used in this demonstration.
Other characters included are comme nted out.
This was to made to fit into an old 08M,
which was the original CW IDer for my 1W QRP rig.
-----------------------------------------------------------------------
NOTES: Physical Connections
pin C.1 LED output, or TR key out with transistor (2N3904) driver
pin C.2 SIDE-TONE output is a simple piezo speaker
-----------------------------------------------------------------------
Morse Code Alphanumeric Character Encoding
------------------------------- ----------------------------------------
Each character to be generated is programmed as a number whose
binary equivalant then generates Morse code.
Test the MSB (Most Significant Bit) to represent dits and dahs.
dot = dit = 0
dash = dah = 1
One (1) bit on the end of the Morse Character to detect a stop
shifting left until the byte equals 128 ($80)
Example Letter Conversion:
k = -.- Morse pattern
k = 101 Replace dash and dots with binary 1 and 0
k = 10 11 Add 1 bit to end
k = 10110000 Pad with 0 bits to make a 8 bit BYTE
k = %10110000 Defined data as binary value
k = $B0 Defined data as HEX value
k = 176 Defined data as Decimal value
------------------------------------- ----------------------------------
Visual Table of Morse Code HEX Values
-----------------------------------------------------------------------
ASCII Shift-Left Code
Letter Morse Binary HEX
A .- 0110 0000 $60
B -... 1000 1000 $88
C -.-. 1010 1000 $A8
D -.. 1001 0000 $90
E . 0100 0000 $40
F ..-. 0010 1000 $28
G --. 1101 0000 $D0
H .... 0000 1000 $08
I .. 0010 0000 $20
J .--- 0111 1000 $78
K - .- 1011 0000 $B0
L .-.. 0100 1000 $48
M -- 1110 0000 $E0
N -. 1010 0000 $A0
O --- 1111 0000 $F0
P .--. 0110 1000 $68
Q --.- 1101 1000 $D8
R .-. 0101 0000 $50
S ... 0001 0000 $10
T - 1100 0000 $C0
U ..- 0011 0000 $30
V ...- 0001 1000 $18
W .-- 0111 0000 $70
X -..- 1001 1000 $98
Y -.-- 1011 1000 $B8
Z --.. 1100 1000 $C8
-------------------------------------------------------- ---------------
ASCII Shift-Left Code
Number Morse Binary HEX
0 ----- 1111 1100 $FC
1 .---- 0111 1100 $7C
2 ..--- 0011 1100 $3C
3 ...-- 0001 1100 $1C
4 ....- 0000 1100 $0C
5 ..... 0000 0100 $ 04
6 -.... 1000 0100 $84
7 --... 1100 0100 $C4
8 ---.. 1110 0100 $E4
9 ----. 1111 0100 $F4
-----------------------------------------------------------------------
Punctuation
----------------------------------------- ------------------------------
e.g. (SK) Digraph are sent together without a character space
word space [space key] 1000 0000 $80
exclamation mark (KW)[!] -.-.-- 1010 1110 $AE
quotation mark ["] .-..-. 0100 1010 $4A
h ashtag [#]
dollar sign (SX)[$] ...-..- 0001 0011 $13
percent [%]
ampersand (AS)[&] .-... 0100 0100 $44
apostrophe ['] .----. 0111 1010 $7A
parenthesis open (KN)[(] -.--. 1011 0100 $B4
parenthesis closed [ )] -.--.- 1011 0110 $B6
asterisk [*]
plus (RN)[+] .-.-. 0101 0100 $54
comma [,] --..-- 1100 1110 $CE
hyphen minus [-] -....- 1000 0110 $86
full stop (period) [.] .-.-.- 0101 0110 $56
forward sla sh (DN)[/] -..-. 1001 0100 $94
colon [:] ---... 1110 0010 $E2
semicolon [;] -.-.-. 1010 1010 $AA
less than [<]
equal sign (BT)[=] -...- 1000 1100 $8C
greater than [>]
question mark [?] ..--.. 0011 0010 $32
at-sign (commat) (AC)[@] .--.-. 0110 1010 $6A
underscore [_] ..--.- 0011 0110 $36
-----------------------------------------------------------------------
Procedural
------------------------------------------- ----------------------------
Start of work (CT) -.-.- 1010 1010 $AA
End of work (SK) ...-.- 0001 0110 $16
Invitation to transmit (K) -.- 1011 0000 $B0
Invitation for a particular
station to transmit
(KN) -.--. 1011 0100 $B4
End of message (AR) .-.-. 0101 0100 $54
Wait (AS) .-... 0100 0100 $44
Understood (SN) ...-. 0001 0100 $14
Error (8 dits) (HH) ........ 1111 1111 $FF
---------------- -------------------------------------------------------
Traditional Timing
-----------------------------------------------------------------------
1 dit = 1 dit
1 dah = 3 dits
letter space = 3 dits
word spacing = 7 dits
---- -------------------------------------------------------------------
Farnsworth Timing
-----------------------------------------------------------------------
letter space = 9 dits
word spacing = 21 dits
------------------------------------- ----------------------------------
#ENDREM
#PICAXE 08M2
;#terminal 4800 ; Used only for Morse speed test ; remove to save bytes
;pause 3000 ; Used only for Morse speed test ; remove to save bytes
' ----------------------------------------- ----------------------------
' Constants
' ---------------------------------------------------------------------
symbol tone = 96 ; sets the tone frequency ( ~750 Hz )
symbol silent = 0 ; set silent tone (or QRSS tone 118/122)
symbol dit_time = 9 ; set length of a dot (mS) approx. ~12wpm
; tone timing and overhead of interpreted BASIC
symbol dah_time = dit_time * 3 ; set length of a dash (3 dits)
symbol letter_time = dit_time * 3 ; set sp ace between letters (3 dits)
symbol word_time = dit_time * 7 ; set space between words (7 dits)
; NOTE:
; Because after each letter is a letter_time (3 dits),
; the actual word_time is (10 dits)
' ------------ ---------------------------------------------------------
' Port Assignments
' ---------------------------------------------------------------------
symbol LED_TR_OUT = c.1 ; LED output or TR key out
symbol SIDE_TONE_OUT = c.2 ; SIDE-TON E output is a simple piezo speaker
' ---------------------------------------------------------------------
' Variables
' ---------------------------------------------------------------------
symbol character = b0 ; BIT register for Morse C ode character
symbol i = b4 ; ASCII value from MESSAGE string
symbol j = b5 ; pointer to ASCII character in MESSAGE string
symbol k = b6 ; pointer Morse Code offset in defined string MORSE_A2Z
symbol m = b7 ; use only for s peed test ; remove or reuse variable
symbol z = b8 ; use only for speed test ; remove or reuse variable
' ---------------------------------------------------------------------
' MACRO Directives
' --------------------------------------------- ------------------------
' STANDARD Message
#DEFINE MESSAGE_0 "CQ CQ CQ DX DE VE3XRM VE3XRM VE3XRM [ K"
' Note: The [ is an extended character to send End of message (AR)
' SPEED TEST - put in a loop and count how many in a minute
#DEFINE MESSA GE_2 "PARIS "
' PANGRAM Holoalphabetic Sentence
#DEFINE MESSAGE_Z "A QUICK BROWN FOX JUMPS OVER THE LAZY DOG 1234567890 "
#DEFINE MESSAGE_Y "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 "
#DEFINE MORSE_A2Z $80,$FC,$7C,$3C,$1C,$0C,$04,$84,$C4,$E4,$F4,$60 ,$88,$A8,$90,$40,$28,$D0,$08,$20,$78,$B0,$48,$E0,$A0,$F0,$68,$D8,$50,$10,$C0,$30,$18,$70,$98,$B8,$C8,$54
#MACRO SendMORSE( string )
j = 0
do
lookup j, ( string, 0 ), i
if i = 0 then exit
call MORSE
loop
#ENDMACRO
' ----------- ----------------------------------------------------------
' Main Program Start
' ---------------------------------------------------------------------
MAIN:
' e.g. Send Morse from a quoted string
'SendMORSE("CQ CQ CQ DX DE VE3XRM VE3XRM V E3XRM AR K")
#REM This is what is placed inline everytime you use SendMORSE()
j = 0
do
lookup j, ( string, 0 ), i
if i = 0 then exit
call MORSE
loop
#ENDREM
' Send Morse from a pre-defined symbol
'SendMORSE(MESSAGE _0)
' All letters and numbers
'SendMORSE(MESSAGE_Y)
' Sample Morse Pangram
SendMORSE(MESSAGE_Z)
' Used only to estimate PICAXE timing ; remove to save bytes
' call MORSE_SPEED_TEST
' IDer Timer - use with a short message as abov e e.g.
'for i = 0 to 9 ; wait ten (10) minutes for next CW ID
' pause 60000 ; wait a minute, then repeat bacon message
'next i
goto MAIN
'----------------------------------------------------------------------
' Subroutines
'-------------- --------------------------------------------------------
MORSE_SPEED_TEST: ' NOTE: remove subroutine to save bytes
' Morse Speed Test - Effect of increased clock speed
' The time function will increment
' at 4 MHz or 16 MHz once every secon d
' at 2 MHz and 8 MHz will be 2s
' at 32 MHz will be 0.5s
' e.g.
' 32 MHz 0.5s
' 16 MHz 1s
' 8 MHz 2s
' 4 MHz 1s
z = 0
m = time + 60
sertxd ("START: ", #time, CR, LF)
do
SendMORSE(MESSAGE_2)
inc z
loop u ntil time > m
sertxd ("END: ", #time, CR, LF)
sertxd ("WPM: ", #z, CR, LF)
return
MORSE:
if i = 32 then
k = 0
elseif i < "A" then ; maybe a number if less than 65
k = i - 47 ; i - 48 + 1 calc offset to numbers
else
k = i - 54 ; calc offset to letters
end if
lookup k, ( MORSE_A2Z ), character
if character = $80 then
gosub word_space
else
do until character = $80
' Testing a bit is equivalent to
' bit_value = character & %10000000 ; ma sk left most bit to test
' Then Test MSB of element
' if bit_value = $80 then
' character variable must be in one of the bit registers - here using b0
if bit7 = 1 then
gosub dah ; if bit 1 do dah sub-routine
else
g osub dit ; else it's 0 do dit sub-routine
endif
' Left shift on all the bits in character.
' 08M & 08M2 doesn't have a shift function.
'character = character * 2 ; multiply shift
character = character + character ; ad dition shift
loop
gosub char_space
end if
inc j ; same as j = j + 1 ; inc counter to point at next character
return
dit:
high LED_TR_OUT
sound SIDE_TONE_OUT,(tone,dit_time) ; sound tone for dit length
low LED_TR_OUT
sou nd SIDE_TONE_OUT,(silent,dit_time) ; silence for dit length
return
dah:
high LED_TR_OUT
sound SIDE_TONE_OUT,(tone,dah_time) ; sound tone for dah length
low LED_TR_OUT
sound SIDE_TONE_OUT,(silent,dit_time) ; silence for dit length
return
char_space:
sound SIDE_TONE_OUT,(silent,letter_time) ; send silence for dah length after char completely sent
return
word_space:
sound SIDE_TONE_OUT,(silent,word_time) ; send silence for break between words
return
'------------------------ ----------------------------------------------
;EOF;
posted/edited by Ralph [VE3XRM] | 20241114 | 20:10
These projects require simple skills in electronics assembly and programming.
Minimal instructions might be provided.
5 Page Views [1]