From pre-history... originally posted way back in 2002 to the PICBasic List...

Hi Jim

I threw this together for a giggle... (there's a secret message embedded within specially aimed it at you - and all the other budding radio hams out there)...

This little ditty reads ASCII (in this case stored in EEPROM) and outputs Morse on a pin... all of EEPROM is read sequentially only stopping when it encounters an ASCII null ($00) or reaches the end of EEPROM space.

Stick it in your favourite PIC, add a piezo transducer or speaker on PORTB.0 and enjoy...

Melanie

Code:
    '
    ' Hardware Assignments
    ' --------------------
    BeeperA var PORTB.0
        ' Hang your PIEZO Transducer on this pin

    '
    ' EEPROM
    ' ------
        ' Supported Characters
        ' Alphabetic A-Z in upper or lowercase ASCII
        ' Numeric 0-9
        ' Special Characters ' () ch : , - / . ? "
        ' Note that ASCII space is used between words
        ' Data is terminated with an ASCII NUll ($00)
        ' This example isn't because it is exactly 64 bytes
        ' long and equals the variable EEPROMMax, so it will
        ' fit into a 16F84 with only 64 bytes EEPROM
        '
    DATA @0,73,32,109,117,115,116,32,114,101,97,100,32,116,104,101
        ' I must read the
    DATA 32,80,73,67,66,65,83,73,67,32,109,97,110,117,97,108,32
        ' PICBASIC manual
    DATA 102,114,111,109,32,99,111,118,101,114,32,116,111,32
        ' from cover to
    DATA 99,111,118,101,114,32,68,101,32
        ' cover De
    DATA 74,73,77,32,66,65,76,76,83
        ' JIM BALLS

    '
    ' RAM Assignments and Variables
    ' -----------------------------
    ASCIIData var byte
        ' variable holding the ASCII data to translate
    CounterA var byte
        ' General Purpose varable
    MorseBitPointer var byte
        ' bit pointer within MorseCode data byte
    MorseCode var byte
        ' translated Character for Morse Code Signalling
    MorseEnable var word
        ' Word Character for Flags and Morse Timing
    ToneOut var word
        ' Variable used in Beeper Tone Generation routine
    TonePitch var word
        ' Variable used to Time Pitch of Beep (in uS)
    ToneTime var word
        ' Variable used to Time length of Tone Beep (in mS)

    '
    ' Program Constants
    ' -----------------
    DefaultBeepPitch con 185
        ' Default Tone Sound/Pitch (in uS)
    EEPROMMax con 64
        ' assumes this PIC has 64 bytes of EEPROM
    MorseDot con 10
        ' Time Interval for Dot (in 10mS increments)
        ' MorseDash would be 3*MorseDot
        ' MorseGap wpuld be 1*MorseDot (inter dot/dash space)
        ' MorseChar would 3*MorseDot (pause at end of character)
        ' MorseWord would be 8*MorseDot (pause at end of word)

    '
    ' Start Program
    ' =============
    goto JumpStart

    '
    ' Subroutine Nest Area
    ' ====================

    '
    ' Subroutine produces 2700Hz Beep
    ' -------------------------------
        ' ToneOut - tone loop counting variable
        ' TonePitch - variable determines PITCH of Beep (in uS)
        ' ToneTime - variable setting LENGTH of Beep (in mS)
BeepOut:
    TonePitch=DefaultBeepPitch
BeepRaw:
    For ToneOut=0 to ToneTime
        High BeeperA
        PauseUS TonePitch
        Low BeeperA
        PauseUS TonePitch
        Next ToneOut
    Return

    '
    ' Subroutine Sounds Out Morse Character
    ' -------------------------------------
SendMorseCode:
    If MorseCode=$FF then
        ' Execute Word Pause
        MorseEnable=MorseDot*80
        Pause MorseEnable
        Return
        endif
    MorseEnable=0
        ' Reset Enable
    For MorseBitPointer=0 to 7
        ' Loop Up to 8 Times
        If MorseEnable=0 then
            ' Check for Character Start Flag
            If MorseCode.7=1 then MorseEnable=1
            ' Set Morse Character Start Flag
            else
            ' If Morse sub-element Enabled, Send sub-element
            ToneTime=(50000/DefaultBeepPitch/10)*MorseDot
            ' Determine Morse Dot Time
            If MorseCode.7=1 then
                ToneTime=ToneTime*3
                ' Determine Morse Dash Time
                endif
            Gosub BeepOut
            ToneTime=MorseDot*10
            Pause ToneTime
            endif
        MorseCode=MorseCode<<1
        ' Shift to next Morse sub-element
        Next MorseBitPointer
    MorseEnable=MorseDot*30
        ' Determine & Execute End of Character Pause
    Pause MorseEnable
    Return

    '
    ' Subroutine Translates ASCII to Morse
    ' ------------------------------------
        '
        ' in case you were wondering, it's written the
        ' way it is (with short Looup tables) to minimise
        ' possible word-wrap when emailing this text
        '
TranslateASCIIMorse:
    MorseCode=0
        '
        ' Translate Numerics (0-9)
        ' ------------------------
    If ASCIIData>47 then
        If ASCIIData<58 then
            Lookup (ASCIIData-53),[$20,$30,$38,$3C,$3E],MorseCode
            ' 5 6 7 8 9
            endif
        If ASCIIData<53 then
            Lookup (ASCIIData-48),[$3F,$2F,$27,$23,$21],MorseCode
            ' 0 1 2 3 4
            endif
        endif
        '
        ' Translate Alphabetics (A-Z)
        ' ---------------------------
    If ASCIIData>96 then
        If ASCIIData<123 then ASCIIData=ASCIIData-32
        endif
    If ASCIIDATA>64 then
        If ASCIIData<91 then
              Lookup (ASCIIData-82),[$0A,$08,$03,$09,$11,$0B,$19,$1B,$1C],MorseCode
              ' R S T U V W X Y Z
              endif
        If ASCIIData<82 then
              Lookup (ASCIIData-73),[$04,$17,$0D,$14,$07,$06,$0F,$16,$1D],MorseCode
              ' I J K L M N O P Q
              endif
        If ASCIIData<73 then
              Lookup (ASCIIData-65),[$05,$18,$1A,$0C,$02,$12,$0E,$10],MorseCode
              ' A B C D E F G H
              endif
        endif
        '
        ' Translate special characters
        ' ----------------------------
    If ASCIIData=39 then MorseCode=$5E
            ' ' Apostrophe
    If ASCIIData=40 then MorseCode=$6D
            ' ( Brackets
    If ASCIIData=41 then MorseCode=$6D
            ' ) Brackets
    If ASCIIData=58 then MorseCode=$78
            ' : Colon
    If ASCIIData=44 then MorseCode=$73
            ' , Comma
    If ASCIIData=45 then MorseCode=$61
            ' - Hyphen
    If ASCIIData=47 then MorseCode=$32
            ' / Oblique Stroke
    If ASCIIData=46 then MorseCode=$55
            ' . Period
    If ASCIIData=63 then MorseCode=$4C
            ' ? Question
    If ASCIIData=34 then MorseCode=$52
            ' " Quotation Moarks
        '
        ' Translate Space
        ' ---------------
    If ASCIIData=32 then MorseCode=$FF
    Return

    '
    ' End of Subroutine Nest Area
    ' ---------------------------

    '
    ' Actual Start of Real Program
    ' ============================
JumpStart:
        '
        ' Set Hardware Directions
        ' -----------------------
    TRISB=%00000000
        '
        ' Timeout to Reset Hardware
        ' -------------------------
    Pause 250
    '
    ' Read EEPROM and Output Morse
    ' ----------------------------
RepeatLoop:
    For CounterA=0 to EEPROMMax-1
        Read CounterA,ASCIIData
        If ASCIIData=0 then goto ExitLoop
        Gosub TranslateAsciiMorse
        Gosub SendMorseCode
        Next CounterA
    '
    ' Timeout 5 seconds and start all over again
    ' ------------------------------------------
ExitLoop:
    Pause 5000
    Goto RepeatLoop

    '
    End