ISKRA auslesen, Block kann nicht geleer werden

Nachdem das erste Projekt (ISKRA und Momentanwertauswertung - Nulleinspeisung) hänge ich nun am anderen Projekt. Um das auslesen des Gesamtwertes in ein anderes Projekt einbauen zu können, muss es erst mal richtig funktionieren.
Im folgenden Sketch wird ein Datenblock von 120 Byte eingelesen, anschließend mit der Suche nach dem Gesamtwert vortgesetzt. Sobald er gefunden ist, wird er errechnet und auf dem seriellen Monitor ausgegeben.

Nun soll eigentlich der Rest der eingelesenen Daten komplett gelöscht und ein neuer Block eingelesen werden. um einen aktuellen Wert zu filtern.
Allerding gibt es nur weitere Werte aus dem vorher gelesenen Block, bist dieser abgearbeitet ist. Erst dann wird gelöscht und neu eingelesen.
Leider finde ich den Fehler nicht, welcher wahrscheinlich einfach ist, aber mitlerweile habe ich Scheuklappen auf.

#include <Wire.h>
#include <SoftwareSerial.h>
#include <SPI.h>

SoftwareSerial mySerial(D3, D5);  // D3 RX, D5 nicht benutzt, da ISKRA M681 keinen IR Eingang zur Kommunikation der SML zulässt

constexpr uint16_t maxSize{ 200 };     // Speichergröße für einen Dump
byte myByte[maxSize] = { 0 };             // Speicherinhalt auf 0 setzen
uint16_t idx = 0;                                     // Index initialisieren
int wert19, wert20, wert21, wert22;  // Werte des Gesamtverbrauchs
int LED = D4;                        // Ausgang LED zur Anzeige Daten aus Zähler lesen
long lastValueFound = millis();      // Zeitwert zur Abschaltung der Heizung bei Verlust von Daten
unsigned long lastReadTime = 0;     // Zeitstempel für 10 Sekunden Abfrage

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600);
  pinMode(LED, OUTPUT);              // LED Ausgang setzen
}

void loop() {
  // Prüfen, ob Daten vorhanden sind und lesen dieser
  if (mySerial.available()) {
    digitalWrite(LED, HIGH);  // LED einschalten, wenn Daten empfangen werden
    myByte[idx] = mySerial.read();
    idx++;

    // Verhindere Überlauf des Indexes
    if (idx >= maxSize - 1) {
      idx = maxSize - 1;
    }
  } else {
    digitalWrite(LED, LOW);  // LED ausschalten, wenn keine Daten empfangen werden
  }

  // Verarbeite die Daten, wenn genug Bytes empfangen wurden
  if (idx > 140) {
    boolean valueFound = false;
    for (uint16_t i = 0; i < 140; i++) {
      // Suche nach der Byte-Reihe für den Gesamtwert
      if (((myByte[i]) == 119) && ((myByte[i + 1]) == 7) && ((myByte[i + 2]) == 1) && ((myByte[i + 3]) == 0) &&
          ((myByte[i + 4]) == 1) && ((myByte[i + 5]) == 8) && ((myByte[i + 6]) == 0) && ((myByte[i + 7]) == 255)) {
        valueFound = true;

        // Gesamtverbrauchswerte berechnen
        wert19 = myByte[i + 19]; wert20 = myByte[i + 20]; wert21 = myByte[i + 21]; wert22 = myByte[i + 22];

        long dezimalwert = (long(wert19) << 24) | (long(wert20) << 16) | (long(wert21) << 8) | long(wert22);
        float Bezug = (dezimalwert / 10000.0000);  // Gesamtleistung in kWh

        Serial.print("Bezug: "); Serial.println(Bezug, 4);
    
        // Speicher leeren und Index zurücksetzen
        clearBuffer();  idx = 0;  break;
      }
    }
    if (!valueFound) {
      clearBuffer();
      idx = 0;
    }
  }

  // Verhindere Überlaufen des Speichers durch regelmäßige Leerung
  if (millis() - lastReadTime > 10000) {  // Alle 10 Sekunden
    lastReadTime = millis();
    if (idx > 0) {
      clearBuffer();
      idx = 0;
    }
  }
}

// Funktion zum Leeren des Speichers
void clearBuffer() {
  for (uint16_t i = 0; i < maxSize; i++) {
    myByte[i] = 0;
  }
}

Ich hoffe, das jemand das Problem erkennt.Schon mal danke

weil Datenschutz ? oder glaubst du etwa die neu eingelesene Daten werden die alten nicht überschreiben können?

wie ich sehe brauchst du nur 23 Bytes. Wieso dann nicht nur die letzte 23 zu speichern?

eigentlich könnte man auch darauf verzichten und die 8 Bytes des Erkennungsverfahrens nur mitzählen, sobald alle 8 gezählt sind werden 12 folgende ignoriert und dann 4 weitere zusammen addiert.

#include <Wire.h>
#include <SoftwareSerial.h>
#include <SPI.h>

SoftwareSerial mySerial(D3, -1);  // D3 RX, D5 nicht benutzt, da ISKRA M681 keinen IR Eingang zur Kommunikation der SML zulässt

const uint32_t Abtatstrate = 10000;//ms
const byte LED = D4;                        // Ausgang LED zur Anzeige Daten aus Zähler lesen
const byte Chain[] = {0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xff};
void setup() {
  Serial.begin(115200);
  mySerial.begin(9600);
  pinMode(LED, OUTPUT);              // LED Ausgang setzen
}

void loop() {
  static uint32_t oldMillis = 0;

  if (millis() - oldMillis < Abtatstrate)while (mySerial.available() > 0)mySerial.read();
  else {
    digitalWrite(LED, HIGH);  // LED einschalten, wenn Daten empfangen werden
    delay(20);
    if (mySerial.available() > 22) {
      bool itsOK = true;
      for (byte i = 0; i < 8; i++) {
        byte CurrByte = mySerial.read();
        if (CurrByte != Chain[i]) {
          itsOK = false;
          i = 8;
        }
      }

      if (itsOK) {
        oldMillis += Abtatstrate;
        for (byte i = 0; i < 11; i++)mySerial.read();
        uint32_t dezimalwert = 0;
        for (byte i = 0; i < 4; i++) {
          dezimalwert = (dezimalwert << 8) | mySerial.read(); // es ist nicht klar ob die Daten wirklich decimal sind oder doch float
         
        }
        digitalWrite(LED, LOW);  // LED ausschalten, wenn keine Daten empfangen werden
        Serial.print("Bezug: "); Serial.println(dezimalwert); // mal sehen was es ausgibt
      }
    }
    else {
      digitalWrite(LED, LOW);  // LED ausschalten, wenn keine Daten empfangen werden
      delay(20);
    }
  }
}

Das ist mir schnuppe, ob überschreiben oder vorher löschen. Es soll funktionieren.

Ja, aber man muss sie erst mal finden in dem Block.

Das verstehe ich nicht. Leider ist es nicht einfach diese Daten zu finden und auszurechnen . Aber das ist ja auch garnicht das Problem. Das finden und rechnen funktioniert ja. Das Problem ist, wie beschrieben, das er nur den ersten Wert in dem kompletten Block finden, errechnen und ausgeben soll, dann den rest in diesem Block ignorieren und einen neuen Block einlesen (oder den alten Block überschreiben) um dann einen aktuellen Wert ausgeben soll

Der Sketch ist ein ganz anderer Ansatz, steig ich erst mal nicht durch, werde den Sketch aber mal testen, danke....

Der Sketch lässt sich nicht kompilieren, bricht mit der Fehlermeldung:"exit status 1
scalar object 'Chain' requires one element in initializer"

const byte Chain[8] = {0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xff};

ja, das habe ich korrigiert.

kann nicht sein, so steht nicht in deinem Code, besonders nach dem du Array mit '0' füllst.

Leider die nächste Fehlermeldung: " 'CurrByte' was not declared in this scope"

So war der Plan, ist aber nicht aufgegangen, deshalb habe ich hier die Anfrage gestartet.
Ich erhalte als Ausdruck jedesmal 2-4 gleiche Werte, dann eine kurze Pause und dann erst neue Werte.

Das ist aber was anderes als:

Ich werde Dir aber nicht weiterhelfen.
Selbst wenn ich es könnte.
Dieses Gefummel abseits der Gegegebenheiten ist eben nur ein Gefummel und damit Fehleranfällig und wird Dir immer wieder auf die Füße fallen.

z.B. dieses Konstrukt:

  if (idx > 140)
  {
    boolean valueFound = false;
    for (uint16_t i = 0; i < 140; i++)
    {
      // Suche nach der Byte-Reihe für den Gesamtwert
      if (((myByte[i]) == 119) && ((myByte[i + 1]) == 7) && ((myByte[i + 2]) == 1) && ((myByte[i + 3]) == 0) &&
          ((myByte[i + 4]) == 1) && ((myByte[i + 5]) == 8) && ((myByte[i + 6]) == 0) && ((myByte[i + 7]) == 255))
      {

was passiert, wenn idx 141 ist?

Warum sollte das 141 sein, so weit ich das verstanden habe, wird die Schleife bei 140 verlassen...

Was soll der Unterschied sein? Der Sketch ließt einen Block ein (200Bytes : constexpr uint16_t maxSize{ 200 };)
Dann fängt er an, in diesem Block nach dem passenden Code für den Gesamtverbrauch zu suchen. Hat er ihn gefunden, errechnet er den Wert und gibt ihn auf dem Monitor aus. Dann soll er eigentlich den Block löschen, oder auch überschreiben mit den nächsten 200Byte. Das macht er aber nicht, sondern sucht in dem alten Block weiter und gibt mir den nächsten gefundenen Wert aus. Erst wenn er alle 2-4 enthaltenen Werte gefunden hat, ließt er wieder einen neuen Block ein. Das ist der eigentliche Fehler.
Nun möchte ich wissen, warum nach der ersten Rechnung kein neuer Block eingelesen wird.
Wusste nicht, das das so ein Aufruhr erzeugt, tut mir leid, aber es ist nur eine Frage.

wie gesagt - das tut dieser Code nicht, trotz deiner festen Überzeugung. Kann es sein dass ISKRA M681 eine Weile die gleiche Daten sendet?

korrigiert

Lässt sich kompilieren und drauf spielen. Die LED flackert, wenn kein Signal reinkommt, leuchtet (jedenfallsaugenscheinlich) bei Signaleingang.
Der serielle Monitor zeigt leider garnichts

Ich habe beim meinem Sketch das i und das idx mit auf den Monitor genommen und nach der Ausgabe eine ein sekündige Pause eingefügt. Jetzt sieht die Ausgabe so aus:

"08:54:59.758 -> Bezug: 9468.5752 i: 93 idx: 141
08:55:01.741 -> Bezug: 9468.5762 i: 103 idx: 141
08:55:03.747 -> Bezug: 9468.5771 i: 115 idx: 141
08:55:05.704 -> Bezug: 0.0000 i: 127 idx: 141
08:55:08.758 -> Bezug: 9468.5801 i: 93 idx: 141
08:55:10.727 -> Bezug: 9468.5811 i: 105 idx: 141
08:55:12.747 -> Bezug: 9468.5820 i: 116 idx: 141
08:55:14.701 -> Bezug: 0.0000 i: 128 idx: 141
08:55:18.777 -> Bezug: 9468.5859 i: 93 idx: 141
08:55:20.747 -> Bezug: 9468.5869 i: 113 idx: 141
08:55:23.759 -> Bezug: 9468.5879 i: 89 idx: 141
08:55:25.716 -> Bezug: 9468.5889 i: 109 idx: 141
08:55:28.768 -> Bezug: 9468.5908 i: 93 idx: 141
08:55:30.733 -> Bezug: 9468.5918 i: 115 idx: 141
08:55:33.742 -> Bezug: 9468.5938 i: 91 idx: 141
08:55:35.764 -> Bezug: 9468.5947 i: 101 idx: 141
08:55:38.741 -> Bezug: 9468.5967 i: 93 idx: 141
"
so sieht das ganz passabel aus, aber wie kommt es zu der 000.0000 Ausgabe?

das kommt wenn gesuchte Sequenz zu nah am Ende ist so liest es außer gefüllten Bereich die Nullen die du beim Leeren reinschreibst.
und warst darüber gewarnt:

ich würde ehe fragen was würde passieren wenn i = 132 ? so wird es viel mehr offensichtlich.

die Lösung ist einfach, entweder:

if (idx > 199) {

oder

for (uint16_t i = 0; i < 140 - 23; i++) {

die Frage hat sich erübrigt, da in deinem Log alle Bezüge unterschiedlich sind.