Forum: Mikrocontroller und Digitale Elektronik Sonderzeichen mit sprintf


von Sven W. (wache)


Lesenswert?

Moin!

Ich möchte auf meinem Display folgendes darstellen:

Winkel: 123,3°

Mein Problem ist das °-Zeichen.

Mein vorgehen ist das folgende:
1
sprintf(text, "Winkel: %5.1f°", Winkel);

auch die Version
1
sprintf(text, "Winkel: %5.1f" "°", Winkel);
fuktioniert auch nicht.

Leider will das aber nicht. Was mache ich denn falsch?

Die Entwicklungsumgebung ist WinAVR mit dem AVRStudio. Der µC ist ein 
AT90CAN128 und das Display ist ein eDIP240-7 über I2C angesteuert.

Vielen Dank schon einmal für die Antworten!

Gruß,

Sven

von Martin (Gast)


Lesenswert?

Hallo, versuchs doch mal mit

sprinf("Winkel: 123,4%c", 123);

die 123 sollen das Grad Zeichen darstellen, musste mal im Datenblatt des 
Displays nachschauen, welcher es wirklich ist.

von Sven P. (Gast)


Lesenswert?

Guck mal, ob dein Display den Kringel überhaupt im Zeichensatz hat.

von Sven W. (wache)


Lesenswert?

Moin!

Die Option %c funktioniert nicht. Gibt es die denn überhaupt im GCC 
Compiler? Ich kenne die nur unter C++.
Laut Datenblatt sol das °-Zeichen Lower 8 und Upper 240 sein (dez). Das 
müsste doch 248 ergeben, oder?

weder
1
sprintf(text, "Winkel: %3.1f %c", Winkel, 248);
noch
1
sprintf(text, "Winkel: %3.1f %c", Winkel, '°');

führen zum Erfolg.

Irgendwie komisch...

Noch jemand eine Idee?

Gruß,

Sven

von Gast (Gast)


Lesenswert?

Hi,

ich hab so was mal in Bascom gemacht. Mein Code dazu sieht so aus:

Befehle = "#ZF3,#ZL10,70,Temperatur:  xx.x{248}C{013}"

xx.x wird später mit ASCII zeichen aufgefüllt und die 248 ist das 
°-Zeichen.
Bei mir ist das die Schriftart 3 aus dem Datenblatt. Benutzt du 
vielleicht eine Andere, in der das °-Zeichen nicht vorkommt?

Ansonsten sieht das mit dem %c und 248 für mich erstmal richtig aus.

Viele Grüße

von Kobaltchlorid (Gast)


Lesenswert?

Sonderzeichen werden in einem C-String normalerweise mit Backslash, 
führender Null und dem Oktalwert des Zeichens angegeben. Wenn dein '°' 
auf deinem Display den Dezimalwert 248 hat, sollte eigentlich
1
 sprintf(text, "Winkel: %3.1f\0370", Winkel);
zum Ziel führen.

Die Umrechnung Dezimal-Oktal macht übrigens ganz bequem der 
Windows-Rechner in der wissenschaftlichen Ansicht. Im Dezimal-Modus 
deine Dezimalzahl eingeben, links dann Okt statt Dez anklicken, 
Umrechnung fertig.

Welchen (Dezimal-)Wert das Grad-Zeichen wirklich hat, lässt sich leicht 
feststellen, schick' einfach alle Werte von 0-255 an das Display.

von spess53 (Gast)


Lesenswert?

Hi

>Welchen (Dezimal-)Wert das Grad-Zeichen wirklich hat, lässt sich leicht
>feststellen, schick' einfach alle Werte von 0-255 an das Display.

Oder im Datenblatt nachsehen. Sollte 0xDF sein.

MfG Spess

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Statt der antiquierten Oktaldarstellung lässt C seit C89 in Strings auch 
hexadezimale Zeichenkonstanten zu. 248dez ist 0xf8, was mit
1
sprintf(text, "Winkel: %3.1f\xf8", Winkel);

ausgegeben werden sollte. Wenn Spess aber richtig liegt, ist 248 und 
also auch 0xf8 falsch, und sollte durch 223 resp. 0xdf ersetzt werden.

von H.Joachim S. (crazyhorse)


Lesenswert?

kommt aufs Display an.
sprintf (lcd_buffer,"%2uß",KTY10);         //Temperatur anzeigen

Mal so ein Fragment aus einem alten Programm :-)

von yalu (Gast)


Lesenswert?

Ich habe gerade im HD44780-Datenblatt nachgeschaut. Falls dein Display
einen dazu kompatiblen Controller ohne zusätzlichen µC zur Umsetzung von
Zeichencodes hat, ist 0xDF richtig, wie spess53 oben geschrieben hat.

Also so:
1
  sprintf(text, "Winkel: %5.1f\xdf", winkel); // hex

oder so:
1
  sprintf(text, "Winkel: %5.1f\337", winkel); // okt

oder (umständlich) so:
1
  sprintf(text, "Winkel: %5.1f%c", winkel, 223); // dez

> Laut Datenblatt sol das °-Zeichen Lower 8 und Upper 240 sein (dez).
> Das müsste doch 248 ergeben, oder?

Die 248 ist der Code für ° in der alten IBM-Zeichencodierung (unter
DOS). Wenn das im Datenblatt des Displays so steht, dann ist es
vielleicht doch eines der intelligenteren. Um welchen Typ handelt es
sich denn?

Kobaltchlorid schrieb:
> sprintf(text, "Winkel: %3.1f\0370", Winkel);

Nur zur Info: Die 0 nach dem Backslash ist zuviel. Oktale
Zeichenkonstanten dürfen maximal 3 Ziffern enthalten.

H.joachim Seifert schrieb:
> kommt aufs Display an.
> sprintf (lcd_buffer,"%2uß",KTY10);         //Temperatur anzeigen

ß hat in der Zeichencodierung nach ISO 8859-1 und -15 den Code 223 bzw.
0xdf, was der HD44780 als ° darstellt (s.o.).

@Sven W.:

Welches Zeichen wird den statt des ° auf dem Display angezeigt?

von Kobaltchlorid (Gast)


Lesenswert?

> Nur zur Info: Die 0 nach dem Backslash ist zuviel. Oktale
> Zeichenkonstanten dürfen maximal 3 Ziffern enthalten.

ich habe die Version mit führender Null aus irgendeinem C-Buch, weiss 
jetzt aber nicht mehr, aus welchem. Ich programmiere mit CodevisionAVR, 
da funktioniert es ausschliesslich mit führender Null, auch bei 
dreistelligen Oktalzahlen. Interessanterweise funktioniert aber auch 
\xF8.

[c] "Test\0370 Test\370 Test\xF8" /[c]

wird bei mir angezeigt als: Test° Test70 Test°

In der Codevision-Doku steht überhaupt nichts zu dem Thema. Ich war 
deshalb der Meinung, dass die Version mit vorangestellter Null auch bei 
größeren Oktalzahlen gängiger Standard ist.

von yalu (Gast)


Lesenswert?

> Ich programmiere mit CodevisionAVR, da funktioniert es ausschliesslich
> mit führender Null, auch bei dreistelligen Oktalzahlen.

Dann ist dieser Compiler nicht standardkonform.

> "Test\0370 Test\370 Test\xF8"
>
> wird bei mir angezeigt als: Test° Test70 Test°

Interessant. Ich habe gerade
1
  printf("Test\0260 Test\260 Test\xb0\n");

mit dem GCC auf dem PC ausprobiert. Den Zeichencode für das ° habe ich
angepasst, damit er zu dem auf ISO 8859-15 eingestellten Ausgabefenster
passt. Man erkennt übrigens schon in der Einfärbung von \0260 durch die
Forensoftware, wie der Hase läuft.

Die Ausgabe sieht wie erwartet so aus:
1
Test0 Test° Test°

Die 0 nach dem ersten Test ist die letzte 0 in \0260, das Zeichen \026
ist nicht darstellbar und wird deswegen bei der Ausgabe unterdrückt.

von Sven W. (wache)


Lesenswert?

Moin!

Vielen Dank für Eure Hilfe!
Die Sache mit dem Backslash habe ich ganz vergessen gehabt, das war die 
Lösung!

Die richtige Zeile lautet alse:
1
float Winkel;
2
sprintf(Text, "Winkel: %5.1f\xF8", Winkel);

Die 0xF8 stehen für meine 248.

Warum mault eigentlich der Compiler mit der folgenden Aussage:
warning: format '5.1f' expects type 'double', but argument 3 has type 
'float'
Ich dachte immer, %f wäre für float!
Es funktioniert ja auch, aber mich interessiert die Warnung trotzdem...

@yalu: Ja, es ist ein (mehr oder besser mehr weniger) intelligentes 
Display. Es ist das eDIP240-7 (http://lcd-module.de/deu/dip/edip.htm). 
Das Datenblatt findest Du auch auf der Seite.
Prinzipiell ist das Display recht nett, aber es ist leider recht 
langsam.

Gruß,

Sven

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sven W. wrote:

> Warum mault eigentlich der Compiler mit der folgenden Aussage:
> warning: format '5.1f' expects type 'double', but argument 3 has type
> 'float'
> Ich dachte immer, %f wäre für float!

Nein, ist double.  float konnte man früher bei variablen Argumentlisten
auf Grund der argument promotion Regeln nicht transportieren.  Mit
modernen variablen Argumentlisten geht das allerdings, und du musst
explizit nach (double) casten.

> Es funktioniert ja auch

Zufällig, weil im AVR-GCC sizeof(float) == sizeof(double) ist.

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.