Umlautausgabe LCD-Display

Hallo,
Ich stehe vor dem Problem Umlaute (ä,ö,ü,Ä,Ö,Ü) auf einem LCD Dispaly auszugeben.
Das wandeln von z.B. ä in \xE1 ist klar. Ebenso die Ausgabe, wenn es sich um einen festen Text handelt.

Es sind aber variable Texte die von einem Smartphone via Bluetooth HC-06 übertragen werden.
Muss also den empfangenen String, wird als "Data" abgelegt nach den Sonderzeichen durchsuchen.

Data wird im Laufe des Programms in 2 Strings (Data1, Data2) geteilt, weil das LCD-Display 1x16 wegen der internen Organisation in 2x 1x8 angesprochen werden muss.

Volker

zunächst musst du rausfinden, ob dein LCD überhaupt einen Zeichensatz hat, wo es diese Zeichen gibt.
Mit sehr großer Wahrscheinlichkeit hast du ein LCD das es nicht nativ kann.
Alternativ könntest du dir diese Zeichen als Sonderzeichen definieren. In der Regel sind max 8 Sonderzeichen möglich.
Und dann eine Routine schreiben, die jeden Text der reinkommt auf Umlaute durchsucht und entsprechend gegen Sonderzeichen austauscht.

Wenn du dann einen funktionierenden Prototypen hast, könntest du eine LCD-Lib adaptieren.

Machbar, aber imho not worth the money...

edit:

dennoch habe ich mich mal hingesetzt und einer LCD Library inkl. deutscher Umlaute erstellt

Hi,

schau Dir mal das Teil hier an, fast selbsterklärend:

Gruß André

Hallo,
LCD-Charakter-Creator ist bekannt und auch für große Umlaute wohl unumgänglich.
Die Ersatzcodes für ä, ö und ü ebenso.
Mir geht es um eine Routine, die jeden Text der reinkommt auf Umlaute durchsucht und entsprechend gegen Sonderzeichen austauscht.
Volker

volkerS:
Muss also den empfangenen String, wird als "Data" abgelegt nach den Sonderzeichen durchsuchen.

Wenn Du die empfangenen Zeichenketten tatsächlich in String-Strings speicherst: Guck mal hier.

Ich würde aber erst mal versuchen, die Zeichen schon in der Empfangsroutine zu ersetzen. Vermutlich wirst Du die empfangenen Zeichen schon dort so händeln müssen, dass sich ein Ersetz-switch() einbauen lässt.

Zeig' vielleicht mal den Sketch.

Gruß

Gregor

Hallo Volker,
ist schon länger her, aber da habe ich das mal für die LCD-Anzeige eines RDS-Radios gemacht ( mit char-strings). Eigentlich ist es ganz einfach: Ein Array mit den Zeichen die umgesetzt werden müssen, ein Array mit den Zielzeichen und 2 geschachtelte for-Schleifen:

Auszug aus dem damaligen Sketch:

// Tabellen für Umsetzung von Sonderzeichen
//                       ß          ä          ö          ü         Ä          Ö          Ü          @          [           \          ]         {          \          }
char rdsSon[] = {(char)0x8c,(char)0x91,(char)0x97,(char)0x99,(char)0xd1,(char)0xd7,(char)0xd9,(char)0x40,(char)0x5b,(char)0x5c,(char)0x5d,(char)0x7b,(char)0x7c,(char)0x7d }; // RDS-Codierung
char lcdSon[] = {(char)0xbe,(char)0x7b,(char)0x7c,(char)0x7e,(char)0x5b,(char)0x5c,(char)0x5e,(char)0xa0,(char)0xfa,(char)0xfb,(char)0xfc,(char)0xfd,(char)0xfe,(char)0xff }; // KS0073 Zeichensatz 

..
...
            // Sonderzeichen umsetzen
            for ( scrollIx=0; scrollIx<strlen(rdsText); scrollIx++ ) {
                if ( (byte)rdsText[scrollIx] >= '@' ) {
                    for ( byte j=0; j<sizeof(rdsSon); j++ ) {
                        // gegebenenfalls umsetzen
                        if ( rdsText[scrollIx] == rdsSon[j] ) {
                            rdsText[scrollIx] = lcdSon[j];
                            break;
                        }
                    }
                }
            }

Ist aber natürlich nur für die 'klassischen' char-strings. Wenn Du die Klasse String verwendest, geht das so nicht.

variable Texte die von einem Smartphone

Da musst du erstmal wissen, wie die "Sonderzeichen" ankommen: ANSI, also CP-1252 8 bit, oder UTF-8 welches für nicht-ASCII Zeichen mindestens 2 byte verwendet, oder ...
Evtl. brauchst du neben "äöüßÄÖÜ" auch noch das neumodische '€'

noiasca:
Mit sehr großer Wahrscheinlichkeit hast du ein LCD das es nicht nativ kann.

Das hört sich nach einem HD44780 Display an. Natürlich können die das.

Hallo,
wie die Sonderzeichen ankommen muss ich prüfen. Ich weiß nur, dass die durch den HC-06 empfangenen Zeichen im seriellen Monitor korrekt dargestellt werden.
Beim Display handelt es sich lt. Aufdruck um ein 1601-1 Series (16x1 Character LCD Module) das diect mit einem I2C-Adapter geliefert wurde.
Hier das aktuelle Programm:

#include <Wire.h> // Wire Bibliothek einbinden
#include <LiquidCrystal_I2C.h> // Vorher hinzugefügte LiquidCrystal_I2C Bibliothek einbinden
LiquidCrystal_I2C lcd(0x27, 8, 2); //Display mit 16 Zeichen in 2 Blöcken und der HEX-Adresse 0x27.
#include <SPI.h>
#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(10, 9); // RX, TX

int LED = 13; // the on-board LED
int LED2 = 14; // Led extern
int Data; // the data received
const int SERIAL_BUFFER_SIZE = 8;
char serialBuffer[SERIAL_BUFFER_SIZE];

void setup()
{
Bluetooth.begin(9600);
Serial.begin(9600);
lcd.init();
lcd.backlight(); //Hintergrundbeleuchtung einschalten
lcd.begin(8,2);
pinMode(LED,OUTPUT);
pinMode(LED2,OUTPUT);

lcd.setCursor(0, 0);
lcd.print("by BKB");

delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pause");
}
void loop() {
String Data;
String Data1;
String Data2;
if (Bluetooth.available()){ //wait for data received
Data=Bluetooth.readString();
if (Data.startsWith( "+DISC:SUCCESS" ))
{
digitalWrite(LED,0);
digitalWrite(LED2,1);
}
else {
digitalWrite(LED,1);
digitalWrite(LED2,1);
Data1=Data.substring(0,8);
Data2=Data.substring(8,17);
lcd.clear();
lcd.print("");
delay(500);
lcd.setCursor(0,0);
lcd.print(Data1);
lcd.setCursor(0,1);
lcd.print(Data2);
Serial.println(Data);
}
}
delay(100);
}

"+DISC:SUCCESS" wird vom HC-06 ausgegeben wenn die Bluetooth-Verbindung zum Smartphone unterbrochen wird. Dies wird über die if-Routine unterbunden.Die Leds dienen als Connect-Anzeige.
Volker

Welches Diplay hast Du?
Ein Modul mit einem HD44780? Da die 00 oder 02 Option? oder einen kompatiblen?

Grüße Uwe

Das Display ist eigentlich egal. Das Problem ist dass die Sonderzeichen nicht Teil des einfachen ASCII Zeichensatzes sind. Der geht nur bis 127. Die Frage ist nicht was das Display macht, sondern wie man diese Zeichen seriell überträgt. Das kommt dann auf die Codierung an.

Einfach mal die empfangenen Zeichen als HEX anzeigen lassen. Dann sieht man schon was abläuft.

Es gibt auch eine erweiterte ASCII Tabelle mit Umlauten:

Wenn das so codieren kann, dann hat man einzelne Bytes die man einfach auf die Display Codierung umsetzen kann

Hallo,

der erweiterte Zeichensatz ist nicht standardisiert. Am besten einen Sketch schreiben der alle Zeichen (Serial.write) durchweg mit ASCII Nummer ausgibt. Dann sieht man schnell was geht und was nicht.

Hallo,
so wie es aussieht, verwendet die Arduino-IDE ( auch der serielle Monitor ) und der GCC durchgängig UTF8. Bei Verwendung von Sonderzeichen ist ein String also länger als es scheint.
Da die empfangenen Strings nach Aussage des TO im seriellen Monitor richtig dargestellt werden, gehe ich mal davon aus, dass sie im UTF8 Format empfangen werden.

P.S. Die deutschen Umlaute und das 'ß' sind im UTF8-Format alle 2 Byte lang und fangen alle mit '0xc3' an. Danach müsste man also im String suchen.

Edit: noch ein kleiner Sketch, der die Codierung zeigt:

char umlaute[] = {"öäüÖÄÜß"};
void setup() {
  // put your setup code here, to run once:
  char buf[30];
  Serial.begin(115200);
  Serial.println("Codierung der Umlaute");
  Serial.println("Zeichen öäüÖÄÜß als Hex:");
  for (byte i=0; i<sizeof(umlaute); i++ ) {
     sprintf(buf, " %2x", (byte)umlaute[i]);
     Serial.print(buf);
  }
  Serial.println();
  for ( byte i=0; i<sizeof(umlaute);i++) {
    Serial.write( umlaute[i] );
  }
  Serial.println();
}

void loop() {
  // put your main code here, to run repeatedly:
}

MicroBahner:
Die deutschen Umlaute ... sind im UTF8-Format alle 2 Byte lang und fangen alle mit '0xc3' an.

Diese Aussage ist nicht ganz richtig, da es für Umlaute grundsätzlich zwei Codierungen gibt, "ö" als Beispiel:

0xc3b6 das Zeichen an sich
0x6fcc88 Grundbuchstaben "o" mit Diarese als nicht vorrückendes Zeichen

Gerade im englischsprachigen Raum scheint mir die zweite Möglichkeit beliebt zu sein. Man muß daher überprüfen, was gesendet wird.

Quelle: UTF-8-Codetabelle mit Unicode-Zeichen

agmue:
"ö" als Beispiel:

0xc3b6 das Zeichen an sich
0x6fcc88 Grundbuchstaben "o" mit Diarese als nicht vorrückendes Zeichen

Das würde ich in dem Fall hier aber ausschließen, denn der serielle Monitor packt das nicht. Wenn ich deine Bytefolge an den ser. Monitor ausgebe, wird das 'o' und das '¨' nebeneinander ausgegeben. Auch wenn ich die 0x6f danach ausgebe, stehen die beiden Zeichen nebeneinander und es wird kein 'ö' daraus.

MicroBahner:
Das würde ich in dem Fall hier aber ausschließen, denn der serielle Monitor packt das nicht. Wenn ich deine Bytefolge an den ser. Monitor ausgebe, wird das 'o' und das '¨' nebeneinander ausgegeben. Auch wenn ich die 0x6f danach ausgebe, stehen die beiden Zeichen nebeneinander und es wird kein 'ö' daraus.

Naja, die Fähigkeiten des seriellen Monitors sind ohnehin sehr beschränkt. Der kann auch keine ANSI-Codes (wie „Clear Screen“ oder „Cursor Home“).

Gruß

Gregor

Das ist schon richtig. Der im Linux-Umfeld oft eingesetzte PuTTY kann es jedenfalls ( wenn man nicht gerade die falsche Schriftart benutzt.. ). Ich denke aber, dass der TO den 'standard' seriellen Monitor der Arduino IDE genutzt hat.

MicroBahner:
Das würde ich in dem Fall hier aber ausschließen, denn der serielle Monitor packt das nicht.

Ich habe Deine Aussage bewußt aus dem Zusammenhang gerissen betrachtet. Das hätte ich wohl deutlicher machen sollen.

Bezogen auf dieses Thema stimme ich Dir zu.

Hi

agmue:
0x6fcc88Grundbuchstaben "o" mit Diarese als nicht vorrückendes Zeichen

Erinnert schwer an längst vergangene Zeiten, wo man dem Nadeldrucker per Steuerzeichen (in diesem Fall BackSpace) dazu gebracht hatte, mehrere Zeichen auf die gleiche Stelle zu drucken.
(oder CR mit entsprechend vielen Leerzeichen oder im Grafik-Modus ... mei, Das ist echt lange her ... und ich vermisse die Geräusch-Kulisse)

Was eine scheene Welt ... Alles kommt zurück ... irgendwann :slight_smile:

MfG

noiasca:
edit:

dennoch habe ich mich mal hingesetzt und einer LCD Library inkl. deutscher Umlaute erstellt

Hallo ich bin neu hier und war bisher nur lesend hier im deutschen Forum unterwegs und wollte mich für deine Lib bedanken. :slight_smile:

Mein derzeitiges Projekt ist eine Rundtischsteuerung mit einem CL-Stepper (JMC Ihss57-36-10) für meine Fräsmaschine ...und nun funktioniert es auch mit den Umlauten.
Ebenso möchte ich mich bei MicroBahner für seine MoBaTols hier bedanken, da er hier auch schreibt :wink:

Grüße Burkhard