Der Morsedecoder zwo


von Ralf Beesner, DK5BU
Elektronik-Labor   Projekte   AVR 



Eigentlich befand ich mich auf Streifzug, um anderer Leute Code für ein eigenes Projekt zu "klauen", aber als ich auf Burkhard Kainkas AVR- Butterfly- Morsedecoder stieß, habe ich es vorgezogen, erst einmal sein Programm auszuprobieren.

Da ich kein AVR- Butterfly besitze, habe ich den Code auf den ATmega8- Prozessor und HD4480- kompatible LCD-Displays abgeändert (das abgebildete myAVR- Board finde ich praktisch, weil man eigene Erweiterungsboards auf Lochrasterbasis sehr schön anflanschen kann).

Burkhards Code gibt lediglich Buchstaben und Zahlen auf dem Display aus. Ich habe die Tabelle um die gebräuchlichen Sonderzeichen ergänzt.

Außerdem fand ich es störend, daß die LCD-Ausgabe keine Leerzeichen bei Wortpausen einfügt. Viele Leute geben nicht nur die Einzelzeichen zu dicht hintereinander (im Telegrafisten-Jargon "schmieren" genannt), sondern halten auch die Wortabstände nicht richtig ein.

Ich habe daher den Code so umgebaut, dass er bei einer Pause von mehr als 2,5 Punktlängen ein (genau ein) Leerzeichen auf das LCD ausgibt.

Das "Befüllen" des Arrays habe ich etwas abgeändert. Zunächst werden alle Felder mit "?" aufgefüllt und dann die gültigen Zeichen ins Array geschrieben. So gibt das Programm ein "?" aus, wenn ein Zeichen nicht decodiert werden kann.

Da mir 60 Zeichen/Minute etwas zu langsam war, habe ich die "hart codierten" Wait-Statements durch Konstanten ersetzt. Die Konstanten werden zu Anfang des Programms aus der Konstante "Dit", der Länge eines Punkts, abgeleitet. Für eine mittlere Geschwindigkeit von 90 Zeichen/Minute muß man also 100 durch 66 ersetzen.

Da Morsetasten wie alle Schalter prellen, musste ich einen Kondensator von 330 nF über die Tastenanschlüsse legen; er bildet zusammen mit dem internen Pullup-Widerstand des AVR einen Tiefpass.

Aus Jux habe ich meine alte mechanisch-halbautomatische Taste an den Decoder angeschlossen. Bei diesen Tasten formt man die Striche einzeln von Hand,indem man den Hebel jeweils nach links drückt, und erzeugt eine Folge von Punkten, indem man ihn nach rechts drückt.

Die Punktfolge wird durch ein waagrechtes Pendel mit einem verschiebbaren Gewicht erzeugt; bei der maximalen Auslenkung des Pendels nach links wird jeweils ein kleiner Federkontakt geschlossen. Da das Pendel einige Sekunden lang schwingen soll, darf es nur wenig bedämpft werden. Dies führt zu ausgeprägtem Prellen des Punktkontakts. Mit 330 nF ist der AVR aber selbst dieser extremen Herausforderung gewachsen.

Die Punktfolge setzt leicht verzögert ein und die Punkte werden auch nicht automatisch auf normgerechte Länge ergänzt. Deshalb ist das saubere Geben mit einer solchen Taste fast unmöglich, wenn man an elektronische Tasten gewöhnt ist. Zur Zeit sind diese Tasten dennoch bei einigen Schnelltelegrafisten "en vogue", weil die gleichförmigen elektronisch erzeugten Zeichen ihnen zu "langweilig" klingen.

Man sollte aber etwas offline üben, bevor man sich damit "on the air" wagt - z.B. mit dem Morsedecoder zwo.

Download Morsedecoder.zip

'-----------------------------------------------------------------------------------------
' Burkhard Kainka
' morse.bas
' morce code decoder with Mega169 and LCD butterfly driver
' using butterfly joystick as morse key
'
' screwed up by Ralf Beesner, DK5BU
' changed für use with an ATMega8 and HD4480-compatible LCD Display
' keyer is attached to PB0 now, Buzzer to PB1
' LCD is attached to Port D; Details see "Config LCD" Statement
' some keycodes have been added, e.g. + - ? ( ) . ,
' and, most important keycode: space between words ;-)
' all timing constants are derived from the duration of a short morse element ("dit"), so its easier
' to change speed

'-----------------------------------------------------------------------------------------

$regfile = "m8def.dat" ' specify the used micro
$crystal = 3686400 ' used crystal frequency
$baud = 9600 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space



Dim Text As String * 16
Dim Key As Byte
Dim C As Byte
Dim Code(255) As Byte
Dim N As Integer
Dim Timepressed As Word
Dim Timenotpressed As Word
Dim Charactercode As Byte
Dim Idling As Word

Declare Sub Getkey
Declare Sub Getkeytimes
Declare Sub Initcode
Declare Sub Printdisplay




Const Dit = 100 ' duration of a dit in ms; speed is 60 characters / min.
'Const Dit = 66 ' duration of a dit in ms; speed is 90 charcters / min.


Const Dithalf = Dit / 2 ' helps to avoid computing in integers
Const Tpconst = Dithalf * 3 ' 1.5 * Dit; maximum tinme for a dit
Const Tnpconst = Dithalf * 4 ' 2 * Dit; minimum time for a dah
Const Iconst = Dithalf * 5 ' 2.5 * Dit; time for a space between morse words


Portb = &HFF ' pullups for Port B
Portc = &HFF ' pullups for Port C


' Timer 1 is configured for Sound at OC1A / PB1
Config Timer1 = Pwm , Prescale = 8 , Pwm = 9 , Compare A Pwm = Clear Down
Pwm1a = 0 'no sound


Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2



Initcode 'prepare code table
Cls
Text = "MORSE DECODER "
Lcd Text


Do
Charactercode = 1
Do
Getkeytimes
If Idling > Iconst Then ' space between morse words
Gosub Printdisplay
Charactercode = 1
End If
Charactercode = Charactercode * 2
If Timepressed > Tpconst Then
Charactercode = Charactercode + 1
End If
Loop Until Timenotpressed > Tnpconst
Gosub Printdisplay

Loop


Sub Printdisplay
C = Code(charactercode)
Text = Text + Chr(c)
Text = Right(text , 15)
Cls
Lcd Text
End Sub


Sub Getkey
Key = Not Pinb.0 ' Keyer is attached to PB0, key_pressed -> low
If Key > 0 Then
Pwm1a = 80
Else
Pwm1a = 0
End If
End Sub




Sub Getkeytimes
Timepressed = 0
Timenotpressed = 0
Idling = 0
Do
Getkey
Waitms 1
Idling = Idling + 1
Loop Until Key > 0

Do
Waitms 1
Timepressed = Timepressed + 1
Getkey
Loop Until Key = 0
Do
Waitms 1
Timenotpressed = Timenotpressed + 1
Getkey
Loop Until Key > 0 Or Timenotpressed > Tnpconst
End Sub





Sub Initcode


For N = 1 To 255 ' fill all Fields with "?"
Code(n) = 63
Next N
Code(1) = 32 ' "space"
Code(2) = 69 ' "E", . , 00000010, ASCII 69
Code(3) = 84 ' "T", - , 00000011, ASCII 84
Code(4) = 73 ' "I", .. , 00000100, ASCII 73
Code(5) = 65 ' "A", .- , 00000110, ASCII 65
Code(6) = 78 ' "N", -. , 00000110, ASCII 78
Code(7) = 77 ' "M", -- , 00000111, ASCII 77
Code(8) = 83 ' "S", ... , 00001000, ASCII 83
Code(9) = 85 ' "U", ..- , 00001001, ASCII 85
Code(10) = 82 ' "R", .-. , 00001010, ASCII 82
Code(11) = 87 ' "W", .-- , 00001011, ASCII 87
Code(12) = 68 ' "D", -.. , 00001100, ASCII 68
Code(13) = 75 ' "K", -.- , 00001101, ASCII 75
Code(14) = 71 ' "G", --. , 00001110, ASCII 71
Code(15) = 79 ' "O", --- , 00001111, ASCII 79
Code(16) = 72 ' "H", .... , 00010000, ASCII 72
Code(17) = 86 ' "V", ...- , 00010001, ASCII 86
Code(18) = 70 ' "F", ..-. , 00010010, ASCII 70
Code(20) = 76 ' "L", .-.. , 00010100, ASCII 76
Code(22) = 80 ' "P", .--. , 00010110, ASCII 80
Code(23) = 74 ' "J", .--- , 00010111, ASCII 74
Code(24) = 66 ' "B", -... , 00011000, ASCII 66
Code(25) = 88 ' "X", -..- , 00011001, ASCII 88
Code(26) = 67 ' "C", -.-. , 00011010, ASCII 67
Code(27) = 89 ' "Y", -.-- , 00011011, ASCII 89
Code(28) = 90 ' "Z", --.. , 00011100, ASCII 90
Code(29) = 81 ' "Q", --.- , 00011101, ASCII 81
Code(32) = 53 ' "5", ..... , 00100000, ASCII 53
Code(33) = 52 ' "4", ....- , 00100001, ASCII 52
Code(35) = 51 ' "3", ...-- , 00100011, ASCII 51
Code(39) = 50 ' "2", ..--- , 00100111, ASCII 50
Code(50) = 47 ' "/"
Code(42) = 43 ' "+" .-.-. , 00101010 ASCII 43
Code(44) = 115
Code(45) = 49
Code(47) = 49 ' "1", .---- , 00101111, ASCII 49
Code(48) = 54 ' "6", -.... , 00110000, ASCII 54
Code(49) = 61 ' "="
Code(54) = 40 ' "("
Code(56) = 55 ' "7", --... , 00111000, ASCII 55
Code(59) = 32
Code(60) = 56 ' "8", ---.. , 00111100, ASCII 56
Code(62) = 57 ' "9", ----. , 00111110, ASCII 57
Code(63) = 48 ' "0", ----- , 00111111, ASCII 48
Code(76) = 63 ' "?"
Code(82) = 34 ' ""
Code(85) = 46 ' "."
Code(97) = 45 ' "-"
Code(109) = 41 ' ")"
Code(115) = 44 ' ","
Code(120) = 58 ' ":"

End Sub


Elektronik-Labor   Projekte   AVR