mor-sux, ein Morsetrainer nach der Koch-Methode


von Ralf Beesner, DK5BU
Elektronik-Labor   Projekte   AVR 




Roland Walter, DL7UNO, veröffentlichte auf seiner speziell eingerichteten Website www.flohjagd.de eine Bauanleitung für den Mini-Fuchsjagdsender "Foxy", der neben einem ISM-Senderschaltkreis für 433,92 MHz mit einem ATtiny45 bestückt ist. Unter den Bascom-Beispielprogrammen findet sich eines, das den Zufallszahlengenerator benutzt, um Telegrafie-Fünfer-Gruppen zu erzeugen. Ich habe damit so lange herumgespielt, bis auf die Initialisierung des Zufallsgenerators nichts mehr übrigblieb; herausgekommen ist ein Morsetrainer mit zwei Modi:

Modus 1 erzeugt Fünfer-Gruppen mit wählbarem Zeichenumfang und wählbarer Geschwindigkeit; Modus 2 erzeugt Klartextwörter, die aus einem längeren Text zufällig zusammengewürfelt werden, auch hier ist die Geschwindigkeit einstellbar. Diese "große Version" habe ich lediglich auf einem Experimentiersystem für Atmega8 verdrahtet und getestet. Auf einer Streifenrasterplatine realisiert habe ich aber eine kleinere Version mit einem Attiny24, die nur Modus 1, also Fünfergruppen "kann".

Morsen lernen?

Nur wenige Menschen werden heute noch Morsen lernen wollen; die Blütezeit des Amateurfunks ist eh vorbei und Morsetelegrafie wird in der Amateurfunkprüfung nicht mehr gefordert. Aber "tot" ist die Morsetelegrafie auf den Amateurfunkbändern noch lange nicht; sie ist reizvoller als Datenbetriebsarten wie PSK31, bei denen die Leute eigentlich nur noch ihre vorprogrammierten Standardtexte "abnudeln", und Telegrafie benötigt weniger Sendeleistung und weniger gute Antennen als SSB- Sprechfunk.

Und morsen ist cool - chatten oder telefonieren kann ja jeder (im Internet) .

Als ich vor fast 40 Jahren Telegrafie im Selbststudium lernte, gab es nur Morsekurse auf Schallplatte oder Tonband. Die Länge der Lektionen war notorisch zu gering; irgendwann konnte ich Teile der Fünfer-Gruppen auswendig hinschreiben; bei Klartext reichte zwei- oder dreimaliges Abspielen, um große Teile aus dem Gedächtnis und nicht nach dem Höreindruck niederschreiben zu können.

Insbesondere das Üben mit Klartext ist jedoch wichtig, denn während man Fünfer-Gruppen irgendwann mechanisch ohne großes Nachdenken mitschreiben kann, kommt man bei der gleichen Geschwindigkeit bei Klartext "ins Schleudern", weil man anfängt, die Buchstaben zusammenzusetzen und bestimmte Wörter zu erwarten. Wenn dann statt des erwarteten Wortes ein anderes erscheint, kommt man völlig aus dem Takt.

Mit dem Aufkommen der Homecomputer und PCs wurde das Morsenlernen im Selbststudium stark vereinfacht; man war aber an das Gerät gebunden. Irgendwann brachte eine Schweizer Firma einen Morsetrainer auf Mikrocontrollerbasis namens "Morsix" heraus, der es ermöglichte, ein kleines Kästchen mit sich herumzutragen und dann Morse zu üben, wenn man gerade etwas Zeit hatte (ohne auf Netzanschluss und PC angewiesen zu sein). Da Gerät hatte seinen Preis und war sicherlich viel schöner als meine Lösung; aber meine ist billiger und selbstgemacht. Und der Name steht für was ganz anderes; er leitet sich von "more sucks" ab ;-)


Hardware

Der Atmega8 arbeitet mit 1 MHz Takt aus dem internen RC- Oszillator; ein fabrikfrischer Atmega kann also ohne umfusen verwendet werden. Die Stromversorgung erfolgt über eine 2-polige Klemme, an die z.B. ein Batteriekasten für 3 Mignonzellen angeschlossen werden kann. Die Frequenz des Atmega8-1-MHz-RC-Oszillators ist übrigens deutlich betriebsspannungsabhängig. Betreibt man den Mikrocontroller mit 3 V statt 4,5 bzw. 5 V, werden die Zeichen hörbar langsamer.

Über zwei "Mäuseklaviere" mit 4 Bit bzw. 5 Bit werden Geschwindigkeit und Lektionsnummer vorgewählt. Gestartet wird das Programm über einen Resettaster. Abgeschaltet wird das Gerät über einen Taster an PD2/INT0, der den Prozessor in den Powerdown schickt, so dass er ständig an der Batterie verbleiben kann.

Die Lautstärke des Morsetons ist über das Poti R1 einstellbar, die Tonhöhe über das Poti R2.
 
Die Ausgabe der Morsetöne kann entweder über einen Buzzer oder eine Anschlussbuchse für Stereo- Ohrhörer erfolgen. Der Atmega8 erzeugt Rechecksignale; der Buzzer dämpft durch seinen begrenzten Frequenzbereich und seine Kapazität die Oberwellen und die "Schaltknackse" etwas.

Bei der Kopfhörer-Variante wird nicht nur der Pegel auf Kopfhörer-taugliche Werte herabgesetzt, sondern C2 und C3 bilden mit den Widerständen einen Bandpass, der die Schaltknackse und Oberwellen auf akzeptable Werte dämpft.






Software - Modus 1

Nach einem Druck auf den Reset- Taster fragt die Software die Stellung der "Mäuseklaviere" für Geschwindigkeit und gewünschte Lektion ab.

Der Geschwindigkeitsbereich reicht von 15 Zeichen pro Minute (ZpM) bis 100 ZpM. Bei Geschwindigkeiten unter 70 ZpM werden die Pausen zwischen den Zeichen verlängert, während die Eigengeschwindigkeit der Zeichen weiterhin 70 ZpM beträgt. So lernt man auch bei geringen Geschwindigkeiten das charakteristische Klangbild der Zeichen (statt Punkte und Striche mitzuzählen).

Bei den Lektionsnummern 1-26 erfolgt die Ausgabe von Fünfer-Gruppen; Lektion 1 beginnt mit nur zwei Zeichen, mit jeder Lektion kommen zwei Zeichen dazu. Die Lektionen sind nach der Koch-Methode aufgebaut, die versucht, möglichst verschiedenartig klingende Zeichen hinzuzunehmen, damit man sich  das Klangbild einprägt, statt Punkte und Striche abzuzählen.

Mit den drei letzten Lektionen kommen auch Umlaute dazu, die man sich nicht entgehen lassen sollte, wenn man im deutschsprachigen Raum herumfunken möchte.

Die auszugebenden Morsezeichen stecken in der Tabelle "Morsezeichentabelle_1". Die Reihenfolge der Zeichen entspricht der Koch- Methode. Der aus dem "Mäuseklavier" ausgelesene Bytewert bestimmt die Obergrenze der Zahl, die der Zufallsgenerator "würfelt".




Software - Modus 2

Lektionsnummern über 26 verzweigen in den Klartext-Modus; hier wird der komplette Zeichensatz zugrundegelegt und es werden aus einem längeren Text zufällig zusammengewürfelte Wörter wiedergegeben. Um es etwas schwieriger zu machen, werden auch Satz- und Sonderzeichen eingestreut. Um Urheberrechtsproblemen aus dem Wege zu gehen, habe ich den zugrundeliegenden Text aus einem eigenen "Machwerk" und aus zwei Beiträgen von Burkhards Website zusammenkopiert,

Der Suchalgorithmus für ein Wort arbeitet in zwei Schritten: zunächst wird ein zufälliger Datastring der "Klartext_tabelle" eingelesen: Im zweiten Schritt wird dann eine zufällige Position innerhalb des Strings angesteuert und ab dort nach einem Leerzeichen gesucht. Ab dem Leerzeichen wird das Wort in Telegrafie ausgegeben. Bei Erreichen eines weiteren Leerzeichens wird eine Wortpause eingeschoben und der Suchalgorithmus neu gestartet.


Software - Geschwindigkeitsmessung

Lektionsnummer 0 gibt das Wort "Paris" aus. Es ist das Normwort, mit dem die Morsegeschwindigkeit gemessen wird. Die Wahl des Wortes "Paris" wirkt heutzutage etwas skurril, aber Paris war (oder ist?) der Sitz der ITU, die mal die weltweiten Fernmelde- Standards festlegte, aber im Zeitalter des Internet und der der RFCs nach Bedeutung ringt.



Eigene Texte

Die Datastrings in "Klartext_tabelle" kann man durch eigene0611Morsen1.jpg Texte ersetzen. Voraussetzung ist der Besitz einer Vollversion von Bascom, da der Code 4 kByte überschreitet. Am besten eignen sich HTML- Texte oder Word- Files, da sie keine hart codierten Zeilenumbrüche aufweisen. Ein Data- String darf max. 254 Zeichen enthalten. Man muß daher den herangezogenen Text rechtzeitig umbrechen und eine neue Data- Zeile anlegen (ich habe die Grenze nicht bei 254 gewählt, sondern bei 155, da die Zeilen dann komplett auf meinen Monitor passten).  


Flashen

Wer keinen Programmer für Atmega8 hat, kann ihn sich provisorisch aus 4 Bauteilen auf einem Steckbrett aufbauen und mit Burkhard Kainkas Programm "ISPmega8.exe" flashen.



mor-sux und less-sux

Die Attiny24-Version habe ich "less-sux" genannt. Wegen des kleineren Flash- Speichers musste der Klartext-Modus wegfallen; less-sux "kann" nur Fünfergruppen und den Paris-Testmodus. Auf einen Attiny84 läßt sich die komplette mor-sux- Software mit minimalen Änderungen portieren, aber ich hatte nur einen Attiny24 zur Hand.




Hardware

Der ATtiny24 arbeitet ebenfalls mit 1 MHz Takt aus dem internen RC- Oszillator; ein fabrikfrischer Attiny24 kann also ohne umfusen verwendet werden. Die Stromversorgung erfolgt über eine 2-polige Klemme, an die z.B. ein Batteriekasten für 2 Mignonzellen angeschlossen werden kann. Die Taktfrequenz des Atiny24-RC-Oszillators ist nur wenig betriebsspannungsabhängig, daher wirkt es sich kaum aus, ob er mit 2 oder 3 Mignonzellen betrieben wird (lediglich die Lautstärke des Buzzers ist etwas geringer). Die Bedienelemente entsprechen weitgehend der "mor-sux"-Version, allerdings gibt es eine Ausnahme: da kein Port mehr frei war, ist das Ein- und Ausschalten herkömmlich über einen Schiebeschalter gelöst (Schalter 6 des Mäuseklaviers S1).




Bedienung

Zu Schluss die Bedienung in Kurzform:

  Wahl der Geschwindigkeit über das Mäuseklavier S2
     Geschwindigkeiten: 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100 ZpM

  Wahl der Lektion über das Mäuseklavier S1
     Lektion 0 : Paris- Schleife
     Lektionen 1-26 : Fünfergruppen nach der Koch- Methode
     Reihenfolge der Zeichen: K M U R E S N A P T L W I . J Z - F O Y , V G 5 / Q 9 2 H 3 8 B ? 4 7 C 1 D 6 Ø X = : ( ) + " ä ö ü <ch> <KA>
     Lektion 27 : Klartext (entfällt bei less-sux)

  Start durch Drücken des Reset- Tasters S3 (mor-sux)
  Abschalten durch Drücken des Tasters S4 (mor-sux)
  Ein- Ausschalten und Reset durch Schalter 6 des Mäuseklaviers 1 (less-sux) 

Download:
Bascom-Quelltexte und Hex-Files (Update 5.11.12): Morsetrainer.zip
Dieser Aufsatz als PDF: Morsetrainer.pdf

'
' Mor-sux Attiny24: Morsetrainer für 5er- Gruppen nach der Koch- Methode.
' Der Zeichensatz beginnt in der ersten Lektion mit 2 Zeichen;
' Bei jeder Lektion kommen zwei Zeichen dazu (bis Lektion 23)
' optionale Lektionen 24 - 26 sind Umlaute
' Pseudo- Lektionsnummer 0 erzeugt PARIS- Schleife (für Geschwindigkeitskontrolle)
' Lektionsnummer wird mit Mäuseklavier an PA0...PA4 eingestellt
'
' Pin PA6 wird als Timer1-Ausgang OC1a verwendet, Ton wird durch Umschalten des
' Pins als Eingang / Ausgang ein- und ausgeschaltet. Tonhöhe wird über Poti an PA5
' und den ADC eingestellt.
'
' Geschwindigkeit ist in 11 Stufen schaltbar (4 Bits an PB0 bis PB2 und PA7).
' Unter 60 ZPM werden die Pausen verlängert, um auf niedrigere Geschwindigkeiten zu kommen
' ( 15 Zeichen pro Minute bis 100 ZPM)
'
'
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'
' Grundeinstelllungen:
$regfile = "attiny24.dat"
$crystal = 1000000
$hwstack = 40
$swstack = 10
$framesize = 20



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

'Variablen und Konstanten dimensionieren:
'
Dim Weerndinit As Eram Word ' Initialisierungswert für den Pseudo-Zufallsgenerator im EEPROM
Dim ___rseed As Word ' Initialisierungs-Variable des Pseudo-Zufallsgenerators, siehe Bascom-Hilfe unter "Rnd()"
'
Dim I As Byte ' Für temporären Gebrauch als Schleifenzähler
Dim M As Byte ' Index des aktuellen Morsebuchstabens in unserer Tabelle
Dim L As Byte ' für niederwertigstes Bit beim bitweisen Erzeugen des Morsezeichens
Dim P As Byte ' für Port- Abfrage Geschwindigkeit und Zeichensatz
Dim Z As Byte ' für Zeichensatz
Dim G As Byte ' Zählvariable

Dim R As Word ' für LowByte von Rnd()

Dim Wortindex As Word '
Dim Wortpos As Byte ' Portbits
Dim Wortstring As String * 8
Dim Wortlaenge As Byte
Dim Wortchar As String * 1
Dim Wortbyte As Byte At Wortchar Overlay ' Overlay- Variable (Byte- Wert von Wortchar)

Dim Tonhoehe As Word
Dim Punktlaenge As Word ' Punktlänge
Dim Strichlaenge As Word ' Strichlänge
Dim Zeichenpause As Word ' Länge der Pause zwischen den Zeichen
Dim Wortpause As Word ' Länge der Pause zwischen den Worten bzw. 5er-Gruppen





' Morseton mit Timer1 erzeugen:

Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Start Timer1

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

Enable Interrupts

Acsr.acd = 0 'Analog-Komparator ausschalten, spart etwas Strom
Porta = &B11111111 ' floatende Eingänge vermeiden
Portb = &B00001111 ' floatende Eingänge vermeiden
Ddra = &B00000000 ' floatende Eingänge vermeiden
Ddrb = &B00000000


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



Main:



' Zufallsgenerator- Initialisierung ist beim Rowalt- Mini- Fuchsjagdsender "Floh" ausgeliehen:

' Zufallsgenerator zur Auswahl der jeweiligen Morsebuchstaben initialisieren:
' Damit der Pseudo-Zufallsgenerator nicht jedesmal nach dem Reset die gleichen Zeichenfolgen erzeugt, müssen wir ihn mit einem
' veränderlichen Startwert füttern. Wir lösen das auf einfachste Weise, indem wir hochzählen, wie oft das Programm bereits
' gestartet wurde und die Bits etwas rotieren lassen. Der entstandene Wert wird dann wieder im EEPROM abgelegt:

___rseed = Weerndinit 'Initialisierungswert aus dem EEPROM holen und Zufallsgenerator damit initialisieren
Rotate ___rseed , Left , 7 'Die Bits des Initialisierungswerts rotieren lassen...
Incr ___rseed 'und den Wert um 1 erhöhen. Damit sollte ein recht zufälliger Eindruck entstehen.
Weerndinit = ___rseed 'Und nun den neuen Wert im EEPROM ablegen.



' Auswahl Geschwindigkeit

P = Not Pinb ' Abfrage Portbits PB0 - PB7 und PA7
G = Not Pina.7
Shift G , Left , 3
P = P And &B00000111 ' PB3-PB7 werden weggeworfen
P = P Or G

Select Case P

Case 0
Punktlaenge = 74
Zeichenpause = 2400 ' eff. 15 ZPM
Case 1
Punktlaenge = 74
Zeichenpause = 1720 ' eff. 20 ZPM
Case 2
Punktlaenge = 74
Zeichenpause = 1350 ' eff. 25 ZPM
Case 3
Punktlaenge = 74
Zeichenpause = 1040 ' eff. 30 ZPM
Case 4
Punktlaenge = 74
Zeichenpause = 820 ' eff 40 ZPM
Case 5
Punktlaenge = 74
Zeichenpause = 480 ' eff 50 ZPM
Case 6
Punktlaenge = 74
Zeichenpause = 325 ' 60 ZPM
Case 7
Punktlaenge = 74
Zeichenpause = 222 ' 70 ZPM
Case 8
Punktlaenge = 65
Zeichenpause = 195 ' 80 ZPM
Case 9
Punktlaenge = 58
Zeichenpause = 173 ' 90 ZPM
Case Else
Punktlaenge = 52
Zeichenpause = 155 ' 100 ZPM

End Select

Strichlaenge = Punktlaenge * 3 'Strichlänge





' Lebenszeichen / Spruchbegin

Waitms 300
M = 50 ' Zeichen <KA> (Spruchbeginn)
M = Lookup(m , Morsetabelle_1) ' Morsezeichen aus Tabelle holen
Gosub Morse
Wait 2





' Auswahl Lektionen (also Umfang des Zeichensatzes)

P = Not Pina ' Abfrage und Invertierung Portbits PC0 ... PC7
P = P And &B00011111 ' Kapitelnummer; nur Bits PA0...PA4 berücksichtigen

Wortpause = Zeichenpause
Shift Wortpause , Left , 1 'Länge Wortpause = 2 * Zeichenpause


If P = 0 Then 'Verzweigung in die Ausgaben des Geschwindigkeits- Normwortes "Paris"
Gosub Paris
End If

If P > 26 Then ' ungültige Eingabe abfangen
P = 26
End If


Z = P ' Z: Umfang des Zeichensatzes
Shift Z , Left , 1 ' Kapitel 1 : 2 Zeichen; 2 neue Zeichen bei jedem weiteren Kapitel



' Erzeugung von 5er- Gruppen mit Zufallsgenerator

Do

For G = 1 To 5
R = Rnd(z) ' M = 0 .... Z
M = Low(r) ' nur unteres Byte des Wortes verwenden
M = Lookup(m , Morsetabelle_1) ' Morsezeichen aus Tabelle holen
Gosub Morse
Next

Waitms Wortpause

Loop




' Ausgabe Normwort für Geschwindigkeitsmessungen

Paris:

Do

Wortstring = "Paris "
Gosub Wortzerlegen

Loop


Wortzerlegen:

Wortlaenge = Len(wortstring)
For Wortpos = 1 To Wortlaenge
Wortchar = Mid(wortstring , Wortpos , 1 )
Gosub Klartextausgabe
Next

Return




Klartextausgabe: ' ungültige Zeichen ausfiltern; gültige Zeichen nachschlagen


Select Case Wortbyte ' Umlaute usw. ummappen in den Bereich 91 - 94

Case Is <= 31 : Wortbyte = 32 ' ungültige Zeichen in Pause ummappen
Case 169 : Wortbyte = 91 ' Ä
Case 214 : Wortbyte = 92 ' Ö
Case 220 : Wortbyte = 93 ' Ü
Case 223 : Wortbyte = 94 ' sz
Case 228 : Wortbyte = 91 ' ä
Case 246 : Wortbyte = 92 ' ö
Case 252 : Wortbyte = 93 ' ü

End Select

If Wortbyte > 123 Then ' ungültige Zeichen in Pause ummappen
Wortbyte = 32
End If


If Wortbyte > 94 Then ' Kleinbuchstaben -> Grossbuchstaben
Wortbyte = Wortbyte - 32
End If
Wortbyte = Wortbyte - 32 ' Morsetabelle_2 beginnt mit Ascii-Zeichen 32

M = Lookup(wortbyte , Morsetabelle_2) ' Morsezeichen aus Tabelle holen
Gosub Morse

Return



' Morsezeichenerzeugung:

Morse:

Gosub Poti

If M = 0 Then ' Sonderfall: Leerzeichen statt nicht morsbarer ASCII- Zeichen
Waitms Wortpause
Goto Zeichenende
End If

For I = 1 To 8
If M = 1 Then ' Das Byte hat nur noch den Wert 1; Zeichenende!
Goto Zeichenende
End If
L = M And &B00000001 ' niederwertigstes Bit lesen
Ddra.6 = 1
If L = 1 Then
Waitms Strichlaenge ' ist das Bit 1 -> dah
Else
Waitms Punktlaenge ' ist das Bit 0 -> dit
End If
Ddra.6 = 0
Waitms Punktlaenge ' Pause innerhalb des Morsezeichens
Shift M , Right , 1 ' Bits um eine Stelle nach rechts shiften
Next I
Zeichenende:
Waitms Zeichenpause ' Pause zwischen Morsezeichen

Return


Poti:

Tonhoehe = Getadc(5) ' Tonhoehe durch Poti einstellbar
Tonhoehe = Tonhoehe + 1024 'für sinnvollen Einstellbereich
Ocr1ah = High(tonhoehe)
Ocr1al = Low(tonhoehe)

Return

End




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




Morsetabelle_1: 'Reihenfolge Koch- Methode:

' -> K M U R E S N A P T L W I . J Z - F O Y , V G 5 / Q 9 2 H 3 8 B ? 4 7 C 1 D 6 Ø X =
' -> zusätzliche: : ( ) + " ä ö ü ch <KA>

Data &B00001101 , &B00000111 , &B00001100 , &B00001010 , &B00000010

Data &B00001000 , &B00000101 , &B00000110 , &B00010110 , &B00000011

Data &B00010010 , &B00001110 , &B00000100 , &B01101010 , &B00011110

Data &B00010011 , &B01100001 , &B00010100 , &B00001111 , &B00011101

Data &B01110011 , &B00011000 , &B00001011 , &B00110000 , &B00101001

Data &B00011011 , &B00101111 , &B00111100 , &B00010000 , &B00111000

Data &B00100111 , &B00010001 , &B01001100 , &B00110000 , &B00100011

Data &B00010101 , &B00111110 , &B00001001 , &B00100001 , &B00111111

Data &B00011001 , &B00110001

Data &B01000111 , &B00101101 , &B01101101 , &B00101010 , &B01010010

Data &B00011010 , &B00010111 ; &B00011100 , &B00011111 , &B00110101


Morsetabelle_2: ' für Klartext- Ausgabe


' Ascii 32 - 47 -> _!"#$%&'()*+,-./
Data 0 , 0 , &B01010010 , 0 , 0 , 0 , &B00101010 , 0 , &B00101101 , &B01101101 , 0 , &B00101010 , &B01110011 , &B01100001
Data &B01101010 , &B00101001

' Ascii 48 - 57 -> 0123456789
Data &B00111111 , &B00111110 , &B00111100 , &B00111000 , &B00110000 , &B00100000 , &B00100001 , &B00100011 , &B00100111 , &B00101111

' Ascii 58 - 64 -> :;<=>?@
Data &B01000111 , &B01110011 , &B00101101 , &B00110001 , &B01101101 , &B01001100 , 0

' Ascii 65 - 90 @ABCDEFGHIJKLMNOPQRSTUVWXYZ
Data &B00000110 , &B00010001 , &B00010101 , &B00001001 , &B00000010 , &B00010100 , &B00001011 , &B00010000 , &B00000100
Data &B00011110 , &B00001101 , &B00010010 , &B00000111 , &B00000101 , &B00001111 , &B00010110 , &B00011011 , &B00001010
Data &B00001000 , &B00000011 , &B00001100 , &B00011000 , &B00001110 , &B00011001 , &B00011101 , &B00010011

' ASCII 91 -95 ä ö ü s (s statt ß)
Data &B00011010 , &B00010111 ; &B00011100 , &B00001000


Elektronik-Labor   Projekte   AVR