Forum: Mikrocontroller und Digitale Elektronik lcd string "ü" darstellen.


von Sebastian B. (sebastian86)


Angehängte Dateien:

Lesenswert?

Guten Morgen zusammen,

Ich habe mal eine frage zum "sprintf" Befehl.


Und zwar möchte ich auf meinem LCD Belüftung schreiben.

bei diesem Code:
1
set_cursor(0,2);
2
sprintf( Out, "Bel\x5Fftung");
3
lcd_string( Out );
erhalte ich folgende warnung:

"warning: hex escape sequence out of range"


Also um ein "ü" darzustellen muss ich mit dem "\x" + "5F" quasi die 
HEX-Zahl in den string packen.
Wenn ich das so compiliere steht auf dem LCD
"Bel_tung" Der Unterstrich deutet nur an das dort ein Komplett schwarze 
Kästchen ist.
Wie man dadran sieht fehlt das "f" von Belüftung und das "ü" wird nicht 
dargestellt. Der fehler kommt irgendwie daher das bei dem 
"Bel"\x5F"ftung"
das kleine "f" noch zu diesem HEX-Umwandlungs-Befehl(?!) genommen wird.
(Wie nennen man diesen Backslash-Umwandlungsteil eigentlich?

Denn wenn ich in dem Code:
1
set_cursor(0,2);
2
sprintf( Out, "\x5F");
3
lcd_string( Out );
schreibe dann wird mir ein "ü" angezeigt.

Vieleicht kann mir da jemand schnell helfen da ich nicht genau weiss 
nach was ich gucken soll da ich nicht weiss wie der "\x"-teil überhaupt 
heißt.

Gruß
Sebastian

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Brünsing schrieb:

> dargestellt. Der fehler kommt irgendwie daher das bei dem
> "Bel"\x5F"ftung"
> das kleine "f" noch zu diesem HEX-Umwandlungs-Befehl(?!) genommen wird.

Du hast das Problem erkannt.

> (Wie nennen man diesen Backslash-Umwandlungsteil eigentlich?

Keine Ahnung. Allgmein sind das Escape Sequenzen. Ob die 
Hex-Ausgabe-Escape-Sequenz einen eigenen, kurzen Namen hat, weiß ich 
aber nicht auswendig.

> Vieleicht kann mir da jemand schnell helfen da ich nicht genau weiss
> nach was ich gucken soll da ich nicht weiss wie der "\x"-teil überhaupt
> heißt.

Die Lösung besteht darin, dass der Compiler automatisch Strings, die 
aufeinander folgen, zusammenhängen muss
1
sprintf( Out, "Bel" "\x5F" "ftung");

Meistens macht man das so
1
#define CHAR_UE    "\x5F"
2
3
sprintf( Out, "Bel" CHAR_UE "ftung");

dann wirds auch an der Verwendungsstelle etwas klarer.

Eine andere Möglichkeit besteht darin, dass man sich die lcd_string 
Funktion pimpt, so dass die ein 'ü' im Text gegen 0x5F austauscht. Dann 
braucht man an der verwendenden Stelle überhaupt nichts tun, der 
'LCD-String-Treiber' erledigt die Anpassung
1
void lcd_string( const char* text )
2
{
3
  char c;
4
5
  while( ( c = *text++ ) ) {
6
    if( c == 'ü' )
7
      lcd_data( 0x5F );
8
    else
9
      lcd_data( c );
10
  }
11
}
12
13
14
sprintf( Out, "Belüftung");
15
lcd_string( Out );

Dasselbe natürlich auch noch für ä ö ß und was es sonst noch so gibt.

PS: Wenn die lcd_data Funktion (oder wie auch immer die bei dir heißt) 
ausschliesslich dazu benutzt wird, Zeichen auszugeben, dann kann man die 
Ersetzung sinnvollerweise auch dort hinein verpflanzen. Zur Not kann man 
sich auch immer noch eine eigene Zeichen-Ausgabe Funktion schreiben, die 
nur diese Ersetzung macht und dann lcd_data aufruft und von überall her 
benutzt wird, wenn es gilt ein Zeichen auszugeben
1
void lcd_char( char c )
2
{
3
  if( c == 'ü' )
4
    c = 0x5F;
5
6
  lcd_data( c );
7
}
8
9
void lcd_string( const char* text )
10
{
11
  while( *text )
12
    lcd_char( *text++ );
13
}
14
15
16
sprintf( Out, "Belüftung");
17
lcd_string( Out );
18
19
lcd_string( "Belüftung ist ein" );

von Jens G. (jensig)


Lesenswert?

vielleicht gibt's auch eine LCD-Funktion, die nicht Characterstrings 
verdaut, sondern reine Bytes, die dann 1:1 ans LCD weitergegeben 
werden.Irgendwann vor ein paar Wochen hatte ich doch schon mal so eine 
ähnliche Frage beantwortet.

von Sebastian B. (sebastian86)


Lesenswert?

Ja Danke Karl Heinz,


das werde ich nachher direkt mal ausprobieren. das mit dem aussondieren 
und dann halt später die automatische umwandlung von ä ü ö


Vielen Dank

von Karl H. (kbuchegg)


Lesenswert?

Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in 
ein char Array umzukopieren, nur um dann damit die Ausgabefunktion 
aufzurufen?

1
  set_cursor(0,2);
2
  sprintf( Out, "Belüftung");
3
  lcd_string( Out );

so ist es doch viel kürzer und auch schneller
1
  set_cursor(0,2);
2
  lcd_string( "Belüftung" );


sprintf brauchst du nur dann, wenn in den Text auch noch Ausgaben zb in 
Form von Zahlenwerten eingebaut werden sollen (und die auch nur dann, 
wenn du spezielle Formatierungswünsche hast)
1
  set_cursor(0,2);
2
  sprintf( Out, "Belüftung Stufe %d", ventLevel );
3
  lcd_string( Out );

von XXXXX (Gast)


Lesenswert?

Hallo

Versuch doch mal:

Bel\x5f\ftung

Bin mir nicht ganz sicher, aber einen Versuch ist es wert.

Gruß
JJ

von Karl H. (kbuchegg)


Lesenswert?

XXXXX schrieb:

> Versuch doch mal:
> Bel\x5f\ftung
> Bin mir nicht ganz sicher, aber einen Versuch ist es wert.

Nein, eigentlich ist das keinen Versuch wert.
Da haben die Gründerväter von C ganz einfach geschlafen und nicht 
spezifiziert bzw. gar nichts dafür vorgesehen, woran der Compiler 
erkennen kann, dass eine direkt angegebene Hex-Zahl definitiv zu Ende 
ist. Solange der nächste Buchstabe zur Hex-Zahl gehören könnte, tut er 
das auch. Das f in 'Belüftung' ist eine mögliche Ziffer einer Hex Zahl 
und gehört damit zur Hex-Zahl dazu, ob du willst oder nicht.

Aus der Tatsäche, dass das jetzt seit nahezu 40 Jahren nicht akut genug 
war, um die Normaungsgremien auf Abhilfe sinnen zu lassen, kann man wohl 
auch ableiten, dass es in der Praxis kein allzugroßes Problem darstellt.

von H.Joachim S. (crazyhorse)


Lesenswert?

Gibt ja noch ne Menge mehr Sonderzeichen, die in der Codierung nicht mit 
ASCII übereinstimmen (Umlaute gross und klein, °, µ etc).
Wenn du Platz genug hast: komplette Zeichsatztabelle hinterlegen 
(128..255 reicht eigentlich) und in der Ausgaberoutine den tatsächlichen 
Zeichencode holen.
Ansonsten musst du eben jeden Sonderfall einzeln bearbeiten.

von Sebastian B. (sebastian86)


Lesenswert?

Karl heinz Buchegger schrieb:
> Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in
> ein char Array umzukopieren, nur um dann damit die Ausgabefunktion
> aufzurufen?
>
>


Gute Frage xD. Das hab ich einmal zu kopiert und war dem noch nicht 
nachgegangen. ich wusste garnicht das es anders auch geht ich dachte 
beim sprintf würde noch irgendwas umgewandelt.

Danke fuer den Tipp, ich bin ja noch am lernen :)

von Bastelphilipp (Gast)


Lesenswert?

1
//**********************************************************************
2
void LCD_Anzeige_Text(unsigned char pos,char string[])
3
{
4
    unsigned char i;
5
    LCD_Instruction((unsigned char) pos);
6
    for (i=0;string[i];i++)
7
    switch(string[i])
8
    {
9
            case'ä':
10
            case'Ä':LCD_Zeichen(0xE1);
11
            break;
12
            case'ö':
13
            case'Ö':LCD_Zeichen(0xEF);
14
            break;
15
            case'ü':
16
            case'Ü':LCD_Zeichen(0xF5);
17
            break;
18
            default:LCD_Zeichen(string[i]);
19
    }
20
}
21
//**********************************************************************

von Hc Z. (mizch)


Lesenswert?

> das werde ich nachher direkt mal ausprobieren. das mit dem aussondieren
> und dann halt später die automatische umwandlung von ä ü ö

Beim Aussondieren kannst Du in eine Falle laufen: Du hängst vom 
Zeichensatz ab, und der wird häufig UTF-8 sein.  Dann aber wird ein „ü“ 
mit 2 Bytes dargestellt (0xC3 0xBC)¹, und Du müsstest das auch noch 
erkennen.

Die Version mit CHAR_UE umschifft das Problem.

(¹ und Apple kodiert es nochmal anders - ein „u“ und eine Diaeresis.)

von H.Joachim S. (crazyhorse)


Lesenswert?

Was auch funktionieren kann (hängt evtl. vom Editor/Compiler ab)
sprintf( Out, "Bel§ftung");

Den Hex-Code für das darzustellende Zeichen (LCD-Zeichensatz) mit Alt 
und Nummernblock dezimal eingeben.
0xF5 ->245dez
Alt halten, dann 245 eingeben. Kommt auf dem Bildschirm natürlich das 
falsche Zeichen.

von Falk B. (falk)


Lesenswert?

@  Karl heinz Buchegger (kbuchegg) (Moderator)

>Woher kommt eigentlich dieser Unsinn, einen fixen Text erst einmal in
>ein char Array umzukopieren, nur um dann damit die Ausgabefunktion
>aufzurufen?

Aus dem Tutorial wahrscheinlich. Und selbst deine zweite Methode ist auf 
dem AVR Unsinn, Stichwort RAM-Verschwendung und pgmspace.h.

1
#include <avr/pgmspace.h>
2
  set_cursor(0,2);
3
  lcd_string_P( PSTR("Belüftung") );

Werd ich demnächst mal ins Tutorial einbauen.

MfG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:

> Werd ich demnächst mal ins Tutorial einbauen.

Bedenke bitte aber auch, dass du es mit Anfängern zu tun hast. Du darfst 
nicht gleich mit der ultimativen Lösung ins Haus fallen, damit 
überfährst du sie durch zuviel Information auf einmal. Das überblicken 
sie dann nicht mehr.

Siehe zb die vielen Fragesteller, die es nicht schaffen, sich aus dem 
Tutorial aus dem Abschnitt über Flash-Zugriffe das Arbeiten mit Strings 
im Flash herauszulesen (was natürlich zum großen Teil daran liegt, dass 
sie nicht wissen wie Strings funktionieren, aber das ist eine andere 
Baustelle)

von Jadeclaw (Gast)


Lesenswert?

Hc Zimmerer schrieb:
> Beim Aussondieren kannst Du in eine Falle laufen: Du hängst vom
> Zeichensatz ab, und der wird häufig UTF-8 sein.  Dann aber wird ein „ü“
> mit 2 Bytes dargestellt (0xC3 0xBC)¹, und Du müsstest das auch noch
> erkennen.

Das Problem erschlage man mit der Verwendung eines Nicht-Unicode-fähigen 
Zeichensatzes im Editor. Ich habe mir FixedSys im AVR-Studio 
eingestellt, Unicode-Sauereien fallen da sofort auf.
Zeichensätze sind unter 'Start' --> 'Alle Programme' --> 'Zubehör' --> 
'Systemprogramme' --> 'Zeichentabelle' anzusehen,

Bastelphilipp (Gast) schrub am 09.06.2010 um 10:56:
[Etwas code]

In dieser Art hatte ich das Problem bei einem M50530-basierten Display 
erschlagen, die Umlaute waren da etwas merkwürdig im Zeichensatz 
verteilt. Nur habe ich die Ersetzung direkt in der LCD-Ausgabe-Routine 
versenkt.

Gruß
Jadeclaw.

von Hc Z. (mizch)


Lesenswert?

Jadeclaw schrieb:
> Das Problem erschlage man mit der Verwendung eines Nicht-Unicode-fähigen
> Zeichensatzes im Editor.

Solange Du sicher bist, dass kein anderer (Du selbst in ein paar Jahren 
inklusive) da mit einem anderen Editor rangeht, kannst Du das natürlich 
machen.

von Falk B. (falk)


Lesenswert?

@  Karl heinz Buchegger (kbuchegg) (Moderator)

>> Werd ich demnächst mal ins Tutorial einbauen.

>Bedenke bitte aber auch, dass du es mit Anfängern zu tun hast. Du darfst
>nicht gleich mit der ultimativen Lösung ins Haus fallen,

Hab ich das in meinen bisherigen Tuturials gemacht?

MFG
Falk

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.