Forum: Mikrocontroller und Digitale Elektronik Morse Decoder


von MX275 (Gast)


Lesenswert?

Hallo zusammen

Ich möchte gerne mit meinem Arduino einen Morse-Decoder bauen.
Möglichst simpel:
1 Taste zum Morsen an Eingang von Arduino.
1 LED visualisiert den Tastendruck.
Der Output wird seriell ausgegeben.

Mir geht es in erster Linie darum, zuverlässig Punkt (. Taste kurz 
gedrückt) und Strich(- Taste lange gedrückt) zu erkennen). Das 
decodieren der Punkt-Strich-Sequenz stellt dann kein Problem mehr dar.

Dies ist die Definition des Morsecodes:
"Der Code verwendet drei Symbole, die Punkt ( · ), Strich ( − ) und 
Pause ( ) genannt werden, gesprochen als dit, dah (oder doh) und 
„Schweigen“. ... Die Pause zwischen zwei gesendeten Symbolen ist ein Dit 
lang. Zwischen Buchstaben in einem Wort wird eine Pause von der Länge 
eines Dah (oder drei Dits) eingeschoben. Zwischen einzelnen Wörtern 
(Leerzeichen) wird eine Pause von 7 dits eingeschoben"

Das Problem ist, dass es mit jeder beliebigen Morse-Geschwindigkeit 
funktionieren soll. Wie kann ich dann ein einzelnes "T" = "-" von einem 
einzelnen "E" = "." unterscheiden? Ein "-" könnte ja auch ein langsam 
gemorster "." sein.

Aktuell messe ich die On-Zeit (Taste gedrückt) und Off-Zeit (Taste 
losgelassen) und vergleiche dann die Zeiten.
Es ist ein Strich wenn On-Zeit = 3 * Off-Zeit (+- gewisse Toleranz)
Es ist ein Punkt, wenn die On-Zeit = Off-Zeit entspricht (+- Toleranz).
Das Letzte Symbol eines Buchstabens erkenne ich noch nicht richtig...


Könnt ihr mir weiterhelfen? Vielen Dank!

Hier ein Ausschnitt aus meinem Code:
1
enum morseDecoderStates 
2
{
3
    MORSE_STATE_INIT = 0,
4
    MORSE_STATE_WAIT_FOR_INPUT,
5
    MORSE_STATE_MEASURE_ON_TIME,
6
    MORSE_STATE_MEASURE_OFF_TIME,
7
    MORSE_STATE_WAIT_FOR_RELEASE,
8
};
9
10
uint16_t timeOn  = 0;
11
uint16_t timeOff = 0;
12
13
unsigned long long debounceTimeStamp = 0;
14
uint16_t measuredTimes[20];
15
uint8_t  measureIndex = 0;
16
String   ditDahString = "";
17
String   decodedString = "";
18
19
20
static String morse[] = 
21
{
22
  // Buchstaben A..Z
23
  ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
24
  "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
25
  ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
26
  // Ziffern 0..9
27
  "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."
28
};
29
30
31
boolean checkDitDah()
32
{
33
    if (timeOn >= (timeOff * 0.2) && timeOn < (timeOff * 1.4) && timeOff > 0)
34
    {
35
        Serial.print(".");     
36
        ditDahString += ".";   
37
        digitalWrite(light0 + 2, HIGH);
38
        return true;
39
    }
40
    if (timeOn >= (timeOff * 1.4) && timeOn <= (timeOff * 5) && timeOff > 0)
41
    {
42
        Serial.print("-");  
43
        ditDahString += "-"; 
44
        digitalWrite(light0 + 3, HIGH);   
45
        return true;
46
    }
47
    return false;
48
49
}
50
51
char decodeString()
52
{
53
    for (uint8_t i = 0; i < 26 + 10; i++)
54
    {
55
        if (ditDahString == morse[i])
56
        {
57
            if (i <= 25)
58
            {
59
                return char('A' + i);
60
            }
61
            else
62
            {
63
                return char ('0' + i - 26);
64
            }
65
        }
66
    }  
67
}
68
69
70
void morseDecoder()
71
{
72
    if (millis() - debounceTimeStamp > 20)
73
    {
74
        debounceTimeStamp = millis();    
75
    
76
        switch(state)
77
        {
78
            case MORSE_STATE_INIT:
79
                debugMessage("MORSE_STATE_INIT");
80
                state = MORSE_STATE_WAIT_FOR_INPUT;
81
                timeOff = 0;
82
                timeOn  = 0;
83
                break;
84
    
85
            case MORSE_STATE_WAIT_FOR_INPUT:
86
                debugMessage("MORSE_STATE_WAIT_FOR_INPUT");
87
                digitalWrite(light0 + 2, LOW);
88
                digitalWrite(light0 + 3, LOW);
89
                if (!digitalRead(button0))
90
                {
91
                    // Taste gedrückt
92
                    digitalWrite(light0, HIGH);  
93
                    timeStamp = millis();
94
                    state     = MORSE_STATE_MEASURE_ON_TIME;
95
                }
96
                break;
97
    
98
            case MORSE_STATE_MEASURE_ON_TIME:
99
                debugMessage("MORSE_STATE_MEASURE_ON_TIME");
100
                timeOn    = millis() - timeStamp;
101
                //Serial.println(String(timeOn));
102
                if (timeOn > 5000)
103
                {
104
                    // Taste zu lange gedrückt
105
                    timeStamp = millis();
106
                    state = MORSE_STATE_WAIT_FOR_RELEASE;
107
                    break;     
108
                }
109
                if (digitalRead(button0))
110
                {
111
                    // Taste nicht mehr gedrückt
112
                    digitalWrite(light0, LOW);     
113
                    timeStamp = millis();
114
                    state = MORSE_STATE_MEASURE_OFF_TIME;
115
                }
116
                break;
117
    
118
            case MORSE_STATE_MEASURE_OFF_TIME:
119
                debugMessage("MORSE_STATE_MEASURE_OFF_TIME");
120
121
                timeOff   = millis() - timeStamp;
122
                //Serial.println(String(timeOff));
123
                 
124
                if (timeOff > timeOn * 6)
125
                {
126
                    // Taste zulange nicht gedrückt. Abbrechen.
127
128
                    timeStamp = millis();
129
                    state = MORSE_STATE_INIT;
130
                    Serial.print("##");
131
                    break;
132
133
                } 
134
                else
135
                {
136
                    if (!digitalRead(button0))
137
                    {
138
                        // Taste wieder gedrückt
139
                        timeOff   = millis() - timeStamp;
140
    
141
                        timeStamp = millis();
142
                        checkDitDah();
143
                        state = MORSE_STATE_MEASURE_ON_TIME;
144
                        break;
145
                    }  
146
                    else
147
                    {
148
                        // Taste noch nicht wieder gedrückt
149
                        if (checkDitDah())
150
                        {
151
                           timeStamp = millis();
152
                           state = MORSE_STATE_INIT;
153
                           break;
154
                          
155
                        }
156
                                          
157
                    }
158
                }
159
   
160
                break;
161
162
163
            case MORSE_STATE_WAIT_FOR_RELEASE:
164
                // Warten bis Taste wieder losgelassen wird
165
                debugMessage("MORSE_STATE_WAIT_FOR_RELEASE");
166
                if (digitalRead(button0))
167
                {
168
                    // Die Taste wurde endlich losgelassen. Von vorne beginnen
169
                    Serial.print("!!");
170
                    timeStamp = millis();
171
                    state = MORSE_STATE_INIT;
172
                    break;
173
                }     
174
                break; 
175
        }
176
    }
177
}

von oszi40 (Gast)


Lesenswert?

Das Rad wurde mehrfach erfunden ist heute trotzdem noch rund.
Morse-Decoder gibt es schon einige wie die Suchmaschine mir verriet. 
Vergleiche Deine Erkenntnisse. 
https://praxistipps.chip.de/arduino-morse-uebersetzer-bauen-so-gehts_104474

von OM (Gast)


Lesenswert?

Ein Morsedecoder ist nicht trivial. Es gibt viele schlechte und noch 
mehr sehr schlechte. Man kann also nicht sagen, dass das Rad schon 
erfunden wurde. Es gibt immer wieder Verbesserungen.

von Wolfgang (Gast)


Lesenswert?

MX275 schrieb:
> Das Problem ist, dass es mit jeder beliebigen Morse-Geschwindigkeit
> funktionieren soll. Wie kann ich dann ein einzelnes "T" = "-" von einem
> einzelnen "E" = "." unterscheiden?

Indem du wartest, bis es nicht mehr ein einzelnes 'T' oder 'E' ist, i.e. 
du pufferst deine Zeichen und entscheidest dann.

Ein Funker hat das gleiche Problem.

von MX275 (Gast)


Lesenswert?

Sieht mehr nach einem Morse-Encoder, nicht nach einem Morse-Decoder aus 
(Nur Pins als Ausgänge geschaltet). Habe schon Arduino Morse Decoder 
gefunden im Internet, aber nur mit festgelegter Morse-Geschwindigkeit!

von MX275 (Gast)


Lesenswert?

@oszi40
MX275 schrieb:
> Sieht mehr nach einem Morse-Encoder, nicht nach einem
> Morse-Decoder aus
> (Nur Pins als Ausgänge geschaltet). Habe schon Arduino Morse Decoder
> gefunden im Internet, aber nur mit festgelegter Morse-Geschwindigkeit!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

MX275 schrieb:
> aber nur mit festgelegter Morse-Geschwindigkeit!
Das ist trivial.
Aber der Witz ist ja gerade die laufende Anpassung an 
Geschwindigkeitsänderungen. Es reicht also auch nicht aus, ein einziges 
Mal die Geschwindigkeit zu vermessen.

von MX275 (Gast)


Lesenswert?

@wolfgang: wie soll ich mich dann entscheiden. Angenommen ich habe eine 
On-Zeit von 2 Sekunden, und eine Offzeit, welche ein Timout bedeutet 
(sagen wir 10 Sekunden... damit meine ich das Ende der Übertragung). War 
es nun ein Punkt oder ein Strich?

von MX275 (Gast)


Lesenswert?

@Lothar M.:
Das ist mir auch bewusst :-)

von Jakob (Gast)


Lesenswert?

Ein Morsedecoder ist nicht pillepalle, aber auch kein Hexenwerk.

So ein Morsedecoder muss nur das nachvollziehen, was in Ohr und Hirn 
eines Morse-Hörers abläuft. Niemand sendet ein einzelnes T, oder E. Erst 
aus dem Zusammenhang von ein bis mehreren Zeichen zeigt sich, was als 
dit, oder dah gesendet wurde.

Bei einer neuen Morsesendung muss man sich auf das Tempo des Senders 
einstellen. Dazu wird ein Zeitwert ermittelt, der die letzten dit 
(kürzer) und dah (länger) sicher voneinander trennt. - Gleiches gilt für 
die 3 möglichen Pausenlängen.

Geübte Hand-Morser machen oft eher 1:2 statt 1:3 bei dit:dah - und das 
Entsprechende bei den Pausen. - Diese Werte müssen ständig nebenbei 
ermittelt und nachgeführt werden. Anders geht's nicht!

Auffällig kurze Zeiten für Signal, oder Pause werden ignoriert.
Das sind wahrscheinlich Übertragungsfehler...
Auffällig lange Zeiten (Signal, oder Pause) werden z.B als
Satzende, Sendungsende, Zeilenvorschub, ... gewertet.

Und was beim Morse-Hörer im Unterbewusstsein geschieht, nämlich auch die
ersten dit-s und dah-s unbekannter Länge vom Anfang der Sendung zu
decodieren, kann man im µC mit Zwischenspeicherung (hier empfiehlt sich 
ein Ringspeicher) und Decodierung erst nach dem die Zeiten bekannt sind, 
nachvollziehen.

Wie man das macht, musst du versuchen, selbst herauszufinden.
Geholfen wird dir hier gern, aber Hausaufgaben für Leute, die nicht 
aufgepasst haben, sind eher unbeliebt...

von Wolfgang (Gast)


Lesenswert?

MX275 schrieb:
> Sieht mehr nach einem Morse-Encoder, nicht nach einem Morse-Decoder

Morsezeichen von Morsetaste rein, serielle Daten raus - das IST ein 
Decoder

MX275 schrieb:
> War es nun ein Punkt oder ein Strich?

Das wirst du nicht entscheiden können und egal ist es auch. Es ist 
relativ sinnfrei ein einzelnes 'E' oder 'T' zu übertragen.

von Stefan (Gast)


Lesenswert?

Hallo,

ich habe jetzt alle Beiträge aufmerksam gelesen und Alles ist mehr oder 
weniger richtig, nichts Falsches.
Aber ich habe den Verdacht dass keiner der Schreiber sich jemals mit 
Morsen auseinander gesetzt hat, d.h. wirklich Geben und Hören kann.

Am besten beschreibt es noch
Jakob schrieb:
> So ein Morsedecoder muss nur das nachvollziehen, was in Ohr und Hirn
> eines Morse-Hörers abläuft.

und das hat auch viel mit Wahrscheinlichkeit zu tun.

Wer jemals in die AFU-Bänder rein gehört hat der weiß dass sich der 
gesamte Morse-Betrieb mit Geschwindigkeiten zwischen 80BpM und 125BpM 
abspielt.
Weniger als 80BpM gilt als Anfänger und mehr als 125BpM gilt als "High 
Speed".
Mit diesem Wissen kann man mit gewisser Wahrscheinlichkeit abschätzen ob 
ein einzelnes Zeichen ein E oder T ist.

Des weiteren ist es bei diesen Geschwindigkeiten (um die 100BpM) dem 
Hörer nicht mehr möglich die Punkte oder Striche der schnell aufeinander 
folgenden Zeichen mitzuzählen.
Der Hörer hat vielmehr die Klangbilder aller Zeichen im Kopf und sein 
Gehirn entscheidet aufgrund dieser Klangbilder um welches Zeichen 
(Buchstaben) es sich handelt.
Meiner Ansicht wäre es also am besten wenn eine Maschine (Computer) 
Klangbilder erkennen und auswerten könnte. Nichts mit starrem Abzählen 
von Punkt und Strich. Auf diese Weise wären auch unsaubere und stark 
verrauschte Signale kein Problem.

Gruss

von Günter Lenz (Gast)


Lesenswert?

von Stefan schrieb:
>Meiner Ansicht wäre es also am besten wenn eine Maschine (Computer)
>Klangbilder erkennen und auswerten könnte.

Das kann aber kein Computer, dem bleibt nichts anderes über
als die Längen der Striche Punkte und Pausen zu messen.

Computer können nicht alles.

http://www.blutner.de/philos/comp.html

Irgendwo hatte ich mal was gelesen was man mit einem
Algorithmus oder Programm nicht lösen kann, oder für
dieses Problem unmöglich ist ein Programm zu schreiben,
was aber für einen Menschen trivial ist. Das war irgend
ein Spiel, ich finde es aber nicht wieder.

von Günter Lenz (Gast)


Lesenswert?

Jetzt habe ich es gefunden, es war ein You-Tube-Video.

https://www.youtube.com/watch?v=BW2PFQz85Do

von Bernd (Gast)


Lesenswert?

Vor etlichen Jahren gab es einen Morse-Decoder auf der Basis eines 
6502-Systems (AIM oder KIM) inkl. ELIZA von der c't. Das System passte 
sich automatisch an die Geschwindigkeit an. Das ELIZA-Programm 
beantwortete einfache Fragen.

Vielleicht hat jemand noch das alte (Sonder-)Heft.

von Rolf M. (rmagnus)


Lesenswert?

Stefan schrieb:
> Meiner Ansicht wäre es also am besten wenn eine Maschine (Computer)
> Klangbilder erkennen und auswerten könnte. Nichts mit starrem Abzählen
> von Punkt und Strich. Auf diese Weise wären auch unsaubere und stark
> verrauschte Signale kein Problem.

Aber woraus besteht für dich das "Klangbild", wenn nicht aus einer Reihe 
kurzer und langer Pulse, die man in einer Maschine halt abzählt?

Günter Lenz schrieb:
> Das kann aber kein Computer, dem bleibt nichts anderes über
> als die Längen der Striche Punkte und Pausen zu messen.

Ein neuronales Netz, das man auf die Erkennung trainiert, wäre noch am 
nächsten an dem, wie es Menschen tun, dran. Das erkennt die Muster.

von Michael W. (dbru61)


Lesenswert?

MX275 schrieb:
> Hallo zusammen
>
>
>
> static String morse[] =
> {
>   // Buchstaben A..Z
>   ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
>   "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
>   ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
>   // Ziffern 0..9
>   "-----", ".----", "..---", "...--", "....-", ".....", "-....",
> "--...", "---..", "----."
> };
>

Moin,

Es fehlen noch Trennung, Komma, Punkt , Slash, Bindestrich und die 
Irrung (i.d. Praxis eine, rein Formal aber dann zwei Versionen).

Viel Erfolg

von MX275 (Gast)


Lesenswert?

Danke für eure Beiträge. Das hat mir weitergeholfen! Ich starte einen 
neuen Versuch.. mit abschätzen etc..

von Thomas K. (joshua314)


Lesenswert?

Guten Tag MX275

vor vielen Jahren ...ca 35.   hab ich einen Morse Decoder auf dem C64 
geschrieben.

Das Decodieren besteht, wie du schon rausbekommen hast, vor allem an dem 
ausdauernden herausfinden der Punkt, Strich, Pause Längen.

Meine Vorgehensweise damals.

1. Ringpuffer anlegen wo alle Ereignisse abgelegt werden.
2. Nach den ersten paar Zeichen (ca.10) den Ringpuffer mit diesen 
Zeichen erst mal füllen.  Ist zwar nicht gut ...  aber dann schon mal 
ein Anfang.
Alles was danach reinkommt über die Kopierten Zeichen drüberschreiben.
3. laufende jetzt Punkte Striche Pausen suchen, erkennen und bewerten.
dabei beachten, dass der Mensch ein sehr schlechter Morsezeichen Geber 
ist.
Ein Punkt zu Strich Verhältnis senkt sich bei Hi-Speed mit zu 1.3xPunkt 
= Strich. Ein Verhältnis 1:2 ist schon gut.
4. Wenn dein Ringpuffer analysiert ist, die Längen für Punkte Striche 
Pausen im Mittel bekannt sind, kannst du dich ranmachen deinen 
Ringpuffer zu dekodieren.......
Dies beudeutet aber auch, dass es vorkommen wird. Dass dein Text in der 
Länge deines Ringpuffers sich immer wieder ändern wird, da du neue 
Analyse Ergebnisse hast....

vy73 Thomas de DG5MPQ

: Bearbeitet durch User
von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

MX275 schrieb:
> Aktuell messe ich die On-Zeit (Taste gedrückt) und Off-Zeit (Taste
> losgelassen) und vergleiche dann die Zeiten.
> Es ist ein Strich wenn On-Zeit = 3 * Off-Zeit (+- gewisse Toleranz)
> Es ist ein Punkt, wenn die On-Zeit = Off-Zeit entspricht (+- Toleranz).
> Das Letzte Symbol eines Buchstabens erkenne ich noch nicht richtig...

Das war schon vor 40 Jahren eine beliebte Programmierübung. Die Lösung 
war schon vor 40 Jahren:

* Mit einer Basiszeit T rechnen. Z.B. def.
1
T = 2 * T_punkt = T_strich / 1.5

* Zur Initialisierung dieser Basiszeit T ein paar Zeichenlängen messen 
bis man zwei Zeichenlängen t1, t2 findet für die gilt:
1
Wenn
2
    2 * t1 < t2; d.h. t1 war wahrscheinlich ein ".", t2 ein "-"
3
oder
4
    t1 > 2 * t2; d.h. t1 war wahrscheinlich ein "-", t2 ein "."
5
dann
6
    T = (t1 + t2) / 2
7
sonst
8
    weiter t1, t2 messen.

* Mit T dann kontinuierlich Zeichen dekodieren. Zeit t eines Zeichens 
messen:
1
    t <= T --> Punkt
2
    t > T --> Strich

* T kontinuierlich anpassen. Beispiel (Gewichtung musst du 
ausprobieren):

Wenn Punkt erkannt wurde:
1
   T_neu = (T_alt + 2 * t) / 2

Wenn Strich erkannt wurde:
1
   T_neu = (3 * T_alt + 2 * t) / 6

Rolf M. schrieb:
> Ein neuronales Netz, das man auf die Erkennung trainiert, wäre noch am
> nächsten an dem, wie es Menschen tun, dran. Das erkennt die Muster.

Mann kann sich auch richtig ins Knie schießen.

: Bearbeitet durch User
von Dussel (Gast)


Lesenswert?

Nur mal als Überlegung, würde ich vielleicht mal an eine Clusteranalyse 
denken. Man hat statistisch rauschende Werte, die Längen der 
Tastenbedienungen, und möchte die in die Cluster 'lang' und 'kurz' und 
vielleicht noch 'Pause' einteilen. Da gibt es sicher auch was für 
eindimensionale Daten.

von Michael M. (michaelm)


Lesenswert?

Wolfgang schrieb:
> Morsezeichen von Morsetaste rein, serielle Daten raus - das IST ein
> Decoder

Die Morsezeichen sind doch schon seriell bei der Eingabe; also ist das 
Format doch nicht generall umgesetzt oder verändert.

Einzig die Exaktheit soll hier mittels des Schnelldenkers hergestellt 
werden.

Was macht dann deiner Meinung nach im Gegensatz hierzu (im Sinne 
"Morsezeichen") ein Encoder?  ;-)

von Thilo L. (bc107)


Lesenswert?

Hannes J. hat das grundlegende Verfahren richtig beschrieben: die 
Timings des gegebenen Codes müssen kontinuierlich erfasst und gemittelt 
werden und dann dynamisch als Entscheidungsbasis zwischen dit und dah 
("Punkt" und "Strich" für Nicht-Funker) zu dienen. Interessant und 
entscheidend ist hier die Art der Mittelung: nimmt man zu viele 
Einzel-Signale, wird die erkennung einer geänderten Geschwindigkeit zu 
träge, nimmt man zu wenige, reagiert der Algorithmus empfindlich auf 
leichte Schwankungen der Gebegeschwindigkeit.

Vor einigen Jahren habe ich für unsere Kids-Bastelecke auf dem 
jährlichen Field Day einen Morsedecoder mit AVR entworfen. er war zum 
Schluss in der Lage >256 WPM (Ja. WPM, nicht BPM) fehlerlos zu erkennen 
und hat eine harte Speed-Umschaltung am Eingang von 20 auf 120 WPM 
innerhalb von 1 Zeichen (zurück innerhalb von maximal 3 Zeichen) 
geschafft. (Ist aber closed source)

-- Thilo, DL2THL

von Der müde Joe (Gast)


Lesenswert?

Hallo, lieber MX275.

Ich habe das morsen noch beim Bund gelernt, in einer Fernmeldeeinheit.

Ich bin kein Programmierer, aber mein Ansatz wäre so:

1. Abtasten des Signals mit einer x-fach höheren Auflösung, speichern
2. Feststellung: Die Decodierung, die Dits und Dats und Pausen müssen 
früher ausgemessen sein, als der Speicher wieder neu beschrieben wird. 
Sonst verliert man Morsezeichen.
3. Sammeln aller Dits und Mittelwertbildung
4. Sammeln aller Dats und Mittelwertbildung
5. Sammeln aller kurzen Pausen und Mittelwertbildung
6. Sammeln aller langen Pausen und Mittelwertbildung
7. Prüfung auf Plausibilität: Sind die Dits kleiner als die Dats, etc.
8. Decodierung des Streams

Die Mittelwerte müssen natürlich nachgeführt werden. Wie oft, hängt von 
der Speichertiefe und Geschwindigkeit der Decodierung ab.

Viel Erfolg!
Der müde Joe.

von Manfred H. (manfredbochum)


Lesenswert?

1984 hab ich als erstes Programm überhaupt einen Morsedecoder für den 
VC20 geschrieben.
Die Zeichenerkennung und Geschwindigkeitsmessung waren nur ein paar 
Zeilen.
Ging bis 150BPM.
Wenn ich das Listing finde poste ich es.

von Chris (Gast)


Lesenswert?


von d*?*** (Gast)


Lesenswert?

Da Rechenleistung heutzutage im Überfluss da ist würde ich die 
dynamische dit-dah Zeichenlängendefinition nach jedem vermuteten 
Morsezeichen(also nach jeder etwas längeren pause) durchführen.
Wenn sich mit den werten kein gültiges Morsezeichen erkennen lässt 
veruchen ob die dit-da vom letzten Zeichen evtl. doch noch mit dazu 
gehören, bzw das nächsten Zeichen abwarten ob das dazugehört, der Geber 
also keine echte Zeichenpause machen wollte.

Wenn nach einer Sequenz unklar Zeichen geblieben sind kann das Programm 
dann ja gleich ein QSM zurück geben ;-)

von Peter D. (peda)


Lesenswert?

Im einfachsten Fall schreibt man die Zeiten zwischen den Flanken in 
einen Ringpuffer, 8Bit Auflösung sollte reichen. Den gleitenden 
Mittelwert der Pulse nimmt man dann, um Punke und Striche zu 
unterscheiden und die Zeichenpause. Damit sollten dann auch von 1:3 
abweichende Verhältnisse zu erkennen sein. Man könnte aber auch ein 
Histogramm anlegen.
Die CPU-Last dürfte gering sein.

von Thilo L. (bc107)


Lesenswert?

>> Die CPU-Last dürfte gering sein.

Jo. In meinem o.g. Programm mit Averaging nach jedem Zeichen, Ausgabe 
auf LCD und seriell usw. war die CPU-Auslastung bei 120 WPM (=600 BPM) 
bei etwa 4% auf einem ATMega32 mit 8 MHz.

von Wolfgang (Gast)


Lesenswert?

Stefan schrieb:
> Wer jemals in die AFU-Bänder rein gehört hat der weiß dass sich der
> gesamte Morse-Betrieb mit Geschwindigkeiten zwischen 80BpM und 125BpM
> abspielt.

Die Aussendungen, bei denen sich Leute fließend mit 200 oder gar 300BpM 
unterhalten, hast du dabei wahrscheinlich gar nicht als Morse-Betrieb 
erkannt.

125BpM lässt sich noch gut von Hand mitschreiben. Die Leute im HSC 
fangen bei 125BpM erst an. Und Meteor Scatter liegt bei 3000BpM.

von Peter D. (peda)


Lesenswert?

MX275 schrieb:
> static String morse[] =

Warum so kompliziert. Ein Zeichen besteht aus max 6 Bit, läßt sich also 
bequem in ein Byte packen. Ein führendes 1-Bit kodiert die Länge.
0b00000010: E
0b00000011: T
0b00000100: I
usw.
Sortiert man dann noch die Bytes aufsteigend, geht eine binäre Suche am 
schnellsten.

von Holger D. (hodoe)


Lesenswert?

Moin, das Bauen/Programmieren eines CW-Decoders bis in höchste 
Geschwindigkeiten ist nun wirlich trivial. Das ist ja heutzutage in 
vielen Transceivern eingebaut. Selbst der QCX kann das. Es gibt hunderte 
von Ansätzen und Lösungen und trotzdem versucht man es immer wieder neu. 
Warum? Weil die Praxis an der Antenne zeigt, dass es eben nicht gut und 
konstant funktioniert, wenn die NF nicht mit einem vernünftigen Pegel 
dekodiert werden kann. Da gibt es natürliche Störungen und Schwund, 
Mensch-gemachte Störungen, nicht konstante Gebeweise. Es gibt 
Handtastengeber, welche mit ele-Keyern, mechanische Lösungen wie Bugs 
usw usw usw. Wenige Hertz abseits der Frequenz. Auf alles stellt sich 
das menschliche Gehirn ein. Und das Gehirn kann häufig sich Bruchstücke 
zusammenbauen.

Das was der Mensch kann, kann der Rechenknecht niemals und wird es nie 
können. Schreibt doch mal ein QSO mit so einem Decoder mit. Ein 
einfaches von dritter Seite eingeworfenes ..--.. wird die Dekodierung zu 
Fall bringen.

Holger

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.