EHZ Zähler auslesen

Begonnen von X-User, 22. März 2012, 10:04:47

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 2 Gäste betrachten dieses Thema.

mattsches

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

knuetterich

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

knuetterich

Zitat von: mattsches in 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



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

mattsches

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?

knuetterich

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ß

knuetterich

Hallo Leute,

hat sich hier was getan?
Ich komme einfach nicht weiter.
Gibt es mittlerweile einen Baustein für eine Wago 750-841, um einen EHZ mittels optischer Schnittstelle (Lesekopf von Volkszähler)
über RS232 auszulesen?

martin.k

Hallo

auch wenn ich nur eine negative Antwort geben kann, dachte ich mal, ich schreibe was. Dann siehst Du wenigstens das Deine Frage gehört wurde :-)
Ich bekomme die Zählerdaten von meiner Photovoltaiküberwachungssoftware per Http.
Mehr brauche ich nicht.
Viele Grüße
Martin