Forum: Mikrocontroller und Digitale Elektronik Sonderzeichen in String für LCD-Display


von R. F. (inet_surfer88)


Lesenswert?

Hallo,

ich habe mir zwei Unterprogramme für die Ansteuerung eines LCD-Displays 
geschrieben.
1
string_senden(); //sendet einen String aufs Display
2
3
zeichen_senden(); //sendet ein einzelnes Zeichen ans Display

Die beiden Programme funktionieren einwandfrei. Wenn ich allerdings 
einen String mit ä, ö oder ü sende, wird anstelle der Zeichen nur ein 
komisches Zeichen dargestellt.
1
string_senden("Programm wählen"); //Hier wird anstelle des ä ein komisches Zeichen dargestellt.

Mein Display kann mit dem Hex-Code 0xE1 ein ä darstellen.
Mit folgendem code funktioniert es einwandfrei:
1
string_senden("Programm w"
2
zeichen_senden(0xE1);
3
string_senden("hlen")

Allerdings ist das etwas umständlich. Gibt es eine Möglichkeit, den 
String in einem Aufruf zu senden. printf und solche Sachen würde ich 
wenn möglich nicht nutzen, da dies ja viel Speicher verbraucht.

von Fabian O. (xfr)


Lesenswert?

Ersetze die Sonderzeichen doch einfach in der zeichen_senden()-Funktion.

von R. F. (inet_surfer88)


Lesenswert?

Fabian O. schrieb:
> Ersetze die Sonderzeichen doch einfach in der zeichen_senden()-Funktion.

Dazu muss ich ermitteln, was an das Display bei einem Sonderzeichen 
gesendet wird, muss bei jedem Zeichen das abfragen und wenn ein 
Sonderzeichen kommt das Zeichen ersetzen. Wäre eine Möglichkeit. Aber 
ein Problem:
Beim ü und ö wird irgend was komisches angezeigt. Hier geht das mit dem 
ersetzen, da ich diese komischen Zeichen nicht brauche. Beim ä wird aber 
ein µ angezeigt. Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn 
das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.

Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so 
einzugeben, dass gleich das korrekte Zeichen übermittelt wird?

von Tschortsch (Gast)


Lesenswert?

>Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so
>einzugeben, dass gleich das korrekte Zeichen übermittelt wird?

string_senden("Programm w\0xE1hlen");

von Ingo (Gast)


Lesenswert?

Wenn du deinen String sendest, tust du das Zeichen für Zeichen. Das 
heißt du guckst vor jedem Senden ob es sich bei deinem Zeichen um ein 
Sonderzeichen handelt und schreibst es manuell um.



Ingo

von Hmm (Gast)


Lesenswert?

Es gibt eine Reihe von Möglichkeiten das Problem zu lösen. Unter anderem 
in verschiedenen Ausprägungen auch diejenigen die Du angedeutet hast.

Aber ein Missverständnis solltest Du doch vorher noch klären.

>Beim ä wird aber ein µ angezeigt.
>Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn
>das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.

Dieses Aussage leitet sich, für mich, aus nichts was ich sonst weiss, 
ab. Wie kommst Du darauf?

Nehme ich mal einen Irrtum oder eine Fehlinformation vorweg, dann ist 
das so: Es gibt keinen Zwang beim Austausch von 'ä' gegen 'µ' auch 
gleichzeitig 'µ' gegen 'ä' auszutauschen. Ob Du das tust oder nicht 
steht Dir frei. Es steht Dir auch frei ein schon einmal gegen ein 'µ' 
ausgetauschtes 'ä' nocheinmal oder eben nicht noch einmal zurück gegen 
ein 'µ' zu tauschen.
Willst Du wirklich beide Übersetzungen in jedem auftretenden String 
realisieren, dann musst Du nur dafür sorge, das die Übersetzung nur 
einmal erfolgt.

Wenn Du Deine Aussage nocheinmal genau betrachtest, erkennst Du, das Du 
mit "Wenn ich ersetze..." eine Verkürzung in mehrerlei Hinsicht 
vorgenommen hast. Ich schreibe das nicht, weil das schlimm ist oder 
dumm, sondern weil es ein Zeichen ist, das Du einen Gedanken nicht 
präzis genug formuliert hast um ihn zu realisieren. Verstehst Du was ich 
meine?
Es fehlt: "was" und "wodurch". Es fehlt: Zu welchen Zeitpunkt? In 
welcher Folge?

Das sind ja keine Fragen die Dir nicht aus dem täglichen Leben nicht 
schon bekannt wären. Hat also nichts mit Anfänger zu tun. Erst das 
Waschpulver und die Wäsche (die aber in beliebiger Reihenfolge) dann die 
Tür schliessen, dann starten. Nicht die Wäsche in das Waschpulverfach 
sondern. etcpp.

Genauso detailliert musst Du Dir vor allem bei auftauchenden Problemen 
klarmachen, was geschieht, bzw. was geschehen soll.

Hoffe das hilft Dir.

von Fabian O. (xfr)


Lesenswert?

R. F. schrieb:
> Beim ä wird aber
> ein µ angezeigt. Wenn ich ersetze, kann ich kein µ mehr anzeigen, wenn
> das gewollt ist, da das Zeichen dann durch ein ä ersetzt wird.

Du ersetzt eben in zeichen_senden() auch ein 'µ' durch den Code, den ein 
'ä' jetzt liefert. Du brauchst also eine Zuordnung zwischen 
Eingabezeichen und Code für das Display.

von Wilhelm F. (Gast)


Lesenswert?

Der Zeichensatz eines Displays stimmt oft nicht mit dem Zeichensatz des 
PC überein. Dann definiert man eigene Zeichen, wie die Umlaute ä, ö, ü, 
und ß. Das muß man dann auch in der Software noch mal berücksichtigen.

von Michael A. (Gast)


Lesenswert?

R. F. schrieb:
> Beim ä wird aber ein µ angezeigt. Wenn ich ersetze, kann ich kein µ
> mehr anzeigen, wenn das gewollt ist, da das Zeichen dann durch ein
> ä ersetzt wird.

Doch, du darfst einfach nur kein "ä" senden, wenn du ein "µ" anzeigen 
möchtest. Vergleiche einfach den Character-Generator von deinem Display 
und den Zeichensatz, den du sonst verwendest. Und für den Fall der Fälle 
bieten viele Displays auch die Möglichkeit einige Zeichen selbst frei zu 
definieren.

von R. F. (inet_surfer88)


Lesenswert?

Tschortsch schrieb:
>>Gibt es keine Möglichkeit, den String beim Unterprogrammaufruf so
>>einzugeben, dass gleich das korrekte Zeichen übermittelt wird?
>
> string_senden("Programm w\0xE1hlen");

Habe ich schon ausprobiert. Funktioniert wei dem Wort wählen auch 
wunderbar, da dem Sonderzeichen ein h folgt.

Folgt dem Sonderzeichen aber einer der Buschstaben zwischen A und E 
funktioniert es nicht.

Beispiel: "Sonderzeichen üben"
hier sende ich: "Sonderzeichen \xF5ben" (F5 steht bei meinem Display für 
ü)
Dann kommt heraus: "Sonderzeichen *n" (Anstelle dem Stern irgend 
einanderes komisches Zeichen.

Offenbar erkennt der Compiler \xF5BE als Zeichen, da B und E im 
HEX-Format als "Zahl" vorkommt. Da das ganze gebilde dann zu lang wird, 
nimmt er nur die letzten 2 Stellen und sendet in dem Beispiel BE, was 
mit dem angezeigten Zeichen dann übereinstimmt.

Übrigens: Atmel Studio 6 und Mega16A

von Wilhelm F. (Gast)


Lesenswert?

Man muß sein Zeichen natürlich in der Software zu dem selbst definierten 
Zeichen übersetzen. Um ein ü zu senden, was man bspw. in der 
Speicherstelle 7 definiert hat, muß man dann das ü zu 7 übersetzen.

Vollautomatisch macht es das Display nämlich nicht.

von Hmm (Gast)


Lesenswert?

>Offenbar...

Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte 
nach.
Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil 
der Hexzahl betrachtet.

von Tschortsch (Gast)


Lesenswert?

>Beispiel: "Sonderzeichen üben"
>hier sende ich: "Sonderzeichen \xF5ben" (F5 steht bei meinem Display für
>ü)
>Dann kommt heraus: "Sonderzeichen *n" (Anstelle dem Stern irgend
>einanderes komisches Zeichen.

Dann musst du das Sonderzeichen als Oktalzahl eingeben.

Ein Byte als Oktalzahl besteht immer aus drei Stellen. Im String werden 
Oktalzahlen mit \0 eingegeben, dann gibts keine Verwechslungsmöglichkeit 
mehr.


hexadezimal F5 = dezimal 245 = oktal 365

string_senden("Sonderzeichen \0365ben");

Zum Umrechnen von Hex nach Oktal kann man bequem den Windows 
Taschenrechner verwenden.

von Hmm (Gast)


Lesenswert?

>Dann musst du das Sonderzeichen als Oktalzahl eingeben.
Nein. Das ist unnötig. Siehe meine Antwort darüber.

von R. F. (inet_surfer88)


Lesenswert?

Hmm schrieb:
>>Offenbar...
>
> Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte
> nach.
> Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil
> der Hexzahl betrachtet.

Diese Lösung wäre mir ehrlich gesagt am liebsten. Aber wie bereits 
geschrieben, funktionieren tut es bei mir mit dem Atmel Studio nicht. 
Mache ich eventuell bei der Eingabe was falsch? Anstelle des 
Sonderzeichens schreibe ich z.B. \xF5, ohne weitere Formatierung. Das 
müsste doch so korrekt sein, und funktioniert ja auch, solange kein A-F 
folgt.

Ich habe mir aber nochmals zu dem ersetzen Gedanken gemacht. Ich hatte 
da mit meinen µ und ä noch einen Denkfehler. Ich glaube ich habe eine 
funktionierene Lösung im Kopf. Muss es nur noch Programmieren und 
testen.
Werde dann noch mal Rückmeldung geben.

von R. F. (inet_surfer88)


Lesenswert?

Tschortsch schrieb:

> Ein Byte als Oktalzahl besteht immer aus drei Stellen. Im String werden
> Oktalzahlen mit \0 eingegeben, dann gibts keine Verwechslungsmöglichkeit
> mehr.

\0 erkennt mein Programm string_senden als Stringende und höhrt auf zu 
senden.

von Hmm (Gast)


Lesenswert?

>Diese Lösung wäre mir ehrlich gesagt am liebsten.

Es geht hier nicht um eine Lösung. Was ich beschrieb war keine Lösung, 
sondern ein Teil der Sprach-Definition. Das ist so. Egal ob Du das als 
Lösung betrachtest oder nicht. Du hast gar keine Wahl.

Es ist wahrscheinlicher das Deine Beobachtung nicht vollständig oder 
korrekt ist. Oder das Deine Beschreibung der Umgebung nicht vollständig 
ist. Es gibt durchaus denkbare Fälle wo dieses Verhalten sinnvoll ist. 
Nur passen die normalerweise und nicht widerspruchsfrei zu Deiner 
Situation. z.B. Unicode-Strings.

Deswegen ist das hier:

>Ich habe mir aber nochmals zu dem ersetzen Gedanken gemacht.

auch zwecklos, solange die Voraussetzungen für diese Gedanken nicht 
korrekt sind. Du kommst nämlich zu falschen Schlüssen, solange die zur 
Voraussetzung haben, das \x nicht so funktioniert wie beschrieben.

>Mache ich eventuell bei der Eingabe was falsch? Anstelle des
>Sonderzeichens schreibe ich z.B. \xF5, ohne weitere Formatierung. Das
>müsste doch so korrekt sein, und funktioniert ja auch, solange kein A-F
>folgt.

Du beliebst leider keine Angaben zu dem Display oder zu der Library zu 
machen. Ergänze das bitte erstmal.

von Hmm (Gast)


Lesenswert?

>\0 erkennt mein Programm string_senden als Stringende und höhrt auf zu
>senden.

Ja. Das stimmt auch mit dem Sprachstandard überein.

Es stand ja auch da:
>in Byte als Oktalzahl besteht immer aus drei Stellen.

Bitte lies solche Aussagen immer gründlich und vollständig. Du kannst 
nicht einfach nach belieben Teile von Aussagen weglassen, darauf 
basierend was probieren und uns das hier als Fehler präsentieren ohne 
auf die Dauer Unmut oder jedenfalls Weg-Gehen zu provozieren. Und lies 
bitte immer eine C-Buch parallel zu solchen Sprachdefinitions-Fragen. 
Nicht alles kann man immer feherfrei und vollständig wiedergeben.

von troll (Gast)


Lesenswert?

Hmm schrieb:
> Nicht alles kann man immer feherfrei und vollständig wiedergeben.
Du sagst es. :-)

scnr

von Karl H. (kbuchegg)


Lesenswert?

R. F. schrieb:
> Hmm schrieb:
>>>Offenbar...
>>
>> Da ist keine Vermutung nötig. Das ist genau festgelegt. Lies das bitte
>> nach.
>> Es werden nur und genau die ersten beiden Ziffern nach dem x als Teil
>> der Hexzahl betrachtet.
>
> Diese Lösung wäre mir ehrlich gesagt am liebsten.

Abgesehen von der Defintion, wie man Character durch Angabe ihres 
Hex-Codes in einen String einbettet, ist diese Lösung trotzdem Unsinn. 
Denn du willst dich nicht um solche Dinge kümmern müssen. Als 
Programmierer willst du schreiben

  lcd_string( "bitte wählen" );

und es ist Aufgabe der lcd_string Funktion bzw. der Funktion die von der 
lcd_string benutzt wird um ein Zeichen (Achtung: Zeichen! Nicht Byte!) 
auszugeben, für das 'ä', bzw. all die anderen Zeichen, den jeweils 
zuständigen Code ans LCD zu schicken, den das LCD für dieses Zeichen 
eben haben will. So viele derartige Sonderzeichen sind das ja nicht.

Alles andere ist zwar insofern interessant, weil es ein Technik ist, die 
man als C-Programmierer selbstverständlich ebenfalls beherrschen muss, 
aber in diesem Fall ist es Unsinn das so zu lösen.

Als Autofahrer kümmerst du dich ja auch nicht darum, welches Zahnrad in 
welches andere Zahnrad greifen muss, damit der 4. Gang eingelegt ist. 
Das ist Aufgabe des Getriebes das zu tun. Du legst den Ganghebel einfach 
in das Fach der H-SChaltung, welches mit 4 beschriftet ist. Und den Rest 
erledigt die Mechanik.

von R. F. (inet_surfer88)


Lesenswert?

So, jetzt habe ich mal meinen Code für zeichen_senden erweitert. Ich 
ersetze jetzt mittels einer switch case die Zeichen ä ö und ü. 
Funktioniert einwandfrei. Jetzt noch in Fleissarbeit die restlichen 
benötigten Sonderzeichen einfügen und das Problem ist gelößt.

Jetzt kann ich ganz normal string_senden("Sonderzeichen üben"); eingeben 
und es wird korrekt angezeigt.

Mein Problem ist damit gelößt. Jetzt kann ich an meinem Projekt 
weiterarbeiten.

Allerdings würde mich noch interessieren, warum es mit \xF5 nicht 
funktioniert.

Ich gebe ein: string_senden("Sonderzeichen \xF5ben");
Es wird angezeigt: Sonderzeichen *n

Ich gebe ein: string_senden("Sonderzeichen \xF5iben");
Es wird angezeigt: Sonderzeichen üiben

Bei dem unteren Beispiel mache ich einen Schreibfewhler mit dem 
zusätzlichen i, damit auf die HEX-Zahl kein A-F folgt. Dann ist die 
Anzeige korrekt.

Hier nochmal ein paar Daten:

Mega16A
AtmelStudio 6
4x20er Display mit ST7066-Controller ROM-Code 0A

Die Programme habe ich komplett selbst geschrieben, verwende also keine 
fertige Library (erhöht den Lerneffekt).

Durch das viele Ausprobieren und ändern fehlt hier momentan etwas die 
Struktur. Ich bringe das ganze mal noch in "Form" und kann das Programm 
dann noch hochladen.

von Wilhelm F. (Gast)


Lesenswert?

R. F. schrieb:

> So, jetzt habe ich mal meinen Code für zeichen_senden erweitert. Ich
> ersetze jetzt mittels einer switch case die Zeichen ä ö und ü.
> Funktioniert einwandfrei.

Na also. Durch den switch case muß alles durch. Bleibt immer noch die 
Frage, ob man wirklich alles mit deutschen Umlauten dar stellen muß.

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.