Wemos D1 Mini und LCD 1602(A) Umlaute

Das habe ich Dir doch geschrieben. Jedes Zeichen was rein kommt anschauen, ob es ein Umlaut ist. Wenn ja, das entsprechende Ersatzzeichen rein schreiben.

Gruß Tommy

Tommy56: Das habe ich Dir doch geschrieben. Jedes Zeichen was rein kommt anschauen, ob es ein Umlaut ist. Wenn ja, das entsprechende Ersatzzeichen rein schreiben.

Gruß Tommy

Ja genau das ist mein Problem. Wie muss die funktion aussehen? Den String in ein char array und dann in einer schleife durchgehen?

Ich hab einfach keine Idee Wie.

Das wäre ein Weg. Ansonsten wie liest Du die Daten von MQTT ein? Wahrscheinlich auch zeichenweise. Da könntest Du das gleich an der Stelle machen.

Gruß Tommy

Tommy56: Das wäre ein Weg. Ansonsten wie liest Du die Daten von MQTT ein? Wahrscheinlich auch zeichenweise. Da könntest Du das gleich an der Stelle machen.

Gruß Tommy

Hast du ein Beispiel?

Ich bekomm es ehrlich gesagt nicht hin.

wenn man sich drüberdraut könnte man auch die Lib patchen und in der write Methode im Anlassfall auf das Sonderzeichen gehen. Print wird sowieso schon vereinzelt.

Nur wundert mich, dass das noch niemand gemacht hätte. Gegoogelt nach einer eingedeutschten Lib hast schon?

noiasca: wenn man sich drüberdraut könnte man auch die Lib patchen und in der write Methode im Anlassfall auf das Sonderzeichen gehen. Print wird sowieso schon vereinzelt.

Nur wundert mich, dass das noch niemand gemacht hätte. Gegoogelt nach einer eingedeutschten Lib hast schon?

Nein habe ich noch nicht. War am Anfang froh das das Display überhaupt läuft :D Aber vielen dank für den Tip!

Ich raff es einfach nicht. Mit lcd.print und gewissen Codes geht es ja. Ich bekomm es einfach nur nicht hin das dementsprechend zu printen da ich ja eine String Variable habe. Eingedeutschte Libs gibt es zumindest bei PlatformIO nicht. Russisch könnte ich anbieten :D

a) mit welcher i2c Lib arbeitest du (GANZ GENAU angeben, sodass ich die auch finde)

b) mach mal einen Minimalen Sketch der nur folgendes Ausgibt:

Zeile 0 a A o Ö u U s

Zeile 1 ä Ä ö Ö ü Ü ß

poste den hier in Code-Tags

(hab aktuell keinen Zugriff auf ein LCD, daher musst du fleißig mitarbeiten).

a)

b)

//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Arduino.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("a A o O u U s");
  lcd.setCursor(0,1);
  lcd.print("ä Ä ö Ö ü Ü ß");
}


void loop()
{
}

IMG_20200317_130207.jpg

Nö schon so dass man die Umlaute sieht!!!

noiasca:
Nö schon so dass man die Umlaute sieht!!!

Ja man sieht was. Aber nicht wie die Umlaute eigentlich aussehen sollten. Versteh die aussage nicht sorry!

Die Umlaute sind nunmal nicht teil des einfachen ASCII Zeichensatzes und liegen im Code ROM des Displays weiter hinten

Nun gibt es ja einmal die möglichkeit die Hex? “Codes” für Umlaute zu nutzen zB.

Das kann man doch direkt in einen String einfügen:

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:

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

Serenifly:
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:

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:

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

Ja

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

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

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.

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

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

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.

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

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.

20200319_105729m.jpg|1024x497

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:

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).

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

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

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