Stromzähler auslesen

Ich habe mich jetzt auch mal dran gemacht meinen ISKRA M681 mit TTL-Lesekopf auzulesen. Das klappt auch ganz gut. Der Datensatz wird ca. alle 2s gesendet, und ich kann ihn im Monitor der IDE anzeigen.

Ich weiss aber noch nicht so recht wie ich meine Daten rauspicken soll.

Nach " 1 0 16 7 0 255" (Wirkleistung in W) kommt einige Stellen später der Wert "7 148" nach dem ich suche.

Momentan lese ich in einer Schleife mit Serial3.read() ein und sende mit Serial.print(inByte) an den Monitor.

1-0:1.8.0*255 Wirkenergie in Wh (total)
1-0:1.8.1*255 Wirkenergie Tarif 1 in Wh (total)
1-0:1.8.2*255 Wirkenergie Tarif 2 in Wh (total)
1-0:16.7.0*255 Wirkleistung in W
1-0:21.7.0*255 Wirkleistung L1 in W
1-0:41.7.0*255 Wirkleistung L2 in W
1-0:61.7.0*255 Wirkleistung L3 in W

Serial Pc bereit

27 27 27 27 1 1 1 1 118 5 25 181 15 134 98 0 98 0 114 99 1 1 118 1 1 5 8 145 175 214 9 8 5 53 52 45 111 43 40 1 1 99 254 146 0 118 5 25 181 15 135 98 0 98 0 114 99 7 1 119 1 9 8 5 53 52 45 111 43 40 7 1 0 98 10 255 255 114 98 1 101 17 8 98 75 122 119 7 129 129 199 130 3 255 1 1 1 1 4 73 83 75 1 119 7 1 0 0 0 9 255 1 1 1 1 9 8 5 53 52 45 111 43 40 1 119 7 1 0 1 8 0 255 101 0 0 1 130 1 98 30 82 255 89 0 0 0 0 11 181 116 140 1 119 7 1 0 1 8 1 255 1 1 98 30 82 255 89 0 0 0 0 11 181 116 140 1 119 7 1 0 1 8 2 255 1 1 98 30 82 255 89 0 0 0 0 0 0 0 0 1 119 7

1 0 16 7 0 255 1 1 98 27 82 0 85 0 0 7 148 1 119 7

1 0 36 7 0 255 1 1 98 27 82 0 85 255 255 255 245 1 119 7 1 0 56 7 0 255 1 1 98 27 82 0 85 0 0 7 142 1 119 7 1 0 76 7 0 255 1 1 98 27 82 0 85 0 0 0 17 1 119 7 129 129 199 130 5 255 1 1 1 1 131 2 65 39 55 95 102 100 166 95 76 177 222 126 141 127 39 89 103 56 166 171 132 70 248 48 113 228 64 54 90 129 121 115 149 63 215 226 65 92 118 203 189 4 169 151 94 165 125 118 1 1 1 99 46 255 0 118 5 25 181 15 136 98 0 98 0 114 99 2 1 113 1 99 75 195 0 0 0 27 27 27 27 26 2 112 145

Das Telegram beginnt immer "27 27 27 27 1 1 1 1"
Danach musst es nur noch zerlegen.

Hatten wir doch gerade vor nicht all zu langer Zeit...
@noiasca (?) und ich hatten das doch komplett zerlegt.

Mal sehen, ob der Thread noch gefunden wird.

ja @my_xy_projekt und @stoni99 schaut danach aus:

https://werner.rothschopf.net/microcontroller/202112_noiasca_smartmeter.htm

genau diese 0:16, 21, 41, 61 Pakete habe ich nicht drinnen, aber das sollte sich einfach in der Lib ergänzen lassen.

wärest Du bitte so nett und den hier ursprünglichen Thread verlinken, auf deren Basis das zerlegen begann.
Danke.

Discussion / Idea on the German Arduino Forum

@stoni99 schaffst du einen besseren dump von Daten?
In deiner Beschreibung sind da Bindestriche, Doppelpunkte, Punkte ... die vermisse ich bei deinem Muster.

1 Like

Achja, das war der, wo ich das teilen weggeschmissen hatte.
Schade. Der war eigentlich effektiv.
gr.
Na denne.

Die Bindestriche & Doppelpunkte scheinen keine Relevanz zu haben und werden vom ISKRA auch nicht gesendet.

Doch doch - Sonst weisst Du ja nicht, wann getrennt wird.
Seite 3 - erster Eintrag

Ich verstehe dich nicht.
Theoretisch muss ich die Rohdaten nach der Datenfolge 1 0 16 7 0 255 durchsuchen. 10 gesendete Zeichen später werden meine gesuchten Werte angegeben!?

Zeig bitte mal den Sketch wie du die obigen Daten ausgewertet hast.

Das Protokoll ist wahrscheinlich SML - das muss man systematisch parsen, nur nach einem Wert suchen ist nicht zuverlässig.

Ja. siehe oben und auch im anderen.... :wink:
Aber ich bin grad dabei das mal ganz anders zu bauen.
Mal sehen - las mir mal ne Minute :wink:

//const byte myzeichen[] = {27, 27, 27, 27, 1, 1, 1, 1, 118, 5, 25, 181, 15, 134, 98, 0, 98, 0, 114, 99, 1, 1, 118, 1, 1, 5, 8, 145, 175, 214, 9, 8, 5, 53, 52, 45, 111, 43, 40, 1, 1, 99, 254, 146, 0, 118, 5, 25, 181, 15, 135, 98, 0, 98, 0, 114, 99, 7, 1, 119, 1, 9, 8, 5, 53, 52, 45, 111, 43, 40, 7, 1, 0, 98, 10, 255, 255, 114, 98, 1, 101, 17, 8, 98, 75, 122, 119, 7, 129, 129, 199, 130, 3, 255, 1, 1, 1, 1, 4, 73, 83, 75, 1, 119, 7, 1, 0, 0, 0, 9, 255, 1, 1, 1, 1, 9, 8, 5, 53, 52, 45, 111, 43, 40, 1, 119, 7, 1, 0, 1, 8, 0, 255, 101, 0, 0, 1, 130, 1, 98, 30, 82, 255, 89, 0, 0, 0, 0, 11, 181, 116, 140, 1, 119, 7, 1, 0, 1, 8, 1, 255, 1, 1, 98, 30, 82, 255, 89, 0, 0, 0, 0, 11, 181, 116, 140, 1, 119, 7, 1, 0, 1, 8, 2, 255, 1, 1, 98, 30, 82, 255, 89, 0, 0, 0, 0, 0, 0, 0, 0, 1, 119, 7};
const byte myzeichen[] = {27 , 27 , 27 , 27 , 1 , 1 , 1 , 1 , 118 , 5 , 25 , 181 , 15 , 134 , 98 , 0 , 98 , 0 , 114 , 99 , 1 , 1 , 118 ,
                          1 , 1 , 5 , 8 , 145 , 175 , 214 , 9 , 8 , 5 , 53 , 52 , 45 , 111 , 43 , 40 , 1 , 1 , 99 , 254 , 146 , 0 , 118 , 5 , 25 ,
                          181 , 15 , 135 , 98 , 0 , 98 , 0 , 114 , 99 , 7 , 1 , 119 , 1 , 9 , 8 , 5 , 53 , 52 , 45 , 111 , 43 , 40 , 7 , 1 , 0 , 98,
                          10 , 255 , 255 , 114 , 98 , 1 , 101 , 17 , 8 , 98 , 75 , 122 , 119 , 7 , 129 , 129 , 199 , 130 , 3 , 255 , 1 , 1 , 1 , 1 ,
                          4 , 73 , 83 , 75 , 1 , 119 , 7 , 1 , 0 , 0 , 0 , 9 , 255 , 1 , 1 , 1 , 1 , 9 , 8 , 5 , 53 , 52 , 45 , 111 , 43 , 40 , 1 ,
                          119 , 7 , 1 , 0 , 1 , 8 , 0 , 255 , 101 , 0 , 0 , 1 , 130 , 1 , 98 , 30 , 82 , 255 , 89 , 0 , 0 , 0 , 0 , 11 , 181 , 116 ,
                          140 , 1 , 119 , 7 , 1 , 0 , 1 , 8 , 1 , 255 , 1 , 1 , 98 , 30 , 82 , 255 , 89 , 0 , 0 , 0 , 0 , 11 , 181 , 116 , 140 , 1 ,
                          119 , 7 , 1 , 0 , 1 , 8 , 2 , 255 , 1 , 1 , 98 , 30 , 82 , 255 , 89 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 119 , 7 , 1 , 0 ,
                          16 , 7 , 0 , 255 , 1 , 1 , 98 , 27 , 82 , 0 , 85 , 0 , 0 , 7 , 148 , 1 , 119 , 7 , 1 , 0 , 36 , 7 , 0 , 255 , 1 , 1 , 98 ,
                          27 , 82 , 0 , 85 , 255 , 255 , 255 , 245 , 1 , 119 , 7 , 1 , 0 , 56 , 7 , 0 , 255 , 1 , 1 , 98 , 27 , 82 , 0 , 85 , 0 , 0 ,
                          7 , 142 , 1 , 119 , 7 , 1 , 0 , 76 , 7 , 0 , 255 , 1 , 1 , 98 , 27 , 82 , 0 , 85 , 0 , 0 , 0 , 17 , 1 , 119 , 7 , 129 , 129 ,
                          199 , 130 , 5 , 255 , 1 , 1 , 1 , 1 , 131 , 2 , 65 , 39 , 55 , 95 , 102 , 100 , 166 , 95 , 76 , 177 , 222 , 126 , 141 , 127 ,
                          39 , 89 , 103 , 56 , 166 , 171 , 132 , 70 , 248 , 48 , 113 , 228 , 64 , 54 , 90 , 129 , 121 , 115 , 149 , 63 , 215 , 226 ,
                          65 , 92 , 118 , 203 , 189 , 4 , 169 , 151 , 94 , 165 , 125 , 118 , 1 , 1 , 1 , 99 , 46 , 255 , 0 , 118 , 5 , 25 , 181 , 15 ,
                          136 , 98 , 0 , 98 , 0 , 114 , 99 , 2 , 1 , 113 , 1 , 99 , 75 , 195 , 0 , 0 , 0 , 27 , 27 , 27 , 27 , 26 , 2 , 112 , 145
                         };
const byte startsequenz[] = {1, 0, 16, 7, 0, 255};
byte mystart[sizeof(startsequenz)] = {'\0'};
bool startOk = false;
unsigned int startpos = 0;
int pos = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (uint16_t i = 0; i < sizeof(myzeichen) - 1; i++)
  {
    Serial.print(F("gelesenes Zeichen: "));
    Serial.println((myzeichen[i]));
    if (startOk == false)
    {
      if (myzeichen[i] == startsequenz[0])
      {
        Serial.println(F("Startzeichen erkannt!"));
        startOk = true;
        startpos = i;
      }
    }
    else
    {
      if (i - startpos < sizeof(startsequenz) - 1)
      {
        Serial.println(F("suche Sequenzzeichen"));
        pos = 0;
        if (myzeichen[i] != startsequenz[i - startpos])
        {
          Serial.print(F("Zeichen "));
          Serial.print(i - startpos);
          Serial.println(F(" passt nicht - setze zurück"));
          startOk = false;
        }
        else
        {
          Serial.print(F(" Sequenzzeichen "));
          Serial.print(i + 1 - startpos);
          Serial.println(F(" erkannt!"));
        }
      }
      else
      {
        delay(1000);
        pos++;
        if (pos > 10)
        {
          Serial.print(F("Wert erkannt: "));
          Serial.println(myzeichen[i]);
        }
        if (pos > 11) return;
      }
    }
  }
}
void loop()
{
}

Mach was draus.

1 Like

Na, da staunt der Stoni!:open_mouth: Muss ich mir mal in Ruhe reinziehen. Danke!:hugs:

Das ich das noch geschafft habe... - Danke!

Dann mal hier noch mein Nachtrag:
Das oben von mir verlinkte offizielle Dokument hat Fehler.

Dort auf der von mir als Referenz bezogenen Seite heisst es:


Dazu ist in der Erläuterung bennant: ABCDE werden im deutschen Energiemarkt verwendet

@stoni99 sein ISKRA M681 verwendet - anders als in dem früheren Thread - nicht das EDIS-Format sondern das OBIS-Value. Ich bin beim drüber blättern in #8 noch davon ausgegangen, das da ein Trennzeichen reingehört - das ist aber ein Darstellungsfehler! (siehe meine roten !)

Damit entfällt jedes Trennzeichen und es wird auf die Sequenz in Gänze gesucht.
Das habe ich oben mit dem Sketch versucht - aber wohl ist mir dabei nicht.
Eigentlich müsste auf den Anfang des Telegramm geprüft und dann auf jeden Inhalt abgeglichen werden, um sicher zu stellen, das die "startsequenz" nicht (teilweise) auf einen Inhalt zurückgreift.

Widerrede?

Nö, von mir nicht. :wink:

SML enthält Längencodierungen, weil es variabel lange Datenfelder gibt. Das sicherste ist das systematische Parsen vom Anfang.

Ich hatte erst mal versucht mit einer diletantischen if Verschachtelung bestimmte Werte direkt beim Einlesen zu filtern. Hat leider nicht geklappt - warum eigentlich nicht?

void setup() {
  Serial.begin(115200);
  while(!Serial) {
    ; //wait of connect
  }
  Serial.println("Serial Pc bereit");

  Serial3.begin(9600);
  
}

void loop() {
  if (Serial3.available()){
    int inByte1 = Serial3.read();
    if (inByte1 == 119) {
      if (Serial3.available()){
        int inByte2 = Serial3.read();
        if (inByte2 == 7) {
          Serial.print(inByte1);
          Serial.print(" ");
          Serial.print(inByte2);
          Serial.print(" ");
          if (Serial3.available()){
            int inByte3 = Serial3.read();
            Serial.print(inByte3);
            Serial.print(" ");
          }
        }
      }
    }
   }
    //Serial.print(inByte);
    //Serial.print(" ");
 
}

Was passiert, wenn available() false ist? :wink:

1 Like

Stimmt, der wartet ja nicht an der Stelle bis es richtig ist.:man_facepalming: