ILC 155, Udint64

Portisch

Level-1
Beiträge
149
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich bin gerade dabei einen Fronius Symo Wechselrichter per Modbus zu integrieren.
Nun gibt dieser Werte als Udint64 aus.

Das unterstützt die ILC ja gar nicht, oder?
Muss man hier einen komplizierten langen Weg gehen, dass ganze in Udint32 umzuwandeln?

Ich will nämlich auch damit rechnen...
 
Hi Portisch

es gibt von PxC eine Library Sammlung namens Solarworx. Dies beinhaltet auch Bausteine neben Inverter wie Kaco, Huawei.... auch Bausteine für das SunSpec Interface welches die fronius Symo haben




ansonsten zur Wandlung
rValue := udint_to_real (dword_to_udint (dwIn1)) * 4294967296.0 (* high dword *)
+ udint_to_real (dword_to_udint (dwIn2));(* low dword *)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Wie Du schon gesagt hast unterstützen wir derzeit keine Ganzzahl 64 bit.

Du kannst natürlich die 2 niederwertigen worte aus dem Modbus Registern nutzen und mit dword nach udint wandeln (range 0-4294967295), bei einer Wandlung in real 32 bit würde der max Wert gerundet auf 4294967296,0

Wie auch Oerw geschrieben hat gibt es auch eine SunSpec Bibliothek die sich in der Solarworx befindet. Der FroniusSymo muss allerding das SunSpec Protokoll unterstützen.
 
Habe mir die SunSpec Bausteine angesehen.
Ich glaube das geht aber mit dem Fronius aber nicht, oder?

Der Fronius unterstützt zwar Sunspec als Push Service, aber als FTP Upload oder als HTTP Post.
Oder ist das eh das richtige?

Wo gibt es ein Beispiel?
 
Hi

SunSpec ist ein Profil was auf Modbus basiert.

Und die Symo Geräte besitzen dieses Profil

Da du die Daten per Modbus lesen möchtest, schau mal auf die ersten zwei Register, darin ist "SunS" abgebildet. Anschließend kommt als Registerwert 0001, Dies ist eine sogenannte PICS. In diesem PICS steht der Hersteller, Seriennummer etc
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe es per FTP Upload einmal probiert. Fronius liefert wenig bis gar keine Daten über SunSpec.
SunSpec 1.0b:
Code:
<SunSpecData v="1">    <d man="Fronius" mod="Fronius Symo 3.7-3-S" sn="345345345345" t="2016-09-24T09:47:11+02:00">
        <m id="1">
            <p id="Mn">Fronius</p>
            <p id="Md">Fronius Symo 3.7-3-S</p>
            <p id="Vr">0.2.0.1</p>
            <p id="SN">345345345345</p>
            <p id="DA">1</p>
        </m>
        <m id="113">
            <p id="W">2366.000000</p>
            <p id="Wh">11106287.000000</p>
            <p id="St">4</p>
        </m>
    </d>
</SunSpecData>

SunSpec 1.2:
Code:
<SunSpecData v="1.2" />

Werde also direkt über Modbus (oscat) die Daten auslesen müssen.

Interessant wären diese Werte:
F_Site_Power
F_Site_Energy_Day
F_Site_Energy_Year
F_Site_Energy_Total
http://www.fronius.com/Applikationen/contentserverdownload/downloadcsitem.aspx?id=361552

Jedoch bekomme ich mit Funktionscode 0x03, Adresse 499 (500) nur die Antwort: ILLEGAL DATA ADDRESS

Andere Register wie z.B. 40004 (40005) funktionieren und liefert mir den Mn (Manufacturer)
 
hier http://www.fronius.de/cps/rde/xbcr/...nternational/42_0410_2152_402156_snapshot.pdf findest du die XML formate.
Die V1.2 ist für Meter und nicht für Wechselrichter

-> im FTP upload oder HTTP hast du somit garnicht alle Daten, alle anderen befinden sich im Modbus (die unteren wie z..b: 500 oder bei 40000 im SunSpec format)
Die F_Site.... Werte kannst du dir selbst ermitteln wenn du aus der PICS122 den "AC lifetime power" nimmst

Das mit der Adresse 499 (500) kann ich dir nicht sagen, da ich diese bisher nicht verwendet habe.
Allerdings hast du hier nicht angegeben, wieviele Register du auslesen würdest. Der erste Werte hat zwei Register, daher würde ich hier einfach mal Adresse 499 (500) nehmen mitr der Anzahl 2.
Eventuell ist es nicht erlaubt, mehrere Werte zeitgleich abzuholen
 
Habe das Problem gelöst! Der Fehler mit ILLEGAL DATA ADDRESS kommt wenn man den Modbus im Demo Modus betreibt.
Im normalen Betrieb können die Daten gelesen werden. Das gute an den Fronius Registern ist, dass man keine Skalierung braucht.

Und mit LREAL geht es auch mit den 64 Bit ;).

Hier der ST Code:
Code:
(*@PROPERTIES_EX@TYPE: POU
LOCALE: 0
IEC_LANGUAGE: ST
PLC_TYPE: independent
PROC_TYPE: independent
GROUP: Fronius
*)
(*@KEY@:DESCRIPTION*)


(*@KEY@:END_DESCRIPTION*)
FUNCTION_BLOCK SYMO


(*Group:Out*)




VAR_OUTPUT
    F_Active_State_Code :    WORD;
    F_Site_Power :    UDINT;
    F_Site_Energy_Day :    LREAL;
    F_Site_Energy_Year :    LREAL;
    F_Site_Energy_Total :    LREAL;
    ERROR :    DWORD;
END_VAR




(*Group:Modbus*)




VAR
    FC :    INT := 3;
    BUSY :    BOOL;
    DELAY :    TIME := TIME#60s;
    UINT_ID :    BYTE := BYTE#1;
    DATA :    oscat_aW0_255;
    R_ADDR :    WORD := WORD#213;
    R_POINTS :    WORD := WORD#1;
    R_DATA_ADR :    INT := 0;
    R_DATA_BITPOS :    INT := 0;
END_VAR




(*Group:lokal*)




VAR
    dwrd1 :    UDINT;
    dwrd2 :    UDINT;
    lreal1 :    LREAL;
    state :    INT := 1;
    state_convert :    INT := 0;
    run :    BOOL := FALSE;
    enable_trigger :    BOOL := FALSE;
    S_BUF :    oscat_NETWORK_BUFFER_SHORT;
    R_BUF :    oscat_NETWORK_BUFFER_SHORT;
    IP_C :    oscat_IP_C;
    IP_CONTROL2_1 :    IP_CONTROL2;
    MY_MB_CLIENT_1 :    MY_MB_CLIENT;
    TIMEOUT :    TIME := TIME#10s;
END_VAR




(*Group:IN*)




VAR_INPUT
    ENABLE :    BOOL := FALSE;
    IP :    DWORD;
    PORT :    WORD;
END_VAR




(*@KEY@: WORKSHEET
NAME: SYMO
IEC_LANGUAGE: ST
*)
CASE state OF
    1:    IF ENABLE THEN
            state := 2;
        END_IF;
    (* get F_Active_State_Code *)
    2:    R_ADDR := WORD#213;
        R_POINTS := WORD#1;
        state := 10;
        state_convert := 1;


    (* get F_Site_Power *)
    3:    R_ADDR := WORD#499;
        R_POINTS := WORD#2;
        state := 10;
        state_convert := 2;


    (* get F_Site_Energy_Day *)
    4:    R_ADDR := WORD#501;
        R_POINTS := WORD#4;
        state := 10;
        state_convert := 3;


    (* get F_Site_Energy_Year *)
    5:    R_ADDR := WORD#505;
        R_POINTS := WORD#4;
        state := 10;
        state_convert := 4;


    (* get F_Site_Energy_Total *)
    6:    R_ADDR := WORD#509;
        R_POINTS := WORD#4;
        state := 10;
        state_convert := 5;


    (* wait until started *)
    10:    IF BUSY THEN
            state := 11;
        END_IF;


    (* wait until finished *)
    11:    IF NOT BUSY THEN
            CASE state_convert OF
                1:    F_Active_State_Code := DATA[0];
                    state := 3;
                2:     F_Site_Power := DWORD_TO_UDINT(SHL(WORD_TO_DWORD(DATA[0]), 16) + WORD_TO_DWORD(DATA[1]));
                    state := 4;
                3,4,5:    dwrd1 := DWORD_TO_UDINT(SHL(WORD_TO_DWORD(DATA[0]), 16) + WORD_TO_DWORD(DATA[1]));
                        dwrd2 := DWORD_TO_UDINT(SHL(WORD_TO_DWORD(DATA[2]), 16) + WORD_TO_DWORD(DATA[3]));
                        lreal1 := (UDINT_TO_LREAL(dwrd1) * LREAL#4294967296.0 + UDINT_TO_LREAL(dwrd2)) / LREAL#1000.0;
            END_CASE;


            CASE state_convert OF
                3:    F_Site_Energy_Day := lreal1;
                    state := 5;
                4:    F_Site_Energy_Year := lreal1;
                    state := 6;
                5:    F_Site_Energy_Total := lreal1;
                    state := 1;
            END_CASE;
        END_IF;


END_CASE;


IP_CONTROL2_1(
    IP:=IP,
    PORT:=PORT,
    TIME_OUT:=TIMEOUT,
    IP_C:=IP_C,
    S_BUF:=S_BUF,
    R_BUF:=R_BUF);


IP_C:=IP_CONTROL2_1.IP_C;
S_BUF:=IP_CONTROL2_1.S_BUF;
R_BUF:=IP_CONTROL2_1.R_BUF;


MY_MB_CLIENT_1(
    IP_C:=IP_C,
    S_BUF:=S_BUF,
    R_BUF:=R_BUF,
    DATA:=DATA,
    DATA_SIZE:=INT#256,
    ENABLE:=ENABLE,
    UDP:=FALSE,
    FC:=FC,
    UNIT_ID:=UINT_ID,
    R_ADDR:=R_ADDR,
    R_POINTS:=R_POINTS,
    R_DATA_ADR:=R_DATA_ADR,
    R_DATA_BITPOS:=R_DATA_BITPOS,
    DELAY:=DELAY);


IP_C := MY_MB_CLIENT_1.IP_C;
S_BUF := MY_MB_CLIENT_1.S_BUF;
R_BUF := MY_MB_CLIENT_1.R_BUF;
DATA := MY_MB_CLIENT_1.DATA;
ERROR := MY_MB_CLIENT_1.ERROR;
BUSY := MY_MB_CLIENT_1.BUSY;




(*@KEY@: END_WORKSHEET *)
END_FUNCTION_BLOCK


Der
MY_MB_CLIENT_1 is eigentlich der gleiche wie der originale MB_CLIENT_1 von oscat.
Ich habe nur die Read Adresse von INT auf WORD geändert, da ansonsten die Register 40000 nicht gelesen werden konnten.
INT get bei der ILC nur bis 32767!
 
Zurück
Oben