mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik String als Morsecode ausgeben


Autor: masl (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
void morse_string( const char* string )
{
  while( *string ) {
    morse_char( *string );
    string++;
  }
}

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
void morse_zeichen( char c )
{
  ... Du bist drann
}

und ich rufe sie so auf
  morse_zeichen( 'h' );
  morse_zeichen( 'a' );
  morse_zeichen( 'l' );
  morse_zeichen( 'l' );
  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.

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
// array beginn mit Zahlen
char MorseCode [] = {
0x1F,                           // 000111111 '0'
0x1E,                           // 111110    '1'

etc.

0x0D,                          // 00001101 'a'


Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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? ^^

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

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

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ganze soll nämlich möglichst auf einen ATtiny13.

ui das wird eng

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Grrrr (Gast)
Datum:

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

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".
// array beginn mit den Ziffern
char MorseCode PROGMEM [] = {
0x1F,                           // 000111111 '0'
0x1E,                           // 111110    '1'

etc.

0x0D,                          // 00001101 'a'

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

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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei den Ziffern gibts ein Schema
#define _0_ 0b00111111
#define _1_ 0b00111110
#define _2_ 0b00111100
#define _3_ 0b00111000
#define _4_ 0b00110000
#define _5_ 0b00100000
#define _6_ 0b00100001
#define _7_ 0b00100011
#define _8_ 0b00100111
#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.

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht 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:
Private Sub Form_Load()
    'Aus diesem String werden die Töne für die einzelnen Zeichen
    'generiert. Zur einfachen Speicherung wird folgendes Verfahren
    'angewandt:
    'Jedes Byte (8 Bit) repräsentiert den Morsecode für ein
    'bestimmtes Zeichen im ANSI-Zeichensatz. Da die Zeichen
    'unterhalb 36 ohnehin keine Entsprechung im Morsecode haben,
    'bzw. gar nicht darstellbar sind, wurden sie weggelassen.
    'Jedes Bit dieser Bytes stellt nun ein Dit oder ein Dah dar.
    'Da die Morsezeichen aber nicht alle gleich lang sind, sind
    'die Zeichendaten innerhalb der Bytes rechts ausgerichtet und
    'ganz oben mit einem Startbit versehen.
    '
    'Beispiele:
    '
    'Buchstabe n (dahdit):
    '0b0000 0110 (6)
    '/       ^^^
    '/       ||`-- Dit
    '/       |`--- Dah
    '/       `---- Startbit
    '
    'Zahl 0 (dadadadadah)
    '0b0011 1111 (63)
    '/   ^^ ^^^^
    '/   || |||`-- Dah
    '/   || ||`--- Dah
    '/   || |`---- Dah
    '/   || `----- Dah
    '/   |`------- Dah
    '/   `-------- Startbit
    '
    'Der Wert 255 (theoretisch sieben Dahs) entspricht keinem
    'Zeichen, sondern markiert leere Bytes.
    MorseCodes = _
      Chr$(255) & Chr$(255) & Chr$(255) & Chr$(94) & _
      Chr$(54) & Chr$(109) & Chr$(255) & Chr$(42) & _
      Chr$(115) & Chr$(97) & Chr$(85) & Chr$(50) & _
      Chr$(63) & Chr$(47) & Chr$(39) & Chr$(35) & _
      Chr$(33) & Chr$(32) & Chr$(48) & Chr$(56) & _
      Chr$(60) & Chr$(62) & Chr$(120) & Chr$(106) & _
      Chr$(255) & Chr$(49) & Chr$(255) & Chr$(76) & _
      Chr$(90) & Chr$(5) & Chr$(24) & Chr$(26) & _
      Chr$(12) & Chr$(2) & Chr$(18) & Chr$(14) & _
      Chr$(16) & Chr$(4) & Chr$(23) & Chr$(13) & _
      Chr$(20) & Chr$(7) & Chr$(6) & Chr$(15) & _
      Chr$(22) & Chr$(29) & Chr$(10) & Chr$(8) & _
      Chr$(3) & Chr$(9) & Chr$(17) & Chr$(11) & _
      Chr$(25) & Chr$(27) & Chr$(28) & Chr$(255)
      
    ReDim Mem(0)
End Sub
Die "Umrechnung" von einem ASCII-Zeichen in das entsprechende Morse-Byte 
sieht dann so aus:
    'Bei Kleinbuchstaben passen die Adressen in der Zeichentabelle nicht
    text = UCase$(text)
'[...]
       If Mid$(text, i, 1) <> " " Then
            'Umlaute erfordern eine Spezialbehandlung, da sie nicht
            'in der Zeichentabelle enthalten sind
            If LCase$(Mid$(text, i, 1)) = "ä" Then
                c = CodeAE
            ElseIf LCase$(Mid$(text, i, 1)) = "ö" Then
                c = CodeOE
            ElseIf LCase$(Mid$(text, i, 1)) = "ü" Then
                c = CodeUE
            Else
                c = Asc(Mid$(MorseCodes, Asc(Mid$(text, i, 1)) - 35, 1))
            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

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void morse_string( const char* string )
{
  while( *string ) {
    morse_char( *string );
    string++;
  }
}

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

OK?

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
masl schrieb:
> Hier nochmal der aktuelle Code.

Hast den Code vergessen, masl.

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, stimmt wohl ;)

Erstmal noch das mit dem Progmem hinbekommen.

Also das Array, das ich jetzt behelfsmäßig benutzt hab sah so aus:
uint8_t array[127];
array[48] = 0b00111111;    // 0
array[49] = 0b00111110;
array[50] = 0b00111100;
array[51] = 0b00111000;
array[52] = 0b00110000;
array[53] = 0b00100000;
array[54] = 0b00100001;
array[55] = 0b00100011;
array[56] = 0b00100111;
array[57] = 0b00101111;    // 9
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?

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
>
uint8_t array[127];
> array[48] = 0b00111111;    // 0
> array[49] = 0b00111110;
> array[50] = 0b00111100;
> array[51] = 0b00111000;
> array[52] = 0b00110000;
> array[53] = 0b00100000;
> array[54] = 0b00100001;
> array[55] = 0b00100011;
> array[56] = 0b00100111;
> array[57] = 0b00101111;    // 9
> usw.

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

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.

Autor: masl (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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?

Autor: masl (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

uint8_t codes[127] = {
   0b00111111,    // Eintrag ' '
   0b00111110,    //         '!'
   0b00111100,    //         '"'
   0b00111000,    //         '#'
   0b00110000,    //         '$'
   0b00100000,    //         '%'
   0b00100001,    //         '&'
   ...
};

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?)
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: masl (Gast)
Datum:

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

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

Autor: dh2faa (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: masl (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Gerhard O. (gerhard_)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gerhard O. (gerhard_)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.