Forum: Mikrocontroller und Digitale Elektronik String als Morsecode ausgeben


von masl (Gast)


Angehängte Dateien:

Lesenswert?

Hallo ihr,

ich versuche grad Morsecode mit einem Piezo-Summer hörbar zu machen.
Das klappt auch schon ganz gut - zumindest für einzelne Zeichen.
Jetzt suche ich aber eine Möglichkeit ganze Zeichenketten komfortabel 
mit dem Programm auszugeben.

Die Morsecodes für einzelne Zeichen (a-z, 0-9 use.) funktioniert 
bereits.
Die Zeichen werden von rechts nach links gelesen und wenn das Byte 
nurnoch die Wertigkeit 1 hat wird abgebrochen.
Bsp:
A (.-) wird codiert mit 0b00000110 und von rechts nach links immer das 
LSB ausgelesen, bis das "Restbyte" nurnoch den Wert 1 hat.

Die Funktion für einzelne Zeichen ist bereits implementiert.
Wie bekomme ich jetzt allerdings hin, dass ich an eine Funktion einen 
String übergeben kann und das gemorst wird, z.B. "hallo welt"

Vielen Dank schonmal
Gruß Masl ;)

von Karl H. (kbuchegg)


Lesenswert?

masl schrieb:

> Die Funktion für einzelne Zeichen ist bereits implementiert.

Na dann hast du ja schon fast auch die Funktion für Strings!

> Wie bekomme ich jetzt allerdings hin, dass ich an eine Funktion einen
> String übergeben kann und das gemorst wird, z.B. "hallo welt"

Den String Zeichen für Zeichen durchgehen und für jedes Zeichen deine 
Zeichenausgabe aufrufen.
1
void morse_string( const char* string )
2
{
3
  while( *string ) {
4
    morse_char( *string );
5
    string++;
6
  }
7
}

von Falk B. (falk)


Lesenswert?


von Grrrr (Gast)


Lesenswert?

masl schrieb:
> und wenn das Byte
> nurnoch die Wertigkeit 1 hat wird abgebrochen.

Nimm lieber die 0. Das ist sowieso String-Konvention und Karl Heinz's 
Code prüft auf Nicht-Null.

von Karl H. (kbuchegg)


Lesenswert?

Jetzt seh ichs erst
(Danke an Grrr, sonst hätt ich mir den Code gar nicht näher angesehen)

masl, du hast geschummelt!
Deine morse_char kann ja gar nicht ein Zeichen ausgeben, so wie man 
landläufig ein Zeichen betrachtet. Dem muss man ja das Zeichen vorher 
schon extra aufbereitet übergeben!

Das gilt nicht!

Du brauchst eine Funktion, die diese Umkodierung für ein einzelnes 
Zeichen selbst macht! D.h. der übergebe ich nicht irgendwelche speziell 
codierten Zeichen, sondern die macht sich die Codierung selber
1
void morse_zeichen( char c )
2
{
3
  ... Du bist drann
4
}

und ich rufe sie so auf
1
  morse_zeichen( 'h' );
2
  morse_zeichen( 'a' );
3
  morse_zeichen( 'l' );
4
  morse_zeichen( 'l' );
5
  morse_zeichen( 'o' );

Also ran ans Werk!

(und den delay mit der DAH_LENGTH kann die Funktion nach jedem Zeichen 
auch gleich noch als Zugabe machen)

und wenn du die Funktion dann hast, dann kannst du sie von der String 
Ausgabe, wie oben gezeigt, benutzen um einen String abzuarbeiten.

von masl (Gast)


Lesenswert?

Grrrr schrieb:
> Nimm lieber die 0. Das ist sowieso String-Konvention und Karl Heinz's
> Code prüft auf Nicht-Null.

das würde dann aber nicht mehr funktionieren.
Hier nochmal ein Beispiel:
k (-.-) ist nach dem Verfahren, das ich angewendet habe 0b00001101
Hier wird jetzt von rechts angefangen auszuwerten.
Das LSB ist eins, also "lang".
Das "Restbyte" ist 0b0000110 und somit noch ungleich 1 also weiter:
0 steht für "kurz"
Restbyte != 1 also weiter:
1 heißt "lang"
Restbyte == 1 => Abruch
Ansonsten würden ja noch die ganzen Nuller als lange Signale (Dah's) 
gewertet werden.
Oder hab ich dich irgendwie falsch verstanden?

@Karl heinz:
Ja, das is schonmal nicht schlecht.
Allerdings übergebe ich der morse_char() Funktion ja schon die fertigen 
Bytes, da ich die Zeichen ja schon per Präprozessor-Defines zugeordnet 
habe.
Ich bräuchte also nochwas, das mit sowas wie eine Datenbank im µC 
ablegt, das die ASCII zeichen den Morse-Bytes zuordnet

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> das würde dann aber nicht mehr funktionieren.

masl schrieb:
> Ich bräuchte also nochwas, das mit sowas wie eine Datenbank im µC
> ablegt, das die ASCII zeichen den Morse-Bytes zuordnet

Ja genau. Du hast einen Schritt übersprungen.

Du brauchst ein Array. Ordne es am besten nach den ASCII Zeichen 
Kodierungen. Evtl. hast Du wegen der Sonderzeichen noch 
Fallunterscheidungen, falls Du das Array mit minimaler Grösse 
deklarieren willst.
1
// array beginn mit Zahlen
2
char MorseCode [] = {
3
0x1F,                           // 000111111 '0'
4
0x1E,                           // 111110    '1'
5
6
etc.
7
8
0x0D,                          // 00001101 'a'

von masl (Gast)


Lesenswert?

Karl heinz, du warst schneller als ich :P

Ich versteh grad nicht ganz, was du mit "die macht sich die Codierung 
selber" meinst. Ich will ja keinen neuen Morsecode erfinden, deshalb 
brauch ich das ja irgendwie abgelegt in einem Array oderso.

Wie meinen? ^^

von Grrrr (Gast)


Lesenswert?

Es geht doch nur darum:

1. Entweder legst Du die von ASCII nach "Deiner" Morsekodierung 
umkodierten Zeichen in einem String ab und übergibst sie der 
Morse-Funktion.
2. Oder Du übergibst den ASCII-String der Morsefunktion, die dann 
ihrerseits Zeichen für Zeichen in die Morsekodierung umsetzt.

Das ist alles.

von Grrrr (Gast)


Lesenswert?

Ich weiss ja nicht was das werden soll, aber für einen Morsetrainer 
musst Du noch an die Verkehrszeichen denken.

von masl (Gast)


Lesenswert?

Danke für die schnelle Hilfe allerseits ;)

Grrrr schrieb:
> Es geht doch nur darum:
>
> 1. Entweder legst Du die von ASCII nach "Deiner" Morsekodierung
> umkodierten Zeichen in einem String ab und übergibst sie der
> Morse-Funktion.
> 2. Oder Du übergibst den ASCII-String der Morsefunktion, die dann
> ihrerseits Zeichen für Zeichen in die Morsekodierung umsetzt.
>
> Das ist alles.

Ja genau, ich würde das gerne mit dem 2. Weg machen.
Unklar ist mir aber noch, wie ich die Zuordnung am besten mache.
Zwei Arrays, einen mit ASCII zeichen, darin das Zeichen suchen und mit 
dem Index dann in den zweiten Array gehen und das codierte raussuchen?
Is relativ umständlich, da gibts bestimmt bessere Lösungen.
Ich kenn mich nich so besonders aus wie man sowas möglichst effizient 
macht, deshalb frage ich ja hier.
Das ganze soll nämlich möglichst auf einen ATtiny13.

Es soll kein Trainer werden, sondern was für's geocachen - wenn das 
überhaupt was wird, wenn nicht hab ich wenigstens was draus gelernt ;)

von Karl H. (kbuchegg)


Lesenswert?

masl schrieb:

> Ja genau, ich würde das gerne mit dem 2. Weg machen.
> Unklar ist mir aber noch, wie ich die Zuordnung am besten mache.

Am besten nimmst du die Codierung die alle benutzen: ASCII
Die kennt dein Compiler nämlich schon

> Zwei Arrays, einen mit ASCII zeichen, darin das Zeichen suchen und mit
> dem Index dann in den zweiten Array gehen und das codierte raussuchen?
> Is relativ umständlich, da gibts bestimmt bessere Lösungen.

Du kannst gleich das Zeichen als Index nehmen

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> Zwei Arrays, einen mit ASCII zeichen, darin das Zeichen suchen und mit
> dem Index dann in den zweiten Array gehen und das codierte raussuchen?
> Is relativ umständlich, da gibts bestimmt bessere Lösungen.

Ganz einfach. Du nimmst das ASCII-Zeichen selbst als Index in ein Array 
mit der Morse-Kodierung.

So wie ich oben schrieb:

[c]// array beginn mit Zahlen
char MorseCode [] = {
0x1F,                           // 000111111 '0'
0x1E,                           // 111110    '1'

etc.

0x0D,                          // 00001101 'a'
/c]

Du musst halt aufpassen, das die ASCII-Codes mit 0 Anfang (NULL) aber 
das Morsealaphabet im Vergleich zu ASCII erst mit dem Zeichen '0' 
anfängt.
Also musst Du erstmal von dem ASCII-Zeichen, '0' abziehen um es als 
Index benutzen zu können. Dann kann das Array kleiner sein. Gleiches 
gilt für jede andere Lücke der ASCII-Codes im Vergleich zum Morsecode.
Du musst erst die Umrechnung machen bevor Du mit dem Index in die 
Tabelle gehst.

von Karl H. (kbuchegg)


Lesenswert?

> Das ganze soll nämlich möglichst auf einen ATtiny13.

ui das wird eng

von Grrrr (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Du kannst gleich das Zeichen als Index nehmen

Grrrr schrieb:
> Du nimmst das ASCII-Zeichen selbst als Index in ein Array
> mit der Morse-Kodierung.

Mähähäh. ;-)

Wenn zwei das selbe sagen, ist vielleicht was dran.

von Grrrr (Gast)


Lesenswert?

Grrrr schrieb:
> ui das wird eng

Der Morsecode hat etwa 50 Zeichen. Das könnte vielleicht noch gehen, 
wenn er die Lücken konsequent ausnutzt.

von Peter D. (peda)


Lesenswert?

masl schrieb:
> Zwei Arrays, einen mit ASCII zeichen, darin das Zeichen suchen und mit
> dem Index dann in den zweiten Array gehen und das codierte raussuchen?
> Is relativ umständlich, da gibts bestimmt bessere Lösungen.

Nein, das ist nicht umständlich.
Ein Index sucht nichts, er zeigt zielgenau auf das richtige Element.
Das sind also 2 Additionen + Pointerzugriffe pro Zeichen.

> Das ganze soll nämlich möglichst auf einen ATtiny13.

Dann könnte es eng werden mit der zusätzlichen ASCII->Morsetabelle.


Peter

von Grrrr (Gast)


Lesenswert?

Grrrr schrieb:
> Grrrr schrieb:
>> ui das wird eng
Da ist was schiefgegangen. Das hat K.H. geschrieben, nicht ich.

von Grrrr (Gast)


Lesenswert?

Grrrr schrieb:
> Das könnte vielleicht noch gehen,
> wenn er die Lücken konsequent ausnutzt.

Wobei der Code um die Lücken zu überspringen in einigen Fällen 
vielleicht grösser ist als die Lücke. Müsste man genau angucken.

von Karl H. (kbuchegg)


Lesenswert?

Grrrr schrieb:
> Grrrr schrieb:
>> ui das wird eng
>
> Der Morsecode hat etwa 50 Zeichen. Das könnte vielleicht noch gehen,
> wenn er die Lücken konsequent ausnutzt.

Ab ins Flash damit.
Die 127 Bytes sollten immer da sein.
Das Problem: Er steht erst am Anfang und wenn wir ihn da jetzt auch noch 
ins Flash reintheatern ....

@TO
Warum fängst du mit einem Tiny13 an?
Nichts gegen den µC, aber für den Anfang ist das grade eine Spur zu 
klein. Wenn man Übung hat, kann man in einen Tiny13 alles mögliche 
reinquetschen. Aber dazu muss man schon wissen was man tut. Jetzt hast 
du das Problem, das du schon 'tricksen' musst, noch ehe du einigermassen 
akzeptabel programmieren kannst.

von Grrrr (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
>> Der Morsecode hat etwa 50 Zeichen. Das könnte vielleicht noch gehen,
>> wenn er die Lücken konsequent ausnutzt.
>
> Ab ins Flash damit.
> Die 127 Bytes sollten immer da sein.
> Das Problem: Er steht erst am Anfang und wenn wir ihn da jetzt auch noch
> ins Flash reintheatern ....

Auch richtig. Aber gut. Sprechen (schreiben) man ihn halt durch.

Also masl:

Das Ganze läuft dann über das Attribut "PROGMEM".
1
// array beginn mit den Ziffern
2
char MorseCode PROGMEM [] = {
3
0x1F,                           // 000111111 '0'
4
0x1E,                           // 111110    '1'
5
6
etc.
7
8
0x0D,                          // 00001101 'a'

Und Du verwendest eine Funktion namens "pgm_read_byte". Siehe auch: 
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html#g73084a8bbde259ffae72980354b3f027

Im Prinzip kannst Du das Array dann genauso wie gewohnt verwenden, nur 
das Du nicht "[]" zum indizieren verwendest sondern den Index, also das 
ASCII-Zeichen an die Funktion pgm_read_byte übergibst.

Klar?

von Karl H. (kbuchegg)


Lesenswert?

Bei den Ziffern gibts ein Schema
1
#define _0_ 0b00111111
2
#define _1_ 0b00111110
3
#define _2_ 0b00111100
4
#define _3_ 0b00111000
5
#define _4_ 0b00110000
6
#define _5_ 0b00100000
7
#define _6_ 0b00100001
8
#define _7_ 0b00100011
9
#define _8_ 0b00100111
10
#define _9_ 0b00101111

Bei den Buchstaben gibts nichts. Allerdings wird nicht zwischen Gross 
und Kleinbuchstaben unterschieden. Macht also 26 Bytes. Dazu noch 14 
Bytes für die Sonderzeichen, macht 40 Bytes in Summe. Bei 64 Bytes 
verfügbar ist das verdammt eng. Könnte sich gerade so lala ausgehen.

Hilft nichts, die Tabelle muss ins Flash. Bei 1K ist es dann auch nicht 
notwendig, da gross zu tricksen. Ein 127-Array für 7-Bit ASCII und die 
nicht benutzen auf 0 setzen. Die 87 Bytes zuviel relativieren sich 
wieder durch den einfacheren Code und die ersten 32 kann man sowieso 
gleich auslassen.

von masl (Gast)


Lesenswert?

Ja ok, das mit dem SPeicherplatz soll uns jetzt mal nicht behindern, im 
Moment probier ich eh grad alles aufm mega32.

Aber das mit den ASCII als Indizes check ich noch nich so ganz, sorry ^^

Von 0-9 im Array hab ich jetzt die Codierung für 0-9 abgelegt.
Dann kommen von 10 bis ende a-z.
So meint ihr oder?

Jetzt bekommt die Funktion ein Pointer auf ein ASCII zeichen. z.B. 0 in 
ASCII 0x30. Was mach ich jetzt damit?

von masl (Gast)


Lesenswert?

Achso, ihr meint ein Array mit dem Index über alle ASCII zeichen und 
dann an dem Index a (0x61) die Codierung für a speichern

von Philipp B. (philipp_burch)


Lesenswert?

Hallo masl,

Grrr und Karl-Heinz haben ja schon einiges an Hilfestellung gegeben. Mir 
kommt die Kodierung der Zeichen aber schwerstens bekannt vor, daher 
würde ich dir jetzt mal unterstellen, du hast die von hier: 
http://www.activevb.de/tipps/vb6tipps/tipp0726.html
Wenn du dir den Code noch etwas weiter anschaust, findest du da auch 
bereits die angesprochene Tabelle, allerdings halt in VB-Code:
1
Private Sub Form_Load()
2
    'Aus diesem String werden die Töne für die einzelnen Zeichen
3
    'generiert. Zur einfachen Speicherung wird folgendes Verfahren
4
    'angewandt:
5
    'Jedes Byte (8 Bit) repräsentiert den Morsecode für ein
6
    'bestimmtes Zeichen im ANSI-Zeichensatz. Da die Zeichen
7
    'unterhalb 36 ohnehin keine Entsprechung im Morsecode haben,
8
    'bzw. gar nicht darstellbar sind, wurden sie weggelassen.
9
    'Jedes Bit dieser Bytes stellt nun ein Dit oder ein Dah dar.
10
    'Da die Morsezeichen aber nicht alle gleich lang sind, sind
11
    'die Zeichendaten innerhalb der Bytes rechts ausgerichtet und
12
    'ganz oben mit einem Startbit versehen.
13
    '
14
    'Beispiele:
15
    '
16
    'Buchstabe n (dahdit):
17
    '0b0000 0110 (6)
18
    '/       ^^^
19
    '/       ||`-- Dit
20
    '/       |`--- Dah
21
    '/       `---- Startbit
22
    '
23
    'Zahl 0 (dadadadadah)
24
    '0b0011 1111 (63)
25
    '/   ^^ ^^^^
26
    '/   || |||`-- Dah
27
    '/   || ||`--- Dah
28
    '/   || |`---- Dah
29
    '/   || `----- Dah
30
    '/   |`------- Dah
31
    '/   `-------- Startbit
32
    '
33
    'Der Wert 255 (theoretisch sieben Dahs) entspricht keinem
34
    'Zeichen, sondern markiert leere Bytes.
35
    MorseCodes = _
36
      Chr$(255) & Chr$(255) & Chr$(255) & Chr$(94) & _
37
      Chr$(54) & Chr$(109) & Chr$(255) & Chr$(42) & _
38
      Chr$(115) & Chr$(97) & Chr$(85) & Chr$(50) & _
39
      Chr$(63) & Chr$(47) & Chr$(39) & Chr$(35) & _
40
      Chr$(33) & Chr$(32) & Chr$(48) & Chr$(56) & _
41
      Chr$(60) & Chr$(62) & Chr$(120) & Chr$(106) & _
42
      Chr$(255) & Chr$(49) & Chr$(255) & Chr$(76) & _
43
      Chr$(90) & Chr$(5) & Chr$(24) & Chr$(26) & _
44
      Chr$(12) & Chr$(2) & Chr$(18) & Chr$(14) & _
45
      Chr$(16) & Chr$(4) & Chr$(23) & Chr$(13) & _
46
      Chr$(20) & Chr$(7) & Chr$(6) & Chr$(15) & _
47
      Chr$(22) & Chr$(29) & Chr$(10) & Chr$(8) & _
48
      Chr$(3) & Chr$(9) & Chr$(17) & Chr$(11) & _
49
      Chr$(25) & Chr$(27) & Chr$(28) & Chr$(255)
50
      
51
    ReDim Mem(0)
52
End Sub
Die "Umrechnung" von einem ASCII-Zeichen in das entsprechende Morse-Byte 
sieht dann so aus:
1
    'Bei Kleinbuchstaben passen die Adressen in der Zeichentabelle nicht
2
    text = UCase$(text)
3
'[...]
4
       If Mid$(text, i, 1) <> " " Then
5
            'Umlaute erfordern eine Spezialbehandlung, da sie nicht
6
            'in der Zeichentabelle enthalten sind
7
            If LCase$(Mid$(text, i, 1)) = "ä" Then
8
                c = CodeAE
9
            ElseIf LCase$(Mid$(text, i, 1)) = "ö" Then
10
                c = CodeOE
11
            ElseIf LCase$(Mid$(text, i, 1)) = "ü" Then
12
                c = CodeUE
13
            Else
14
                c = Asc(Mid$(MorseCodes, Asc(Mid$(text, i, 1)) - 35, 1))
15
            End If
Das solltest du relativ direkt in deinen Code übernehmen können. 
Natürlich ist die Behandlung von Spezialzeichen hier eigentlich nicht 
ausreichend, aber wenn du vorgefertigte Texte verwendest, passiert da 
nichts.

Gruss,
Philipp

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> Dann kommen von 10 bis ende a-z.

"10" ist sicher ein Tipfehler, aber sonst richtig.

Jetzt ziteren wir mal Onkel Karl Heinz:
1
void morse_string( const char* string )
2
{
3
  while( *string ) {
4
    morse_char( *string );
5
    string++;
6
  }
7
}

So weit so gut.
1
morse_char(char character ) {
2
   uint8_t Morsecode;
3
   character -= '0'; // wir ziehen '0' ab, weil unsere Tabelle erst dort anfängt
4
   Morsecode = (uint8_t) pgm_read_byte (array + character);
5
   PiepMal (Morsecode); // heisst, morse_char bei Dir, benenn' eins von beidem um
6
}

OK?

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> Achso, ihr meint ein Array mit dem Index über alle ASCII zeichen und
> dann an dem Index a (0x61) die Codierung für a speichern

Jau.

von Karl H. (kbuchegg)


Lesenswert?

masl schrieb:
> Ja ok, das mit dem SPeicherplatz soll uns jetzt mal nicht behindern, im
> Moment probier ich eh grad alles aufm mega32.
>
> Aber das mit den ASCII als Indizes check ich noch nich so ganz, sorry ^^
>
> Von 0-9 im Array hab ich jetzt die Codierung für 0-9 abgelegt.
> Dann kommen von 10 bis ende a-z.
> So meint ihr oder?

Nein.

Das was du als Zeichen kennst, ist in Wirklichkeit im Rechner auch nur 
eine Zahl. Erst bei der Ausgabe entscheidet sich, was mit dieser Zahl 
gemacht wird.
Soll die Zahl als Zahl ausgegeben werden, dann muss man dafür eine 
Textrepräsentierung erzeugen. Schickt man aber die Zahl, so wie sie ist, 
ganz einfach zum Ausgabegerät, so weiß das Ausgabegerät selber, das 
diese Zahl für ein Zeichen steht und auch für welches  -> ASCII Code

Stell dir einfach vor du vereinbarst mit deinem Kumpel: Jedesmal wenn 
ich 'A' meine, geb ich dir die Zahl 65, bei 'B' 66, 'C' wird zu '67' 
etc. etc.

Anstelle von 'HALLO WORLD' überträgst du die Zahlen 72, 65, 76, 76, 79 
...

Dein Kumpel weiss dann schon, wie die Nachricht lautet.

Nun gibt es natürlich viele solcher Zuordnungen von Zeichen zu Zahlen.
Eine davon, die sich durchgesetzt hat, nennt sich ASCII.
Und wenn du danach googelst findest du massenweise ASCII Tabellen.

> Jetzt bekommt die Funktion ein Pointer auf ein ASCII zeichen.

Die Funktion bekommt keinen Pointer. Sie bekommt das Zeichen direkt. 
Also eigentlich bekommt sie eine Zahl, und diese Zahl steht für das 
Zeichen. Darum brauchst du dich aber nicht kümmern. Wenn du im Code 'A' 
schreibst, ersetzt der Compiler das für dich mit 65

> ASCII 0x30. Was mach ich jetzt damit?

Du benutzt diese Zahl als Index in ein Array und kriegst so den Code den 
du an deine Ausgabefunktion weiterreichen musst.

Edit: Grrr hat ja schon weitergearbeitet. Er hat dabei auch benutzt, 
dass im ASCII Code die ersten Zeichen allesamt Steuerzeichen sind, die 
du daher nicht in deiner Tabelle brauchst. Allerdings sind vor der '0' 
ein paar für dich interessante Zeichen. Die würde ich nicht auslassen. 
Lass daher deine Tabelle zb beim Leerzeichen anfangen.

von Grrrr (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
>> Von 0-9 im Array hab ich jetzt die Codierung für 0-9 abgelegt.
>> Dann kommen von 10 bis ende a-z.
>> So meint ihr oder?
>
> Nein.

Er meinte, glaube ich, mit "Codierung" die Morsekodierung. Nicht noch 
mal irgendwie vom Symbol >>>1<<< zu dem ASCII-Code, oder sowas.

von Karl H. (kbuchegg)


Lesenswert?

Und falls du dich fragst, warum dieses seltsame Codieren, warum 
speichert man nicht gleich den Text als Text:
Die Antwort ist: In einem Computer ist alles eine Zahl. Jeder Befehl, 
jedes Zeichen, jedes Rechenergebnis. Alles nur Zahlen. Mit etwas anderem 
als mit Zahlen kann ein Computer nicht hantieren. Was diese Zahlen 
bedeuten, wofür sie stehen, entscheidet sich erst bei der Interpretation 
der Zahl. Dem Computer ist das erst mal völlig egal. Wenn sein Programm 
während der Ausführung auf 65 stösst, dann führt er die zugehörige 
Aktion aus (die 65 steht für irgendeinen Befehlscode); Soll er zu den 65 
2 dazuzählen, dann macht er das; werden die 65 über die UART ausgegeben, 
dann erledigt er auch das brav (und das Terminal zeigt dafür ein 'A' an. 
d.h. das Terminal weiß auch nichts von einem 'A', es färbt einfach nur 
die entsprechenden Pixel laut einer Tabelle schwarz, die dein Gehirn 
dann zu einem A macht). Und so wie ein Terminal eine Tabelle hat, welche 
Pixel beim Empfangen der Zahl 65 scharz zu färben sind, so benutzt dein 
Programm eine ähnliche Tabelle, um zu entscheiden in welcher Reihenfolge 
die Di und Da auf den Lautsprecher gelegt werden müssen.

von Grrrr (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Allerdings sind vor der '0'
> ein paar für dich interessante Zeichen. Die würde ich nicht auslassen.
> Lass daher deine Tabelle zb beim Leerzeichen anfangen.

Ooops. Richtig.

von masl (Gast)


Lesenswert?

Hey ihr, also nochmal vielen vielen Dank für die ausführlichen 
Erklärungen und Hilfen, echt super ;)

Hier nochmal der aktuelle Code.
Das Senden von Strings funktioniert jetzt, aber der Array wird ja hier 
bei jedem Funktionsaufruf neu initialisiert, das ist ja nicht so schön.
Schreibe ich den Array dann am besten in den Flash (mit progmem)?

Ja, verschieben könnte ich das ganze auch noch, so dass der Array erst 
ab dem Leerzeichen anfängt, den ganzen Kram davor brauch ich ja nicht.

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> aber der Array wird ja hier

Wo hier?

> bei jedem Funktionsaufruf neu initialisiert
Bei mir nicht.

> Schreibe ich den Array dann am besten in den Flash (mit progmem)?

Ich meine mich dunkel zu erinnern, das davon die Rede war. ;-)

> Ja, verschieben könnte ich das ganze auch noch, so dass der Array erst
> ab dem Leerzeichen anfängt, den ganzen Kram davor brauch ich ja nicht.

Ja.

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> Hier nochmal der aktuelle Code.

Hast den Code vergessen, masl.

von masl (Gast)


Lesenswert?

Jo, stimmt wohl ;)

Erstmal noch das mit dem Progmem hinbekommen.

Also das Array, das ich jetzt behelfsmäßig benutzt hab sah so aus:
1
uint8_t array[127];
2
array[48] = 0b00111111;    // 0
3
array[49] = 0b00111110;
4
array[50] = 0b00111100;
5
array[51] = 0b00111000;
6
array[52] = 0b00110000;
7
array[53] = 0b00100000;
8
array[54] = 0b00100001;
9
array[55] = 0b00100011;
10
array[56] = 0b00100111;
11
array[57] = 0b00101111;    // 9
12
usw.
Ich hab einfach die Codierungen direkt an die "ASCII Stelle" 
geschrieben.

Wie mache ich das jetzt mit dem PROGMEM Array?
Muss ich da alle Werte angeben? Also erst 48 mal die 0 schreiben, bis 
ich dann die erste Codierung (für die 0) schreiben kann?

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> der Array wird ja hier
> bei jedem Funktionsaufruf neu initialisiert

Das ist aus Deinem Code leider nicht ersichtlich.
Bitte poste den kompletten Code.

masl schrieb:
> Wie mache ich das jetzt mit dem PROGMEM Array?

So, wie hier: Beitrag "Re: String als Morsecode ausgeben" und 
hier: Beitrag "Re: String als Morsecode ausgeben" beschrieben.

von Karl H. (kbuchegg)


Lesenswert?

masl schrieb:
> Jo, stimmt wohl ;)
>
> Erstmal noch das mit dem Progmem hinbekommen.
>
> Also das Array, das ich jetzt behelfsmäßig benutzt hab sah so aus:
>
1
uint8_t array[127];
2
> array[48] = 0b00111111;    // 0
3
> array[49] = 0b00111110;
4
> array[50] = 0b00111100;
5
> array[51] = 0b00111000;
6
> array[52] = 0b00110000;
7
> array[53] = 0b00100000;
8
> array[54] = 0b00100001;
9
> array[55] = 0b00100011;
10
> array[56] = 0b00100111;
11
> array[57] = 0b00101111;    // 9
12
> usw.

Nope.
Zieh es aus der Funktion raus, mach es also als ein globles Array.
Und dann initialisierst du es auch gleich
1
 uint8_t array[127] = {
2
   0b00111111,    // Eintrag 0
3
   0b00111110,    //         1
4
   0b00111100,    //         2
5
   0b00111000,    //         3
6
   0b00110000,    //         4
7
   0b00100000,
8
   0b00100001,
9
   ...
10
};

Das ist jetzt einmal eine wenig Tipparbeit, weil du die nicht benutzen 
Einträge nicht einfach auslassen kannst sondern auch mit anführen musst. 
Ich rate dir daneben im Kommentar, zumindest alle 10 Einträge eine 
laufende Nummer dazuzuschreiben (wenn du hex bevorzugst, dann besser 
alle 8), ansonsten kommst du irgendwann durcheinander. Du kannst auch 
gleixch direkt das Zeichen, welches an dieser Stelle im Array steht, 
daneben hinschreiben. Ist vielleicht noch besser.

von masl (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal der Code.
Meine Frage ist:
Wenn ich das jetzt mit dem Progmem mache, muss ich ja beim 
initialisieren des Arrays erstmal die Plätze 0-47 vertrödeln, bis ich 
bei 48 bin, wo ich dann meine COdierung für 0 speichern kann. Gibts da 
ne elegante Lösung?

von masl (Gast)


Lesenswert?

Ja ok Karl heinz, also muss ich alle nicht benutzten Stellen angeben, 
danke

von Karl H. (kbuchegg)


Lesenswert?

Und nenn das Ding nicht array. Benenne Variablen nach ihrer Funktion,
nicht nach ihrem Datentyp. Du baust gerade eine Morsecode-Tabelle, also 
eine Tabelle die die Codes für ein Zeichen enthält

1
uint8_t codes[127] = {
2
   0b00111111,    // Eintrag ' '
3
   0b00111110,    //         '!'
4
   0b00111100,    //         '"'
5
   0b00111000,    //         '#'
6
   0b00110000,    //         '$'
7
   0b00100000,    //         '%'
8
   0b00100001,    //         '&'
9
   ...
10
};

von Grrrr (Gast)


Lesenswert?

masl schrieb:
> Gibts da
> ne elegante Lösung?

Ja, die in dem Beitrag 
Beitrag "Re: String als Morsecode ausgeben" genannte Berechnung, 
namentlich die in der Funktion ausgeführte Subtraktion
(Sag mal. liest eigentlich einer was ich da schreibe?)
1
character -= '0';

Beachte aber bitte, dass Du, wie Karl Heinz schon bemerkt hat, nicht bei 
der Null sondern beim Leerzeichen anfangen musst.

Also bitte ' ' subtrahieren und nicht '0'.


Brublablubrabbelblubrab.

von Karl H. (kbuchegg)


Lesenswert?

masl schrieb:
> Hier mal der Code.
> Meine Frage ist:
> Wenn ich das jetzt mit dem Progmem mache, muss ich ja beim
> initialisieren des Arrays erstmal die Plätze 0-47 vertrödeln, bis ich
> bei 48 bin, wo ich dann meine COdierung für 0 speichern kann. Gibts da
> ne elegante Lösung?

Wie gesagt: die ersten 32 kannst du auslassen.
Du ziehst dann einfach vom char diese 32 ab (noch besser: Du ziehst ' ' 
ab. Ja, das geht) und greifst zu.

von Grrrr (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wie gesagt: die ersten 32 kannst du auslassen.
> Du ziehst dann einfach vom char diese 32 ab (noch besser: Du ziehst ' '
> ab. Ja, das geht) und greifst zu.

Nein. Ich würde sogar sagen, das Du die ersten 32 wegläßt indem Du ' ' 
abziehst von dem Zeichen abziehst.

Gruss Schultz

von masl (Gast)


Lesenswert?

Grrrr schrieb:
> (Sag mal. liest eigentlich einer was ich da schreibe?)

Ja tu ich, aber ich versteh nich gleich alles auf anhieb ;)

von dh2faa (Gast)


Lesenswert?

Hallo,

auf meiner Seite www.dh2faa.de unter Projekte
#16 Feierabendprojekt: Ein Morsezeichengenerator mit dem 2313 und BASCOM
findest Du ein Beispiel für einen Morsezeichengenerator.
Das ganze mit BASCOM und für einen 2313 !
Viel Spaß
Heiko

von masl (Gast)


Angehängte Dateien:

Lesenswert?

Hey dh2faa, danke für den Tipp ;)

So, ich häng mal den vorläufigen Quellcode an.
Funktioniert bis jetzt einwandfrei, werde bei Gelegenheit aber alles 
noch bisschen optimieren.

Vielen Dank für die super Hilfe die ich von euch bekommen habe!!

Grüße
Masl

von Gerhard O. (gerhard_)


Angehängte Dateien:

Lesenswert?

Hallo,

im Anhang ein uC Program wo das Morsen als printf funktioniert mit 
gepufferten Betrieb so dass man ohne unterbrechungen MORSE von der 
keyboard senden kann oder in der Form von printf() wie z.B.

Examples:

printf(put_morse, "CQ CQ CQ DE HAMRADIO");
printf(put_morse, "%03.1f DEG C", ftempC);
printf(put_morse, "%02x", u8_number); (etc)

Mit put_morse(c); lassen sich einzelne Zeichen senden.

In I2CLCD_BEACON.h ist eine Liste der ASCII Zeichen die als MORSE 
verwirklicht sind.

Der Puffer ist ca 190 Bytes - Genug fuer ein paar Minuten morsen.

Gruss,
Gerhard

von masl (Gast)


Lesenswert?

Hey Gerhard, für meine Zwecke reicht mein Progrämmchen schon, aber werd 
deinen Code mal speichern, falls cih was größeres vor habe :)

Vielen Dank!
Gruß Marcel

von Gerhard O. (gerhard_)


Lesenswert?

masl schrieb:
> Hey Gerhard, für meine Zwecke reicht mein Progrämmchen schon, aber werd
> deinen Code mal speichern, falls ich was größeres vor habe :)
>
> Vielen Dank!
> Gruß Marcel

Hi Marcel,

ich wollte damals eigentlich nur wissen ob das mit printf() geht. 
Jedenfalls viel Spass mit Deinem Projekt. In meinem Originalprogramm 
konnte man auch vom Terminal Text als CW ausgeben und wurde schoen 
gleichmaessig abgearbeitet.

Gruss,
Gerhard

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.