Hallo zusammen,
ich habe mit Hilfe von viel suchen und diesem Forum einen Arduino Code erstellt,
welche SML einließt und für die Aktuelle Power, sowie L1 - L3 die Werte sowohl positiv und negativ anzeigt.
Gestartet bin ich mit diesem Artikel und den Links darin:
Danke schon mal an alle die dort eine sehr gute Grundlage geliefert haben.
Mit dem Code aus post#9 von slaven1337 konnte ich schon viel auslesen und hab diesen als Grundlage genommen.
Ich habe den Code erweitert um Constanten für L1 - L3 die mein Zähler (EFR CGM4) nach Eingabe meiner Zähler Pin Codes ausgiebt:
const byte powerSequenceL1[] = { 0x07, 0x01, 0x00, 0x24, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00 }; //sequence preceeding the current Power of L1 in Watt; dynamic Value
const byte powerSequenceL2[] = { 0x07, 0x01, 0x00, 0x38, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00 }; //sequence preceeding the current Power of L2 in Watt; dynamic Value
const byte powerSequenceL3[] = { 0x07, 0x01, 0x00, 0x4C, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00 }; //sequence preceeding the current Power of L3 in Watt; dynamic Value
Mein Zähler liefert zudem die Werte nicht statisch (wie in anderen Artikeln manchmal zu lesen ist) aus, sondern je nach Größe/Länge dynamisch.
Nach der powerSequencekommt bei mir (in HEX) 0x52, 0x53, 0x54 usw. für die Länge des Wertes.
Danach wird der Wert ausgegeben.
Beispiel für 0x52:
0x52 0B 01
Hier ist die Länge erkennbar (0x52), dann der Wert 0x0B und das Ende 0x01.
Weiterhin hatte ich mit negativen Werten zu kämpfen. Im Laufe meiner Suche habe ich irgendwann gefunden/verstanden dass die Länge in 0x6X oder 0x5X ausgegeben werden kann.
Bei 0x5X enthält der Wert auch ein Vorzeichen welches bei der Ausgabe als HEX nicht erkennbar ist bzw. angezeigt wird.
Hier mein Code für L1 mit Erkennung der Wert-Länge und dem nutzen des Vorzeichens mittels z.B. int8_t:
void findPowerSequenceL1() {
byte powerL1[9];
byte powerValueLength = 0;
byte temp; //temp variable to store loop search data
byte startIndexL1 = 0;
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
/*************************************************************************************
*
* Read Power for Line 1
*
*************************************************************************************/
if (temp == powerSequenceL1[startIndexL1]) {
startIndexL1++;
if (startIndexL1 == sizeof(powerSequenceL1)) {
Serial.println(F("reading powerSequenceL1 ConsumptionValues: "));
for(int y = 0; y < 9; y++){ //read the next 9 bytes (the actual power value)
powerL1[y] = smlMessage[x+y+1]; //store into powerL1 array
}
powerValueLength = ( powerL1[0] - 81 );
Serial.print(F("powerValueLength is: "));
Serial.println(String(powerValueLength));
switch (powerValueLength) {
case 1:
currentPowerL1 = (int8_t)powerL1[1];
break;
case 2:
currentPowerL1 = ((int8_t)powerL1[1] << 8) | (int16_t)powerL1[2];
break;
case 3:
currentPowerL1 = ((int8_t)powerL1[1] << 16) | ((int16_t)powerL1[2] << 8) | (int32_t)powerL1[3];
break;
/*case 4:
currentPowerL1 = (powerL1[1] << 24 | powerL1[2] << 16 | powerL1[3] << 8 | powerL1[4]); break;
case 5:
currentPowerL1 = ((unsigned long long)powerL1[1] << 32 | powerL1[2] << 24 | powerL1[3] << 16 | powerL1[4] << 8 | powerL1[5]); break;
case 6:
currentPowerL1 = ((unsigned long long)powerL1[1] << 40 | (unsigned long long)powerL1[2] << 32 | powerL1[3] << 24 | powerL1[4] << 16 | powerL1[5] << 8 | powerL1[6]); break;
case 7:
currentPowerL1 = ((unsigned long long)powerL1[1] << 48 | (unsigned long long)powerL1[2] << 40 | (unsigned long long)powerL1[3] << 32 | powerL1[4] << 24 | powerL1[5] << 16 | powerL1[6] << 8 | powerL1[7]); break;
case 8:
currentPowerL1 = ((unsigned long long)powerL1[1] << 56 | (unsigned long long)powerL1[2] << 48 | (unsigned long long)powerL1[3] << 40 | (unsigned long long)powerL1[4] << 32 | powerL1[5] << 24 | powerL1[6] << 16 | powerL1[7] << 8 | powerL1[8]); break;*/
}
powerValueLength =0;
debug_out(F("Leistung L1: "), DEBUG_MED_INFO, 0);
debug_out(String(currentPowerL1), DEBUG_MED_INFO, 1);
//stage = 4;
startIndexL1 = 0;
}
} else {
startIndexL1 = 0;
} // End of Power L1
}
stage++; // go to stage 3
memset(powerL1, 0, sizeof(powerL1)); // clear the buffers
debug_out(F("----------------------------------------------------------------------------"), DEBUG_MED_INFO, 1);
}
Ich bin bei meinen Analysen meines Zählers noch nicht über die Wert-Länge 3 (0x54) hinaus gekommen, weshalb alles was länger wäre auskommentiert ist.
Wenn hier jemand noch die korrekte Syntax herausfindet oder weiß, freue ich mich über eine Info.
Ich hoffe hiermit anderen mit Smart Meter SML, HEX und negativen Werten weiterhelfen zu können.