Go Down

Topic: Smart Meter - SML HEX Code zerlegen (Read 2538 times) previous topic - next topic

slaven1337

Hallo zusammen,

ich habe mich bereits durch die bestehende Threads (z.B. Klick) zu dem Thema Smart Meter und SML (Smart Meter Language) gelesen, komme aber leider nicht weiter - ich verstehe nicht, wie ich mein Vorhaben in Arduino Code umsetzen kann.

Situation: ISKRA MT175 Smart Meter mit IR-Ausgang -> empfangen wird über Phototransistor und 10KOhm Pull-Up Widerstand - aktuell über ein UART (für Funktionstest).

Ich erhalte mit HTerm ohne Probleme vollständige SML-Telegramme, welche ich nach diesen Informationen auch manuell dekodieren kann.

Beispiel-Telegramm (private Daten habe ich mit XX unkenntlich gemacht - keine Ahnung, ob man damit etwas anfangen kann, sicher ist sicher  :) ):

Code: [Select]
1B 1B 1B 1B 01 01 01 01 76 05 08 20 66 B7 62 00 62 00 72 63 01 01 76 01 01 05 02 B5 77 93 0B 06 49 53 4B 01 0B CB 29 03 31 01 01 63 56 A4 00 76 05 08 20 66 B8 62 00 62 00 72 63 07 01 77 01 0B 06 49 53 4B 01 0B CB 29 03 31 07 01 00 62 0A FF FF 72 62 01 65 03 FD A3 C8 77 77 07 81 81 C7 82 03 FF 01 01 01 01 04 49 53 4B 01 77 07 01 00 00 00 09 FF 01 01 01 01 0B XX XX XX XX XX XX XX XX XX XX 01 77 07 01 00 01 08 00 FF 65 00 00 01 82 01 62 1E 52 FF 59 00 00 00 00 02 6E F4 91 01 77 07 01 00 01 08 01 FF 01 01 62 1E 52 FF 59 00 00 00 00 02 6E F4 91 01 77 07 01 00 01 08 02 FF 01 01 62 1E 52 FF 59 00 00 00 00 00 00 00 00 01 77 07 01 00 10 07 00 FF 01 01 62 1B 52 00 55 00 00 01 1B 01 77 07 81 81 C7 82 05 FF 01 01 01 01 83 02 95 CF 60 7F D4 67 98 8D 7A E2 FF 68 57 BE CE 44 D0 C9 3C 86 E9 97 D2 DF AE AA 27 BC 8A 42 E7 3A AA 1C 59 E0 74 B7 23 61 8B C8 44 B4 44 6D AF DF 01 01 01 63 F7 DD 00 76 05 08 20 66 B9 62 00 62 00 72 63 02 01 71 01 63 2A D1 00 1B 1B 1B 1B 1A 00 B6 90 1B 1B 1B 1B 01 01 01 01 76 05 08 20 66 BA 62 00 62 00 72 63 01 01 76 01 01 05 02 B5 77 94 0B 06 49 53 4B 01 0B CB 29 03 31 01 01 63 67 78 00 76 05 08 20 66 BB 62 00 62 00 72 63 07 01 77 01 0B 06 49 53 4B 01 0B CB 29 03 31 07 01 00 62 0A FF FF 72 62 01 65 03 FD A3 C9 77 77 07 81 81 C7 82 03 FF 01 01 01 01 04 49 53 4B 01 77 07 01 00 00 00 09 FF 01 01 01 01 0B 06 49 53 4B 01 0B CB 29 03 31 01 77 07 01 00 01 08 00 FF 65 00 00 01 82 01 62 1E 52 FF 59 00 00 00 00 02 6E F4 92 01 77 07 01 00 01 08 01 FF 01 01 62 1E 52 FF 59 00 00 00 00 02 6E F4 92 01 77 07 01 00 01 08 02 FF 01 01 62 1E 52 FF 59 00 00 00 00 00 00 00 00 01 77 07 01 00 10 07 00 FF 01 01 62 1B 52 00 55 00 00 01 1D 01 77 07 81 81 C7 82 05 FF 01 01 01 01 83 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 01 01 01 63 D7 12 00 76 05 08 20 66 BC 62 00 62 00 72 63 02 01 71 01 63 EE DA 00 1B 1B 1B 1B 1A 00 ED 43

Gestartet wird ein Telegramm immer mit "1B 1B 1B 1B 01 01 01 01", enden tut es immer auf "1B 1B 1B 1B 1A" + CRC-Bits.

Ich möchte genau zwei Werte aus dem Salat extrahieren:

1) Die aktuelle Wirkleistung:
Diese hat folgendes Format : 07 01 00 10 07 00 FF 01 01 62 1B 52 00 55 XX XX XX XX 01

Beginnt immer mit 07 01 00 10 07 00 FF 01 01 62 1B 52 00 55
dann kommt der Wert (z.B. wie oben): 00 00 01 1B: Ergibt Dezimal 238 (Watt)
dann wird immer mit "01" abgeschlossen

2) Den Gesamtverbrauch: Dieser hat folgendes Format : 07 01 00 01 08 00 FF 65 00 00 01 82 01 62 1E 52 FF 59 XX XX XX XX XX XX XX XX 01

Beginnt immer mit 07 01 00 01 08 00 FF 65 00 00 01 82 01 62 1E 52 FF 59
dann kommt der Wert (z.B. wie oben): 00 00 00 00 02 6E F4 91: Ergibt Dezimal 40826001 -> 4082,6001 kWH
dann wird immer mit "01" abgeschlossen

Theoretisch ist mein Ziel ganz einfach formuliert: Aus dem eingelesenen HEX-Telegramm sollen ein Integer (Wirkleistung) und ein Float (Gesamtverbrauch) werden.

Ich muss ja sicher irgendwie die fixen Startsequenzen nutzen, um das gesamte Telegramm zu durchsuchen und dann die darauf entsprechenden Stellen zu extrahieren. Aber wie macht man so etwas?

Vielen Dank im Voraus und schöne Pfingsten!  :)


PS: Realisiert werden soll alles letztendlich auf einem ESP8266 ESP-12E, welcher die beiden Werte per UDP oder MTTQ -da bin ich noch unschlüssig - an meinen Home Assistant Server sendet.

Doc_Arduino

Hallo,

entweder liest du alles in großes Array ein und ziehst dir dann die entsprechenden Werte von den entsprechenden Stellen raus und setzt den Endwert zusammen oder um Speicher zu sparen zählst du am Anfang mit und speicherst erst ins Array wenn die erste relevante Ziffernfolge für dich kommt und ziehst ab da alle anderen raus. Zur Einfachheit würde ich erstmal alles einlesen. Optimieren kann man später immer noch. 
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Rentner

Hallo,
Stehen die relevanten Werte denn innerhalb des telegramms immer an den selben Stellen
Dann kann man ja byteweise einlesen , zählen und ab der relevanten Position speichern .



 


postmaster-ino

Hi

So weit wäre ich gerne :o
Mit welchen Parametern hast Du HTerm gefüttert?
Ich hatte mittels der Photo-Diode eines CNY70 (Reflex-Lichtschranke) nur Müll empfangen, war allerdings auch 'nur' mit einem Arduino vor Ort (irgendwie war ich zu faul, das Oszi vor den Zählerschrank zu packen ... auf Laptop bin ich gar nicht gekommen :smiley-confuse: nutze Diese aber auch nur äußerst selten - bin meinem PC treu geblieben und dadurch wenig mobil ;) )

Selber würde ich, glaube, die Daten parsen - sofern zwischen den Einzelzeichen genügend Platz für Berechnungen sind.
Allerdings interessieren mich eher alle Daten, Die das Ding ausspuckt.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

slaven1337

Hi

So weit wäre ich gerne :o
Mit welchen Parametern hast Du HTerm gefüttert?
Ich hatte mittels der Photo-Diode eines CNY70 (Reflex-Lichtschranke) nur Müll empfangen, war allerdings auch 'nur' mit einem Arduino vor Ort

MfG
Hi, ich habe es - bisher - nur mit einem UART versucht. Hier war HTerm auf 9600/8/1/N gestellt. Der Transistor musste dafür nicht mal besonders genau ausgerichtet sein (kann ich aus einem vorherigen Test berichten, in dem ich den Phototransistor nur mit der Hand vorgehalten habe). Jetzt habe ich mir aus einem alten Milchkartondeckel bereits einen perfekt passenden Lesekopf gebaut :D


Zu den anderen Anmerkungen: Vielen Dank zu nächst einmal. Ich habe zumindest schon mal in die richtige Richtung gedacht. Leider habe ich gar keine Ahnung, wie ich anfangen soll. Hat jemand vll einen Code-Schnippsel, der mir zeigt, wie ich aus dem gesamten Telegramm mir die passenden Stellen extrahieren kann?

Bzw. noch einen Schritt davor: Wie ich mir das Array so zurecht schneiden kann, dass es immer genau den Inhalt eines Telegramms enthält? (D.h. keine Stücke von vor- oder nachgelagerten Telegrammen?)

Danke erneut! :)

Doc_Arduino

Hallo,

beschäftige dich bitte erstmal mit den seriellen Funktionen und den Bsp. der IDE, alles weitere baut darauf auf. Erstmal musst du alles einlesen können bevor es verarbeitet werden kann. Die Verarbeitung ist nachgelagert, nicht davor.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

noiasca

gem. deiner verlinkten Info hat die Message einen exakten Aufbau.
Freu dich über das verfügbare deutsche PDF. Scheint im drübersehen ein Type Length zu sein.
Also ich würde das SAUBERST parsen, und nicht an irgendwelchen Stellen rauskitzeln, den bei einem Update, könnte die Message innerhalb der Spec korrekt aber anders aufgebaut sein.
Lieber jetzt einmal durchbeisen und gem. Spec arbeiten.

Vom Vorgehen her vieleicht so:

alles ab
1B 1B 1B 1B 01 01 01 01

in einem Buffer einlesen und dann mit einer rekursiven Funktion den gewünschten Tag suchen gehen.

Wie weit bist du konkret, hast du die Message (MessageLength) schon im Speicher und gehts "nur" mehr ums zerteilen?




DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

slaven1337

Ich habe mich auf Basis dieses Sketches an die Arbeit gemacht.  (Ich weiß nicht, ob man das hier direkt posten darf?)

D.h. mein aktueller Stand ist: Der ESP8266 liest den IR-Code aktuell anständig in ein Byte-Array mit dem Namen datagram ein (ich hoffe das interpretiere ich richtig).

Der Autor des Sketches hatte das Ziel, das unbehandelten SML-Telegramm per UDP an einen Server im lokalen Netz zu schicken, um die Daten dann dort zu verarbeiten.

Ich würde das gerne so umbauen, dass ich meine beiden gewünschten Werte (Wirkleistung und Gesamtverbrauch) bereits extrahiert versenden kann. Die Kommunikations mit dem UDP-Ziel klappt auch einwandfrei (kommt alles an, sagt Wireshark).

Nur weiter weiß ich nun nicht - d.h. ich habe keine Ahnung, wie ich das Byte Array nun entsprechend zerlege und durchsuche (bin da leider nicht so fit) und ob der Autor des Sketches hier einen guten Weg gewählt hat. Für mich sieht das so aus, als würde erst einmal alles aufgefangen ohne auf die Start- und Stopsequenz zu achten?

Danke und Grüße!

Doc_Arduino

Hallo,

der Autor lässt den Anfang des Datenpaketes an Hand der Pausenzeit erkennen. Ist ein Weg von mehreren.
Wie gesagt, du solltest dich erstmal um das Verständnis der seriellen Funktionen kümmern. Meine Empfehlung.
Dann kannste testen ob du bestimmte Dinge schalten und walten kannst mit Buchstabeneingabe im seriellen Monitor.
Dann kannste dich entscheiden ob du die Pausenerkennung übernimmst oder die Anfangserkennung wählst.
Wenn das klar ist könnten wir weitermachen mit der Starterkennung vom Frame. Dann käme aus meiner Sicht switch case oder ein String Vergleich ins Spiel.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

slaven1337

#9
May 20, 2018, 07:36 am Last Edit: May 20, 2018, 07:48 am by slaven1337
Hallo,
danke für deine Antwort - mit deinem Tipp hast du auf jeden Fall Recht. Habe mich versucht dort etwas einzuarbeiten.

Ich habe letztendlich einen Sketch gefunden, den ich erweitern konnte. Hier wird nach Anfang und Ende der SML-Sequenz gesucht.

Hier mal mein aktueller Code - sicher nicht unbedingt das beste Coding, aber es kommt an Ende etwas raus und das ist schon einmal mehr, als vor 24 Stunden  :)

Code: [Select]
//Credit - This codes is based on the work of user "rollercontainer" at https://www.photovoltaikforum.com/volkszaehler-org-f131/sml-protokoll-hilfe-gesucht-sml-gt-esp8266-gt-mqtt-t112216-s10.html
//For SML protocol see http://www.schatenseite.de/2016/05/30/smart-message-language-stromzahler-auslesen/
//Hardware used: https://www.msxfaq.de/sonst/bastelbude/smartmeter_d0_sml.htm

byte inByte; //byte to store the serial buffer
byte smlMessage[1000]; //byte to store the parsed message
const byte startSequence[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01 }; //start sequence of SML protocol
const byte stopSequence[]  = { 0x1B, 0x1B, 0x1B, 0x1B, 0x1A }; //end sequence of SML protocol
const byte powerSequence[] = { 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55 }; //sequence preceeding the current "Wirkleistung" value (4 Bytes)
const byte consumptionSequence[] = { 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x00, 0x01, 0x82, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59 }; //sequence predeecing the current "Gesamtverbrauch" value (8 Bytes)
int smlIndex; //index counter within smlMessage array
int startIndex; //start index for start sequence search
int stopIndex; //start index for stop sequence search
int stage; //index to maneuver through cases
byte power[4]; //array that holds the extracted 4 byte "Wirkleistung" value
byte consumption[8]; //array that holds the extracted 8 byte "Gesamtverbrauch" value
int currentpower; //variable to hold translated "Wirkleistung" value
int currentconsumption; //variable to hold translated "Gesamtverbrauch" value
float currentconsumptionkWh; //variable to calulate actual "Gesamtverbrauch" in kWh


void setup() {
// bring up serial port
  Serial.begin(9600);
}

void loop() {
  switch (stage) {
    case 0:
      findStartSequence(); // look for start sequence
      break;
    case 1:
      findStopSequence(); // look for stop sequence
      break;
    case 2:
      findPowerSequence(); //look for power sequence and extract
      break;
    case 3:
      findConsumptionSequence(); //look for consumption sequence and exctract
      break;
    case 4:
      publishMessage(); // do something with the result
      break;   
  }
}


void findStartSequence() {
  while (Serial.available())
  {
    inByte = Serial.read(); //read serial buffer into array
    if (inByte == startSequence[startIndex]) //in case byte in array matches the start sequence at position 0,1,2...
    {
      smlMessage[startIndex] = inByte; //set smlMessage element at position 0,1,2 to inByte value
      startIndex++;
      if (startIndex == sizeof(startSequence)) //all start sequence values have been identified
      {
     //   Serial.println("Match found");
        stage = 1; //go to next case
        smlIndex = startIndex; //set start index to last position to avoid rerunning the first numbers in end sequence search
        startIndex = 0;
      }
    }
    else {
      startIndex = 0;
    }
  }
}



void findStopSequence() {
  while (Serial.available())
  {
    inByte = Serial.read();
    smlMessage[smlIndex] = inByte;
    smlIndex++;

    if (inByte == stopSequence[stopIndex])
    {
      stopIndex++;
      if (stopIndex == sizeof(stopSequence))
      {
        stage = 2;
        stopIndex = 0;
      }
    }
    else {
      stopIndex = 0;
    }
  }
}

void findPowerSequence() {
  byte temp; //temp variable to store loop search data
 startIndex = 0; //start at position 0 of exctracted SML message
 
for(int x = 0; x < sizeof(smlMessage); x++){ //for as long there are element in the exctracted SML message
    temp = smlMessage[x]; //set temp variable to 0,1,2 element in extracted SML message
    if (temp == powerSequence[startIndex]) //compare with power sequence
    {
      startIndex++;
      if (startIndex == sizeof(powerSequence)) //in complete sequence is found
      {
        for(int y = 0; y< 4; y++){ //read the next 4 bytes (the actual power value)
          power[y] = smlMessage[x+y+1]; //store into power array
        }
        stage = 3; // go to stage 3
        startIndex = 0;
      }
    }
    else {
      startIndex = 0;
    }
  }
   currentpower = (power[0] << 24 | power[1] << 16 | power[2] << 8 | power[3]); //merge 4 bytes into single variable to calculate power value
}


void findConsumptionSequence() {
  byte temp;
 
  startIndex = 0;
for(int x = 0; x < sizeof(smlMessage); x++){
    temp = smlMessage[x];
    if (temp == consumptionSequence[startIndex])
    {
      startIndex++;
      if (startIndex == sizeof(consumptionSequence))
      {
        for(int y = 0; y< 8; y++){
          //hier muss für die folgenden 8 Bytes hoch gezählt werden
          consumption[y] = smlMessage[x+y+1];
        }
        stage = 4;
        startIndex = 0;
      }
    }
    else {
      startIndex = 0;
    }
  }

   currentconsumption = (consumption[0] << 56 | consumption[1] << 48 | consumption[2] << 40 | consumption[32] | consumption[4] << 24 | consumption[5] << 16 | consumption[6] << 8 | consumption[7]); //combine and turn 8 bytes into one variable
   currentconsumptionkWh = currentconsumption/10000; // 10.000 impulses per kWh
}


void publishMessage() {
//Output count of extracted bytes
//Serial.print("Byte count: ");
//Serial.println(smlIndex);
//Serial.print('\n');
        //output 4 bytes of exctracted power bytes
//for(int x = 0; x < 4; x++){
//Serial.print(power[x],HEX);
//Serial.print(" ");
//}
      //output calculated "Wirkleistung"
Serial.print("Leistung: ");
Serial.println(currentpower);
//Serial.print('\n');
      //output 8 bytes of exctracted consumption bytes
//for(int x = 0; x < 8; x++){
//Serial.print(consumption[x],HEX);
//Serial.print(" ");
 // }
      //output calculated "Gesamtverbrauch"
Serial.print("Gesamtverbrauch: ");
Serial.println(currentconsumptionkWh);

// clear the buffers
  memset(smlMessage, 0, sizeof(smlMessage));
  memset(power, 0, sizeof(power));
  memset(consumption, 0, sizeof(consumption));
//reset case
  smlIndex = 0;
  stage = 0; // start over
}



Damit ich nicht den ganzen Tag im Keller neben dem Zähler sitzen muss, habe ich das ganze getestet, in dem ich via UART und HTerm den vorher aufgezeichneten Byte Satz vom Zähler an den ESP8266 übermittelt habe. Aktuell werden nun die beiden gewünschten Werte in die serielle Konsole geschrieben.

Manchmal verschluckt er sich aber und ich weiß noch nicht genau warum - die Konsole friert dann einfach ein. Ich habe mal ein wenig mit der Häufigkeit der Übertragungen gespielt, daran scheint es aber nicht wirklich zu liegen.  :smiley-confuse:

Edit: Ich glaube, ich erkenne das Problem. Für den Fall, dass die serielle Übertragung unsauber ist und/oder die Endsequenz nicht gefunden werden kann, wird die smlMessage extrem groß und macht Probleme. Fehlt nur noch eine Lösung :)

noiasca

ergänze die 4 schritte um Debug Serial Print, damit du siehst wo er hängen bleibt.


Eventuell hilft es, wenn du in den stages 1 - 4 den
while (Serial.available())

noch mit einer Zeitbedingung versiehst (z.B. > 2sec) und in diesem Fall mit einem Fehler zurück in stage 0 aussteigst.
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

postmaster-ino

#11
May 20, 2018, 09:08 am Last Edit: May 20, 2018, 09:09 am by postmaster-ino
Hi

Hört sich doch schon ganz gut an (mein Zähler wäre im 1.ten Stock, also durchaus erreichbar).
In dem Sketch von github (Quelle) wird beim Einlesen überprüft, ob der Puffer schon voll ist - Das fehlt bei Dir - solange neue Daten vorhanden sind, werden Diese an den Puffer angehangen - egal, wie groß der Puffer ist - denke, Das führt bei Dir zu den beschriebenden Problemen.

Von dem Code gibt es eine zweite, wohl Vorversion.
In der oberen Version wird eine zusätzliche Dummy-Seriel-Schnittstelle benutzt (noch kA, warum), weiter sieht die Anfangs-Erkennung mit der Verknüpfung der Bytewerte durch && intuitiv sinniger aus, als mit || in der wohl früheren Version.

... dann werde ich Mal einem Nano neues Leben einhauchen und mich vor den Zähler stellen ;) ...

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

agmue

... wird die smlMessage extrem groß ...
Code: [Select]
byte smlMessage[1000]; //byte to store the parsed message
...
      smlMessage[startIndex] = inByte; //set smlMessage element at position 0,1,2 to inByte value
      startIndex++;

Das Feld ist auf 1000 Elemente begrenzt, der Index startIndex wird aber nirgendwo auf kleiner 1000 begrenzt. Wenn die Startsequenz nicht gefunden wird, überschreibt smlMessage[startIndex] unkontrolliert den Speicher.

Versuche mal als Begenzung:

Code: [Select]
startIndex =  (startIndex +1) %1000;

Besser wäre es vermutlich, einen Ringpuffer zu implementieren.

... wird beim Einlesen überprüft, ob der Puffer schon voll ist - Das fehlt bei Dir - ...
Ok, nur Zweiter.
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

slaven1337

#13
May 20, 2018, 12:34 pm Last Edit: May 20, 2018, 12:36 pm by slaven1337
Quote
Versuche mal als Begenzung:

Code: [Select]
startIndex =  (startIndex +1) %1000;
Danke für den Tipp - habe ich gemacht (für alle Funktionen), glaube aber, der Wurm ist noch wo anders drin...

Quote
In dem Sketch von github (Quelle) wird beim Einlesen überprüft, ob der Puffer schon voll ist - Das fehlt bei Dir - solange neue Daten vorhanden sind, werden Diese an den Puffer angehangen - egal, wie groß der Puffer ist - denke, Das führt bei Dir zu den beschriebenden Problemen.
Danke, das GitHub Skript habe ich bei meiner Recherche gar nicht gefunden.

Quote
.. dann werde ich Mal einem Nano neues Leben einhauchen und mich vor den Zähler stellen ;) ...
Gibt doch nichts schöneres an einem Sonntag, an dem man Montag noch Zeit zur Fehlersuche hat :D

Kleiner Tipp bzgl. des Lesekopfes: Hier ist tatsächlich sehr präzise Ausrichtung des Transistors angesagt, mit minimalen Abstand. Bin eben ein wenig verzweifelt, als keine Werte vom Zähler kamen, nachdem ein blanker Fototransistor direkt dran gehalten aber funktionierte, habe ich noch meinen Milchtütendeckel-IR-Sensor angepasst. Nun purzeln die Werte rein.

Mittlerweile habe ich mich auch daran erinnert, dass ich noch ein altes Android Smartphone mit USB OTG-Funktion besitze. Dank praktischer Consolen App, kann ich nun den Laptop im Büro lassen und nehme nur das Handy mit in den Keller :) . (Arbeitsoptimierung auf einem Sonntag  :o)


Zu dem oben genannten Problem:

Quote
ergänze die 4 schritte um Debug Serial Print, damit du siehst wo er hängen bleibt.
Super Tipp! Hat mich schon mal auf meine Funktion aufmerksam gemacht, die den Gesamtverbrauch identifizieren soll.

Code: [Select]
void findConsumptionSequence() {
  byte temp;
 
  startIndex = 0;
for(int x = 0; x < sizeof(smlMessage); x++){
    temp = smlMessage[x];
    if (temp == consumptionSequence[startIndex])
    {
      startIndex =  (startIndex +1) %1000;
      if (startIndex == sizeof(consumptionSequence))
      {
        for(int y = 0; y< 8; y++){
          //hier muss für die folgenden 8 Bytes hoch gezählt werden
          consumption[y] = smlMessage[x+y+1];
        }
        stage = 4;
        startIndex = 0;
      }
    }
    else {
      startIndex = 0;
    }
  }

   currentconsumption = (consumption[0] << 56 | consumption[1] << 48 | consumption[2] << 40 | consumption[32] | consumption[4] << 24 | consumption[5] << 16 | consumption[6] << 8 | consumption[7]); //combine and turn 8 bytes into one variable
   currentconsumptionkWh = currentconsumption/10000; // 10.000 impulses per kWh
}


Diese fängt manchmal an zu hägen und scheint dann in einer Endlosschleife zu laufen, bis der ESP8266 abstürzt oder man vorher manuell via Button resettet.




noiasca

finde das construct sowieso eigenartig,
warum nicht einfach mit

strstr(string, needle)

nach der needle im im string suchen und dann (wenn noch genügend bytes vorhanden sind) die consumption auslesen?

DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

Go Up