Bit maskieren und abfragen, ich sehe das Muster, aber ?

Also ist alles ab 0x80 der Start der Message.
Der Messagetype bestimmt sich dann anhand der folgenden Bits
Der Inhalt bestimmt sich dann aus den folgenden Bytes.
Können die folgenden Bytes >= 0x80 sein?
JA? -> Dann vergiss alles vorher gesagte
NEIN -> dann ist die erfolgreiche Prüfung auf >= 0x80 Dein Startbyte und Du verzweigst dann anhand der folgenden Bits.

Exakt, eine Sequenz beginnt immer mit einem Byte > 0x80, durch maskieren mit 63 wird der reine Befehlscode beginnend mit Null extrahiert und im entsprechenden case verarbeitet.
Bit 6 entscheidet ob zusätzlich zwei Datenbytes dran hängen.

Ich habe das Programm umgeschrieben,
Timeout eingebaut
Test der Datenbits auf 01xx xxxx
und while-Schleife bis alle Daten aus dem Puffer sind.

Gibt es eine elegante Möglichkeit den Empfangspuffer bei time out zu leeren, Daten könnten da ja trotzdem aufschlagen?

cu

Ähm, beim auslösen des Timeouts den buffer gleich 0 setzen. Oder denke ich da zu einfach. Bzw. Wird er bei neuen Empfang so oder so überschrieben, oder nicht?

Wie sieht denn dein Timeoutcode aus?

Moment.
Wenn das Timeout zuschlägt, ist der UART leer.
In dem Moment leerst Du den bytePuffer und setzt den Index auf 0 zurück.
Es ginge evtl. auch nur den index auf 0 zu setzen.


void display_einlesen()
{
  if (Serial.available() > 0)       // neue Daten vom Display?
  {
    myByte = Serial.read();
    if (myByte >= 0x80)
    {
      idx = 0;
      readStart = millis();
    }
    data[idx] = myByte;
    idx++;
  }
  if (idx >= 2 || millis() - readStart > timeout)
  {
    printData();
    memset(data, 0, sizeof(data));
    idx = 0;
  }
}

So oder so ähnlich.
Die Prüfung auf 63 oder 64 kannst Du dann ausserhalb machen.

Nein, habe getestet ...
Es kann ja ein Byte da sein, der Timeout schlägt dann auch zu, das zweite kommt kurz darauf.
Ist natürlich händisch simuliert.

Habe das mit einer while-schleife gelöst, die liest bis 0xFF kommt -> Puffer leer.

Im Moment geht allerdings gar nichts, mir ist gestern der Windowsrechner so was von total verreckt, habe stundenlang repariert.
Heute alles ok - Nextioneditor gestartet -> wieder totaler Crash.

cu

Das ist wurscht.
Wenn der Timeout kommt, muss alles danach verworfen werden.
Das ist Sinn und Zweck eines TimeOut.
Du kannst nicht sicherstellen, dass das danach kommende Byte das Folgebyte ist.

Mache ich doch, die while-schleife ...
Ein 0xFF kommt definitiv nicht vom Display, also ist der Puffer beim ersten leer.

if (timeout) {
        debm("timeout Datenempfang");
        byte muell;
        while (muell < 254) {                     // Empfangspuffer leeren
          muell = Serial.read();
        }

Läuft auch alles,
Time out funktioniert,
Datenbyteprüfung funktioniert
läuft in Schleife bis alle im Puffer liegenden Daten verarbeitet sind (zumindest wenn kein Bytefehler kommt).

Naja, wie geht auf Null setzen, das war ja die Frage ...

Überschrieben wird der Empfangspuffer nicht, das wäre tödlich ....
Was mit den Daten geschieht muss der Programmierer entscheiden, Serial holt rein und legt ab ....

cu

@hawe07546

je nach Inhalt von byte_befehl die Bedingung byte_befehl & 64 ergibt entweder 0 oder 64, dann:
if(0) ist dann logisches FALSE;
if(64) ist dann logisches TRUE (weil der Wert ist nicht null, d.h. auch -1 aus rechnerischem Sicht gibt logisches TRUE)

Ja, danke, hatte mir das so zusammen gereimt ....

cu

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.