Autor Thema: EHZ Zähler auslesen  (Gelesen 21411 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline mattsches

  • Full Member
  • ***
  • Beiträge: 183
    • Profil anzeigen
Re: EHZ Zähler auslesen
« Antwort #15 am: 14. Januar 2015, 22:36:11 »
Hallo Ralf,

ich mache das mit meinem EMH (EnBW) und meiner Beckhoff mit einem Schmalspur-(nur die beiden Zähler 1.8.0 und 2.8.0 sowie die aktuelle Leistung werden ausgelesen) Baustein so:

FUNCTION_BLOCK EMH_Meter
VAR_INPUT
bTrigger : BOOL; (* externer Trigger für Ausgabe der aktuellen Zählerdaten *)
END_VAR
VAR_OUTPUT
rIncomingEnergy : REAL; (* Bezugszähler in kWh *)
rOutgoingEnergy : REAL; (* Einspeisezähler in MWh *)
rAvailablePower : REAL; (* aktuell verfügbare Leistung in W; positiv: Einspeisung, negativ: Bezug *)
bNewDataReceived : BOOL; (* new data received from meter *)
END_VAR
VAR
KL6Control_COM2 : SerialLineControl;
bError_COM2 : BOOL;
udErrorId_COM2 : UDINT;

fbReceiveData : ReceiveData;

aPrefix : ARRAY[0..7] OF BYTE := 16#1B, 16#1B, 16#1B, 16#1B, 16#01, 16#01, 16#01, 16#01;
aSuffix : ARRAY[0..5] OF BYTE := 16#1B, 16#1B, 16#1B, 16#1B, 16#1A, 16#01;
aReceiveData : ARRAY[0..511] OF BYTE := 256(0);

pValueFromMeter : POINTER TO DINT;
aValueFromMeter : ARRAY[0..3] OF BYTE;

rBufIncomingEnergy : REAL; (* Puffer für Bezugszähler in kWh *)
rBufOutgoingEnergy : REAL; (* Puffer für Einspeisezähler in MWh *)
rBufAvailablePower : REAL; (* Puffer für aktuell verfügbare Leistung in W; positiv: Einspeisung, negativ: Bezug *)

END_VAR

(* COM2-Schnittstelle ansteuern *)
KL6Control_COM2(
Mode := SERIALLINEMODE_PC_COM_PORT,
pComIn := ADR(Com2InData),
pComOut := ADR(Com2OutData),
SizeComIn := SIZEOF(Com2InData),
TxBuffer := TxBuffer_COM2,
RxBuffer := RxBuffer_COM2,
Error => bError_COM2,
ErrorID => udErrorId_COM2);

(* Telegramm aus Empfangspuffer holen, Erkennung mittels Präfix und Suffix *)
fbReceiveData(
pPrefix:= ADR(aPrefix),
LenPrefix:= 8,
pSuffix:= ADR(aSuffix),
LenSuffix:= 6,
pReceiveData:= ADR(aReceiveData),
SizeReceiveData:= SIZEOF(aReceiveData),
Timeout:= t#700ms,
Reset:= ,
RXbuffer:= RxBuffer_COM2,
DataReceived=> ,
busy=> ,
Error=> ,
RxTimeout=> ,
LenReceiveData=> );

bNewDataReceived := FALSE;

(* Daten aufbereiten, wenn empfangen *)
IF fbReceiveData.DataReceived THEN
bNewDataReceived := TRUE;

(* aktuelle Werte aus empfangenem Byte-String auslesen *)
(* Byte-Reihenfolge ist gegenüber Codesys gedreht! *)
pValueFromMeter := ADR(aValueFromMeter); (* Zeiger auf Zwischenspeicher vorbereiten *)

(* Bezugszähler: Bytes 156-159 *)
aValueFromMeter[0] := aReceiveData[159]; (* Bezugszähler in 0,1 Wh *)
aValueFromMeter[1] := aReceiveData[158];
aValueFromMeter[2] := aReceiveData[157];
aValueFromMeter[3] := aReceiveData[156];
rBufIncomingEnergy := DINT_TO_REAL(pValueFromMeter^)/10000; (* skaliert auf kWh *)

(* Einspeisezähler: Bytes 180-183 *)
aValueFromMeter[0] := aReceiveData[183]; (* Bezugszähler in 0,1 Wh *)
aValueFromMeter[1] := aReceiveData[182];
aValueFromMeter[2] := aReceiveData[181];
aValueFromMeter[3] := aReceiveData[180];
rBufOutgoingEnergy := DINT_TO_REAL(pValueFromMeter^)/10000000; (* skaliert auf MWh *)

(* aktuelle Leistung: Bytes 284-287 *)
(* positiver Wert=Bezug, negativer Wert=Einspeisung *)
aValueFromMeter[0] := aReceiveData[287]; (* aktuelle Leistung in 0,1 W *)
aValueFromMeter[1] := aReceiveData[286];
aValueFromMeter[2] := aReceiveData[285];
aValueFromMeter[3] := aReceiveData[284];
rBufAvailablePower := DINT_TO_REAL(pValueFromMeter^)/10*-1;
END_IF

(* Daten ausgeben, wenn angefordert *)
IF bTrigger THEN
rIncomingEnergy := rBufIncomingEnergy;
rOutgoingEnergy := rBufOutgoingEnergy;
rAvailablePower := rBufAvailablePower;
END_IF

Kann aber gut sein, dass das für deinen Zähler nicht passt.

Die Werte übernehme ich mit einem externen Trigger (=Daten vom Wechselrichter erhalten); einfach die Abfrage "IF bTrigger..." rausschmeißen, wenn nicht gewünscht bzw. den ganzen Block löschen und direkt in die Ausgangsvariablen schreiben.

Zum Auslesen benutzte ich eine super simple Schaltung aus je einem Fototransistor und Widerstand, angelehnt an die Infos von armin63 hier: http://www.photovoltaikforum.com/datenlogger-f5/hager-ehz-auslesen-t57405.html. Kostet 'n Appel. Nicht mal mit Ei.

Gruß,
mattsches

Offline knuetterich

  • Newbie
  • *
  • Beiträge: 9
    • Profil anzeigen
Re: EHZ Zähler auslesen
« Antwort #16 am: 20. Januar 2015, 15:52:16 »
Hallo mattsches,

erstmal vielen Dank für Antwort.  :)
Ich habe mir mittlerweile den Lesekopf (RS232) von Volkszähler bestellt.
Die RS232-Karte 750-650 habe ich leider noch nicht.
Wenn die Komponenten an Bord sind, werde ich mal tüfteln.

Der FB könnte bei mir so ähnlich aussehen, jedoch ist natürlich die Bibliothek zwischen Beckhoff und Wago unterschiedlich.
Ich benötige wohl die Bibliothek Serial_Interface_01.lib.

Ich suche noch nach Beispielen die auf meine Anwendung passen.

Gruß
Ralf

Offline knuetterich

  • Newbie
  • *
  • Beiträge: 9
    • Profil anzeigen
Re: EHZ Zähler auslesen
« Antwort #17 am: 05. März 2015, 14:50:38 »
Hallo Ralf,

ich mache das mit meinem EMH (EnBW) und meiner Beckhoff mit einem Schmalspur-(nur die beiden Zähler 1.8.0 und 2.8.0 sowie die aktuelle Leistung werden ausgelesen) Baustein so:

FUNCTION_BLOCK EMH_Meter
VAR_INPUT
bTrigger : BOOL; (* externer Trigger für Ausgabe der aktuellen Zählerdaten *)
END_VAR
VAR_OUTPUT
rIncomingEnergy : REAL; (* Bezugszähler in kWh *)
rOutgoingEnergy : REAL; (* Einspeisezähler in MWh *)
rAvailablePower : REAL; (* aktuell verfügbare Leistung in W; positiv: Einspeisung, negativ: Bezug *)
bNewDataReceived : BOOL; (* new data received from meter *)
END_VAR
VAR
KL6Control_COM2 : SerialLineControl;
bError_COM2 : BOOL;
udErrorId_COM2 : UDINT;

fbReceiveData : ReceiveData;

aPrefix : ARRAY[0..7] OF BYTE := 16#1B, 16#1B, 16#1B, 16#1B, 16#01, 16#01, 16#01, 16#01;
aSuffix : ARRAY[0..5] OF BYTE := 16#1B, 16#1B, 16#1B, 16#1B, 16#1A, 16#01;
aReceiveData : ARRAY[0..511] OF BYTE := 256(0);

pValueFromMeter : POINTER TO DINT;
aValueFromMeter : ARRAY[0..3] OF BYTE;

rBufIncomingEnergy : REAL; (* Puffer für Bezugszähler in kWh *)
rBufOutgoingEnergy : REAL; (* Puffer für Einspeisezähler in MWh *)
rBufAvailablePower : REAL; (* Puffer für aktuell verfügbare Leistung in W; positiv: Einspeisung, negativ: Bezug *)

END_VAR

(* COM2-Schnittstelle ansteuern *)
KL6Control_COM2(
Mode := SERIALLINEMODE_PC_COM_PORT,
pComIn := ADR(Com2InData),
pComOut := ADR(Com2OutData),
SizeComIn := SIZEOF(Com2InData),
TxBuffer := TxBuffer_COM2,
RxBuffer := RxBuffer_COM2,
Error => bError_COM2,
ErrorID => udErrorId_COM2);

(* Telegramm aus Empfangspuffer holen, Erkennung mittels Präfix und Suffix *)
fbReceiveData(
pPrefix:= ADR(aPrefix),
LenPrefix:= 8,
pSuffix:= ADR(aSuffix),
LenSuffix:= 6,
pReceiveData:= ADR(aReceiveData),
SizeReceiveData:= SIZEOF(aReceiveData),
Timeout:= t#700ms,
Reset:= ,
RXbuffer:= RxBuffer_COM2,
DataReceived=> ,
busy=> ,
Error=> ,
RxTimeout=> ,
LenReceiveData=> );

bNewDataReceived := FALSE;

(* Daten aufbereiten, wenn empfangen *)
IF fbReceiveData.DataReceived THEN
bNewDataReceived := TRUE;

(* aktuelle Werte aus empfangenem Byte-String auslesen *)
(* Byte-Reihenfolge ist gegenüber Codesys gedreht! *)
pValueFromMeter := ADR(aValueFromMeter); (* Zeiger auf Zwischenspeicher vorbereiten *)

(* Bezugszähler: Bytes 156-159 *)
aValueFromMeter[0] := aReceiveData[159]; (* Bezugszähler in 0,1 Wh *)
aValueFromMeter[1] := aReceiveData[158];
aValueFromMeter[2] := aReceiveData[157];
aValueFromMeter[3] := aReceiveData[156];
rBufIncomingEnergy := DINT_TO_REAL(pValueFromMeter^)/10000; (* skaliert auf kWh *)

(* Einspeisezähler: Bytes 180-183 *)
aValueFromMeter[0] := aReceiveData[183]; (* Bezugszähler in 0,1 Wh *)
aValueFromMeter[1] := aReceiveData[182];
aValueFromMeter[2] := aReceiveData[181];
aValueFromMeter[3] := aReceiveData[180];
rBufOutgoingEnergy := DINT_TO_REAL(pValueFromMeter^)/10000000; (* skaliert auf MWh *)

(* aktuelle Leistung: Bytes 284-287 *)
(* positiver Wert=Bezug, negativer Wert=Einspeisung *)
aValueFromMeter[0] := aReceiveData[287]; (* aktuelle Leistung in 0,1 W *)
aValueFromMeter[1] := aReceiveData[286];
aValueFromMeter[2] := aReceiveData[285];
aValueFromMeter[3] := aReceiveData[284];
rBufAvailablePower := DINT_TO_REAL(pValueFromMeter^)/10*-1;
END_IF

(* Daten ausgeben, wenn angefordert *)
IF bTrigger THEN
rIncomingEnergy := rBufIncomingEnergy;
rOutgoingEnergy := rBufOutgoingEnergy;
rAvailablePower := rBufAvailablePower;
END_IF


Hallo mattsches,

ich habe mal versucht deinen Code auf einer Beckhoff umzusetzen.
Dabei bekomme ich eine Fehlermeldung, dass die Variablen "Com2InData", "Com2OutData", "TxBuffer_Com2" und "RxBuffer_Com2" nicht existieren.
Kannst du hier weiterhelfen?

Gruß
Ralf

Offline mattsches

  • Full Member
  • ***
  • Beiträge: 183
    • Profil anzeigen
Re: EHZ Zähler auslesen
« Antwort #18 am: 05. März 2015, 21:19:40 »
Das sind globale Variablen, d.h. in einer GVL deklariert:
(* COM2 - EMH Stromzähler *)
Com2InData AT %I* : PcComInData;
Com2OutData AT %Q* : PcComOutData;
RxBuffer_Com2 : ComBuffer;
TxBuffer_Com2 : ComBuffer;

In und OutData sind dann im Systemmanager mit den Prozessdaten der seriellen Schnittstelle verknüpft.

Im Beckhoff Information System ist die Einbindung der Schnittstelle ganz gut beschrieben: http://infosys.beckhoff.de/index.php?content=../content/1031/tcplclibserialcom/html/tcplclibsercom_common.htm&id=

Aber ich dachte, Du hast eine Wago-Steuerung? Dann funktioniert das reine Einlesen der Daten von der Schnittstelle ja eh anders, und mein Beispiel dürfte für Dich erst ab der Zeile
IF fbReceiveData.DataReceived THEN
interessant werden. Oder?

Offline knuetterich

  • Newbie
  • *
  • Beiträge: 9
    • Profil anzeigen
Re: EHZ Zähler auslesen
« Antwort #19 am: 13. Oktober 2017, 10:28:24 »
Hallo Leute,

ich möchte das Thema noch einmal aufgreifen.
Gibt es mittlerweile einen Baustein für eine Wago 750-841, um einen EHZ mittels optischer Schnittstelle (Lesekopf von Volkszähler)
über RS232 auszulesen?


Gruß