# Eltako M-Bus Stromzähler mittels CoDeSys auslesen



## SPS_A (29 Juni 2015)

Hallo zusammen,

ich möchte über M-Bus mehrere Stromzähler auslesen. Prinzipiell geht das ganze ja über die von WAGO bereitgestellten Bibliotheken recht einfach. Jetzt hat der Zähler, den ich auslesen möchte, aber die Werte etwas "unkonventionell" gespeichert. Es handelt sich um einen Eltako DSZ12DM. Die M-Bus Beschreibung ist unter folgendem Link zu finden: 

http://www.eltako.com/fileadmin/dow...tromzaehler_Technische_Daten_Einlernhilfe.pdf

Auf Seite 2 (3 im laufenden Dokument) ist ja beschrieben, in welchem Byte welche Info steckt. Nun werten aber alle Funktionsblöcke, die ich in den M-Bus Bibliotheken von WAGO gefunden habe, maximal die ersten 20 Datensätze aus. Jetzt würde ich einfach den "FbMbus_RawDevice" Baustein nehmen, um das ganze Telegramm abzufangen. Scheint auch relativ einfach zu gehen, die Spannung auf den einzelnen Phasen lässt sich auch ohne Umwandlung auslesen, da die ~230V ja problemlos in ein Byte passen. Die einzige Hilfe die ich bräuchte, wäre das Umwandeln der anderen Werte. Also wie mache ich z.B. aus Byte 23-26 "4 b.BCD" einen Double, um die Energiemenge mit Kommazahl zu bekommen? Hat da jemand eine Idee? Ich hatte es über folgende Funktion versucht:


```
FUNCTION DoubleByteToReal : REAL
VAR_INPUT
    b1 : BYTE;
    b2 : BYTE;
END_VAR
VAR
    ar : ARRAY[0..1] OF BYTE;
    pR : POINTER TO REAL;
END_VAR
```


```
ar[0] := b1;
ar[1] := b2;

pR := ADR(ar);

DoubleByteToReal := pR^;
```

Da kommt aber nichts sinnvolles bei raus. Hat vielleicht jemand einen Lösungsansatz?

Viele Grüße


----------



## Thruser (1 Juli 2015)

Hallo,

das mit Deinem Real wird so nicht funktionieren. Das BCD in der Tabelle steht für binary coded decimal. Richtig ausgelesen erhälst Du dann erst einmal eine Ganzzahl. Im Byte davor (22, für 23-26) findest Du ob der Wert dann durch 10 oder durch 100 geteilt werden muß..

Gruß


----------



## SPS_A (2 Juli 2015)

Hallo Thruser,

vielen Dank für dein Antwort. Als Beispiel habe ich mal ein Telegramm ausgelesen. Im "MBuBuffer" liegt das "abobData" Array mit einer Größe von 0 bis 255, also 256 Bytes. Bytes 23-26 aus dem Datenblatt müssten dann ja 22-25 aus dem MBus-Buffer sein. Darin stehen folgende Werte:

```
aobData[22] = 18
aobData[23] = 86
aobData[24] = 52
aobData[25] = 0
```

So wirklich schlau werd ich daraus aber nicht. Wie komm ich von den 4 Bytes auf etwas verwertbares für die Potenz und den Zählerstand!?

Viele Grüße

edit: 

Wenn ich jetzt z.B. mit der util.lib die BCD_TO_INT-Konvertierung für die einzelnen Bytes durchführe:


```
bcdkonv1 := BCD_TO_INT(18);
bcdkonv2 := BCD_TO_INT(86);
bcdkonv3 := BCD_TO_INT(52);
bcdkonv4 := BCD_TO_INT(0);
```

Kommt folgendes raus:


```
bcdkonv1 = 12
bcdkonv2 = 56
bcdkonv3 = 34
bcdkonv4 = 0
```

Macht das so erstmal Sinn!?

Viele Grüße


----------



## Thruser (2 Juli 2015)

Hallo,

prüf doch erst einmal folgendes:

In Byte 19 (Array) müßte der Wert 0x8C (140) stehen und in Byte 20 der Wert 0x11 (17). Damit kannst Du schon einmal gucken ob Du die richtige Stelle hast. Im nächsten Byte (21) muß dann entweder 0x04 (4) oder 0x05 (5) stehen.

Dein Wert müßte dann entweder 3456,12 kWh oder 34561,2 kWh sein. (Ich gehe davon aus, daß EtoT1_1 die höchsten und EtoT1_4 die niederwertigsten Stellen sind).

Was zeigt denn Dein Zähler an?

Am besten Du läßt Dir die Werte mal in Hex anzeigen, da kann man BCD nämlich wunderbar ablesen.

12 -> 0x12 = 18 (int)
23 -> 0x23 = 35 (int)

Aber kann die Wago MBus_03.lib Bibliothek das wirklich nicht lesen? (FbMBus_Electricity)

Gruß


----------



## SPS_A (5 Juli 2015)

Hallo Thruser,

vielen Dank für deine Info. Ich komm remote leider nicht an den Zähler dran und habe grade nur einen Screenshot zur Hand mit ein paar Werten aus dem Array. In den Bytes die du beschrieben hast stehen die Werte so drin, in Byte 21 bzw. 22 aus der Beschreibung die 4. Ich hatte es bisher mit der M_Bus02.lib probiert. Die Energiemenge konnte ich damit auslesen, aber an Leistung kam ich leider nur an die von Phase1-N drangekommen, aber bei der Gesamtleistung war Schluss. Werde versuchen morgen mal vorbeizufahren und das zu testen. Eine Frage vorab vielleicht noch: Wie würde ich am geschicktesten aus den 4 Einzelbytes den Messwert zusammensetzen. Mit fällt grade nur eine Stringzusammensetzung anschließend eine Umwandlung in ein REAL ein, was sicherlich eine sehr sehr ungünstige Variante ist. 

Besten Dank noch mal für die Hile, viele Grüße


----------



## Thruser (6 Juli 2015)

Hi,


```
power := BCD_TO_INT(aobData[25]);
power := power*100+BCD_TO_INT(aobData[24]);
power := power*100+BCD_TO_INT(aobData[23]);
power := power*100+BCD_TO_INT(aobData[22]);

power := power/10; (*für aobData[21]=4, /100 für aobData[21]=5*)
```

das ist eine Möglichkeit. Eventuell mußt Du die Reihenfolge vertauschen.

Gruß


----------

