Umlaute mit der Lib Max72xxPanel.h und Adafruit_GFX.h darstellen [gelöst]

FF kriegst du, wenn du ein read machst aber kein Zeichen da ist.

Wenn FC vorzeichenbehalftet in eine long Variable gepackt wird, hast du dort das Bitmuster FFFFFFFC.

Da du in #39 nicht zeigst, wie du die Ausgabe von 46313A4A616E2044FFFFFFFC72686F6C743B
erzeugst, soll das an Tipps reichen.

Brich das Problem auf kleine Einheiten runter:

mach einen vollständig kompilierbaren "Empfänger" Sketch mit deiner Funktion leseBahn()
mach einen vollständig kompillierbaren "Sender" Sketch mit dem du F1: Jan Dürholt überträgst.

Imho liegt es an deinem Sender, nicht an deinem Empfänger.

Hallo zusammen,
vielen Dank für die rege Teilnahme an meinem Problem. :kissing_heart:
@agmue
Die Klarheit bringt mir wieder Kopfschmerzen.... :smile:
Nun, nachdem die Codierung wohl ANSI ist verstehe ich nicht so recht warum Zahlen und Buchstaben bis auf Umlaute, Serial ausgegeben werden können.

@michael_x
Vielen Dank für Deine Info
wenn ich Dich richtig verstanden habe und die Daten in einem char einlese, und vor dem Umlaut noch andere Zeichen habe, erzeugt die Hex-Ausgabe dann Leerstellen.

Ich möchte nichts verheimlichen..... hier wie ich auf die HEX Ausgabe komme :wink:

void leseBahn()                                                                                          
{
  const uint32_t breakTimeRead = 70;       // Abbruchzeit in ms
  char readChar;                           // Einzelnes Zeichen
  static uint8_t x = 0;                    // Position im Array
  static char buf[charNum] = {0};          // Zwischenspeicher
  uint32_t lastmillis = millis();          // Startzeit merken...
  if (Datenherkunft == 2) {                // Datensatz kommen vom RennPC
    while (Serial3.available() > 0 && millis() - lastmillis < breakTimeRead)
    {
      readChar = Serial3.read();             // Einlesen
      Serial.print(readChar, HEX);
      if (readChar == ';')                   // Feldende? ...
      {
        Serial.println(" ");
        buf[x] = '\0';                       // ... CharArray abschliessen ...
        teileBuf(buf);                       // ... Übergeben zum teilen und senden ...
        x = 0;                               // ... Position im Array rücksetzen
      }
      else if (!isControl(readChar))         // Zeichen ist kein Steuerzeichen ...
      {
        buf[x] = readChar;                   // ... dann aufnehmen ...
        x++;                                 // ... neue Position setzen
      }
    }
  }

@noiasca
Auch Dir vielen Dank,
es sind eins Empfänger und Sender :wink:
Aber ich nenne es mal Steuergerät...
Es soll die Daten Serial vom RennPC aufnehmen und die Daten sortiert über CANBUS übertragen.
Teilnehmer sind zb. Matrix-Anzeige, Ampel oder auch Dunlopturm

Die Matrixanzeige ist diejenige die nun die Aufgabe hat, die Fahrernamen auszugeben.
Hatte bisher mit meinem Nano als Sender getestet....immer schön mit Serial.print(Fahrernamen)
Da hat auch alles funktioniert, aber bei dem Test mit dem RennPC die blöde Überraschung.
Racecontrol_CAN_BUS_KURZVERSION.ino (13.8 KB)
Teilnehmer_NANO_CanBus_V2.1.ino (40.1 KB)

Den Satz verstehe ich nicht, was geht da in Deinem Kopf vor?

Da hätte ich eine spekulative Idee: Serial.print(Fahrernamen) beim Test-Nano gibt UTF-8 aus, der RennPC aber ANSI. Damit hättest Du den RennPC falsch simuliert.

Könnte das sein?

Will sagen....warum die anderen Zeichen(bei ANSI) dann richtig angezeigt werden?

Das ist richtig, nun habe ich den Salat......aber Unwissenheit schützt vor Strafe nicht :wink: :smile:
Weiß nun nicht wie ich da rauskomme.... :weary:

Aus historischen Gründen stimmen die 7-Bit-Codes zwischen ANSI und UTF-8 überein.

  1. Daten vom RennPC nach UTF-8 umcodieren
  2. Alles auf ANSI umstellen

Was ist einfacher und schneller umzusetzen?

Na das ist die Erklärung.....Hatte gedacht das wären unterschiedliche Codierungen für Alle Zeichen.

Wenn 1. nicht so schwer ist, würde ich gern es so machen.
Dann könnte z.B. die Matrix so bleiben.....und wenn ich noch andere Geräte dazu mache, wäre es glaub ich einfacher. Oder wie siehst Du das?

Da steckt die amerikanisch-europäische Geschichte der Computerentwicklung drin. Asiatische Zeichen benötigen bis zu vier Bytes und sind damit Speicherfresser. Es gibt daher auch UTF-8-Codierungen, die asiatische Zeichen bevorzugen und auf asiatischen Computern Speicher sparen.

Nur mal so am Rande :slightly_smiling_face:

Sehe ich auch so, obwohl mir der Überblick über Dein Projekt fehlt. Aber wenn es mit dem Nano und UTF-8 schon funktioniert hat, dürfte das am schnellsten zu realisiern sein. Du kannst Dich ja zunächst auf die Umlaute und ß beschränken.

Das nenne ich mal ne mal eine Super Erklärung, Danke

Hast Du vielleicht einen Ansatz für mich? Ich wüsste jetzt garnicht wie damit anfangen soll.
Deine Hilfe letztens bei der Matrix mit Umlauten-Darstellung hat mich schon weggehauen.
Und wenn ich ehrlich bin .... auch nicht verstanden :woozy_face:

Eventuell eine Funktion ansi2utf8 mit switch/case?

dann wäre erst mal zu kontrollieren was der "RennPC" tatsächlich schickt.

Scheint mir nicht so einfach zu sein.... werde das erstmal zurückstellen.
Da bin ich ehrlich, das ist mir im Moment zu schwer.
Wenn ich daran weiter mache, werdet Ihr Bestimmt von mir hören da bin ich mir sicher.

@noiasca
ich hatte das mal vor vielen vielen Vollmonden.... eingelesen.

Hab ich mir gedacht :wink:

void setup() {
  Serial.begin(115200);
  char readChar = 0xFC;
  Serial.print(readChar, HEX);
}

Das gibt natürlich FFFFFFFC aus.

Nachtrag: nimm einfach
byte readChar = 0xFC;

Wäre halt schon toll gewesen, wenn man genau die Übertragung von F1:Jan Dürholt sehen hätte können.

Ich gehe wieder mal in den Hintergrund.

Hab Dir doch was verheimlicht....bin nicht schlau genug um zu wissen was ich da mache :wink:
Hab auch gerade ne Hirnblockade....weil mir das ganze gerade sehr sehr ärgert.

@noiasca

Hole ich nach, wenn ich nicht mehr mit dem Hammer draufhauen möchte.

Gehe mir jetzt mal den Magen Vollschlagen.....
Du bist nicht Du, wenn du hungrig bist. :joy:

Vorher nicht, das ist normal.
Ich verrate dir mal, dass ich (und vermutlich viele andere auch) in diese und ähnliche Fallen schon so oft reingetappt sind, dass man es im Lauf der Zeit schnell merkt, wenn man wieder drauf reingefallen ist. Im vorigen Beitrag könnte evtl. inzwischen eine Lösung sein.
( Auch int statt char würde helfen. )

Das steht doch in #41, oder?

"Natürlich" finde ich das nicht. Beim ESP32 mit 32 Bit Recheneinheit mag das -4 sein, bei einem UNO oder Mega2560 mit 8 Bit Recheneinheit erschließen sich mir die vielen FFs nicht. (Warum ein Zeichen vorzeichenbehaftet gespeichert wird, übrigens auch nicht, gehört aber nicht hierher.)

Was ist also die "natürliche" Erklärung?

@Benziner: Wenn Du die fehlenden UTF-8-Codes ergänzt, kannst Du die Funktion in Dein Programm integrieren.

Programm ANSI nach UTF-8
void ansi2utf8(byte c, char * arr, byte &pos)
{
  if (c < 128)
  {
    arr[pos] = c;
    pos++;
  } else {
    switch ( byte(c) )
    {
      case 0xE4: // ä
        arr[pos++] = 'a';
        arr[pos++] = 'a';
        break;
      case 0xF6: // ö
        arr[pos++] = 'o';
        arr[pos++] = 'o';
        break;
      case 0xFC: // ü
        arr[pos++] = 0xC3;
        arr[pos++] = 0xBC;
        break;
      case 0xC4: // Ä
        arr[pos++] = 'A';
        arr[pos++] = 'A';
        break;
      case 0xD6: // Ö
        arr[pos++] = 'O';
        arr[pos++] = 'O';
        break;
      case 0xDC: // Ü
        arr[pos++] = 'U';
        arr[pos++] = 'U';
        break;
      case 0xDF: // ß
        arr[pos++] = 0xC3;
        arr[pos++] = 0x9F;
        break;
      default:
        Serial.print(c, HEX);
        Serial.print('\t');
        Serial.print(pos);
        Serial.print('\n');
        arr[pos++] = '.';
    }
    arr[pos] = '\0';
  }
}

void setup (void)
{
  Serial.begin(9600);
  Serial.println("\nStart");
  byte txt[] = {'x', 0xE4, ' ', 0xF6, ' ', 0xFC, ' ', 0xC4, ' ', 0xD6, ' ', 0xDC, ' ', 0xDF, 'x'};
  char buf[30] = {0};
  byte x = 0;
  for (byte j = 0; j < sizeof(txt); j++)
  {
    ansi2utf8( txt[j], buf, x );
  }
  Serial.println(buf);
}

void loop(void) {}

Hallo Männer's und Männer:innen, :wink:
so der Frust hat sich langsam gelegt...haben gestern die Matrix an der Bahn installiert.
Läuft bis auf die Namens-Anzeige auch Perfekt...vielen vielen Dank an alle die dieses Projekt verwirklicht haben. Besonderen Dank an @my_xy_projekt und @agmue, die zwei haben mich nun mehr 3 Jahre an dem Projekt begleitet und immer wieder geholfen. :heart_eyes:

DANKE, OHNE EUCH WÄRE ES NICHT WIE ES HEUTE IST !!!

Da stimmt, und das schlimme daran....mit jedem happen erlerntes möchte man(n) mehr.

Sorry ich hätte es gern gemacht aber mein Bastelzimmer sah dermaßen Chaotisch aus....
eigentlich immer noch :joy:
Es waren 8 Bus Teilnehmer die quer durch den Raum verteilt waren und mit Klingelleitung verdrahtet waren....wie ein Spinnennetz sagte die Frau. (Hatte mir auch den einen oder anderen Teilnehmer vom Tisch,Schrank vom Fernseher gerissen weil ich mit dem Fuß hängen geblieben bin)
Auch Dir Danke für die angebotene Hilfe.

Nun mein lieber agmue, wieder einmal.....1000 Dank :heart_eyes:
nur wenn das so einfach wäre. Hatte es mir vorgestern mal kurz angesehen aber wegen dem Umbau bzw. Aufbau der Matrix an der Bahn zu wenig Zeit gehabt.

Hab so einiges leider nicht verstanden wie z.B. void setup (void) oder auch void loop(void) {}
was hat es sich mit dem void in Klammern auf sich? Hatte es mal kurz versucht zu integrieren...
aber da war IDE nur am meckern.....

Werd es gleich noch mal versuchen...mit der CAN Bus Kurzversion wenn ich Du mir vielleicht das mit dem Void erklärst.....???
Racecontrol_CAN_BUS_KURZVERSION.ino (13.9 KB)

In ewiger Dankbarkeit

1 Like

GOOOIIIL!

:star_struck: :star_struck: :star_struck:

"void" steht für Nichts, es geht auch void loop() {}. Es gibt keinen Rückgabewert (linkes void) und auch keine Parameter (rechtes void). Beispiel:

int a = 5;
byte b = foo (a);

Hier wird der Funktion foo der Inhalt von a übergeben, worauf sie einen Wert an die Variable b zurückgibt. Wenn man das typgerecht macht, sieht die Funktion so aus:

byte foo(int c) 
{
  byte d = c / 1000;
  return d;
}

OK?