Go Down

Topic: Wemos D1 Mini und LCD 1602(A) Umlaute (Read 475 times) previous topic - next topic

derseb

#15
Mar 17, 2020, 01:37 pm Last Edit: Mar 17, 2020, 01:45 pm by derseb
Die Umlaute sind nunmal nicht teil des einfachen ASCII Zeichensatzes und liegen im Code ROM des Displays weiter hinten
Das kann man doch direkt in einen String einfügen:
Code: [Select]

lcd.print("R\xE4ume");

Wo ist da das Problem?

Das einzige wo du aufpassen musst ist wenn das Zeichen direkt nach dem Hex-Byte auch als Hex-Ziffer interpretiert werden kann (z.B. 'a' bis 'f'). Da versucht der Compiler das auch als Teil der Hex-Zahl zu Parsen. Dann kann man aber das machen:
Code: [Select]

lcd.print("R\xE4""ume");


Ja

Code: [Select]
lcd.print("R\xE1""ume");

funktioniert. Aber wenn ich einen String habe bekomme ich das nicht ersetzt. Habe folgendes versucht:

Code: [Select]
String str = "Ein sehr langer String welcher ersetzt werden soll mit verschiedenen äää";
str.replace("ä", "\xE1");


Komischerweise im kleinen Sketch funktioniert es. Aber im großen nicht.

Serenifly

Gebe dir mal einzelnen Zeichen des Strings als Hex-Codes aus. Dann siehst du genau was da drin steht und musst dich nicht auf Interpretationen des Compilers verlassen

derseb

Gebe dir mal einzelnen Zeichen des Strings als Hex-Codes aus. Dann siehst du genau was da drin steht und musst dich nicht auf Interpretationen des Compilers verlassen
Bekomm ich auch grad nicht hin.

Habe aber eine Möglichkeit gefunden. Ich schicke einfach die Umlaute codiert via MQTT mit. Jetzt habe ich nur das Problem mit den hex geschichtet mit "0123456789abcdef" nach einem Umlaut.

 Hast du eine Idee?

Der MQTT Payload beinhaltet dann "L\xE1t's Play" was wunderbar funktioniert. Aber "L\xE1at's Play" geht nicht.

michael_x

Quote
Aber "L\xE1at's Play" geht nicht.
Das liegt an dem "a"
0xE1a ist leider eine gültige Hex-Zahl, aber nicht die von dir gewünschte.

Hex E1 ist Oktal 341. "L\341at's Play" wäre also die einfachste Lösung

 

noiasca

#19
Mar 17, 2020, 07:36 pm Last Edit: Mar 19, 2020, 11:23 am by noiasca
will das vieleicht wer mit einem I2C LCD ausprobieren?

Die Klasse hat ein neues
private uint8_t special;

wird gesetzt wenn die write Methode ein 0xC3 bekommt,
dann wird das nächste Zeichen umgeschrieben auf einen Umlaut (und das special wieder zurückgesetzt.

aktuell nur die kleinen Umlaute und das ß

Soweit die Theorie. Ich kanns aber momentan nicht testen.

how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

noiasca

#20
Mar 19, 2020, 11:22 am Last Edit: Apr 02, 2020, 03:02 pm by noiasca
auch wenns scheinbar niemanden interessiert, hier nun die Bestätigung.

Es läuft auf Displays mit dem A00 Zeichensatz. Das sind jene, die im oberen Bereich japanische Zeichen ausgeben. Es gibt nur kleine Umlaute im ROM, große Umlaute werden somit auch durch kleine ersetzt.

Dann noch ein paar Sonderzeichen wie Micro, Grad, Division und Summe.

Ich lade mal die unaufbereitete Version hier hoch, evtl. baue ich es in einer anderen Lib ein. Weis aber noch nicht in welche.



So schaut das write nun aus:
Code: [Select]

inline size_t LiquidCrystal_I2C::write(uint8_t value) {
  //Serial.println(value, HEX);
  if (special == 0xC3)
  {
    special = 0;
    switch (value)
    {
      case 0x84 :    // Ä
      case 0xA4 :
        send(0xE1, Rs); // gibt ein ä aus
        break;
      case 0x96 :    // Ö
      case 0xB6 :
        send(0xEF, Rs); // gibt ein ö aus
        break;
      case 0x9C :    // Ü
      case 0xBC :
        send(0xF5, Rs); // gibt ein ü aus
        break;
      case 0x9F :
        send(0xE2, Rs); // gibt ein ß aus
        break;

      case 0xB7 :
        send(0xFD, Rs); // DIVISION SIGN
        break;
      default :
        //Serial.print("D40 default 0x"); Serial.println(value, HEX);
        write(value);
    }
  }
  else if (special == 0xC2)
  {
    //Serial.print("D37 "); Serial.println(value, HEX);
    special = 0;
    switch (value)
    {
      case 0xB0 :
        write(0xDF); // DEGREE SIGN
        break;
      case 0xB5 :
        write(0xE4); //MICRO SIGN
        break;
      case 0xB7 :
        write(0xEF); // MIDDLE DOT
        break;
      default :
        //Serial.print("default 0x"); Serial.println(value, HEX);
        send(value, Rs);
    }
  }
  else if (special == 0xE2)
  {
    //Serial.print("D64 "); Serial.println(value, HEX);
    special = 0;
    switch (value)
    {
      case 0x88 :
        send(0xF6, Rs); // SUMMATION
        break;
      default :
        //Serial.print("default 0x"); Serial.println(value, HEX);
        send(value, Rs);
    }
  }
  else if (value == 0xC2 || value == 0xC3 || value == 0xE2)
  {
    special = value;
  }
  else
  {
    send(value, Rs);  // "normales" Zeichen
  }
  return 1;
}


sind noch eine Menge auskommentierte Debug-Ausgaben drinnen, aber läuft bisher fehlerfrei.

Wenn ich das jetzt alles richtig im Kopf habe, zum Nachlesen:
Sonderzeichen kommen als UTF-8, daher kommt bei einigen Sonderzeichen vorher ein Kontroll-Byte (C2, C3, ...). Ich frage daher im .write auf diese Sonderzeichen ab, setze entsprechend ein Flag (special) um dann im nächsten .write zu wissen, das ein Sonderzeichen vorausgegangen ist. Über die Switch/Case wird dann das UTF Zeichen auf den LCD-Zeichensatz umgeschlüsselt.  Nerven kostet die Überschneidung vom ß und dem Summenzeichen, aber es klappt auch.

Wie erwähnt, ich habe hier nur ein Display mit dem A00 Zeichensatz. Im A01 Zeichensatz gibt es mehr europäische Sonderzeichen (und auch kyrillische Zeichen). Wenn man ein Display mit A01 Zeichensatz hat, muss man halt die auszugebenden Zeichen anpassen. Z.B. wäre das ä dann 0xE4.
Vorgangsweise sollte nun klar sein.

Edit: Anlage gelöscht. Download der Lib von meiner Homepage (da wird es auch gewartet).
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

uwefed

Der Zeichensatz des Displays entspricht nur teilweise dem Ashii Zeichensatz. Dazu haben die Displays eins von 2 Zeichensätze.


Hier ein guter Artikel:
http://www.martyncurrey.com/arduino-with-hd44780-based-lcds/
Die Displays haben die Möglichkeit 8 Zeichen zu definieren.
Schau mal ob in der Bibliothek ein Beispiel dafür mitgeliefert wird.
Grüße Uwe

noiasca

#22
Mar 20, 2020, 11:05 am Last Edit: Mar 27, 2020, 09:00 pm by noiasca
Uwe danke für den Lesetipp. Special Char sind mir ein Begriff. Aber ich nehme lieber das was im ROM ist, dann bleiben die special chars weiterhin zur Verfügung und außerdem sind ja viele andere interessante Zeichen auch da.

Ich bin mit meiner Doku noch etwas hinten, aber hier mal ein Preview wenn es dich interessiert, was mich so bewegt hat: https://werner.rothschopf.net/202003_arduino_liquid_crystal_umlaute.htm

how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

Go Up