Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: e!Cockpit Modbus-TCP

  1. #1
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    ich bin neu hier und versuche seit einiger Zeit mit einer Wago PFC200 eine elektronische Last anzusteuern. Zur Kommunikation dient ein zusätzliches Modul an der Last. Dieses erlaubt die Kommunikation via Modbus TCP (auf dem Port 502) und Modbus RTU (auf dem Standard-Port 5025 und allen anderen). Die Daten selbst werden über ein Patchkabel übertragen.
    Ich arbeite in e!Cockpit mit dem Baustein FbMbMasterTcp, um mit Modbus TCP die Last anzusteuern, was soweit auch ganz gut funktioniert. Nun möchte ich ein Programm (ModbusTCP_1), das sich um die wiederkehrenden Standardanfragen kümmert. Dieses wird regelmäßig von PLC_PRG aufgerufen und bekommt nur die Daten mit, die übergeben werden. Die Register sind schon im Programm deklariert. In PLC_PRG werden die Daten verarbeitet bzw. weitergeleitet, was auch klappt.


    Nun habe ich zwei Probleme, die ich nicht gelöst bekomme:

    Problem 1: Ich kann einzelne Register nicht auslesen. Konkret geht es hier um die aktuellen Messwerte der Last. Ich empfange das Echo, welches besagt, dass ich die Register auslesen möchte, awData bleibt jedoch leer (0).

    Problem 2 (ist vermutlich simpler): Ich möchte in drei unterschiedliche Register nacheinander verschiedene Werte schreiben und anschließend drei weitere Register auslesen. Das Ganze soll noch mit einer IF-Bedingung kombiniert werden, sodass die nächste Anfrage nur gesendet wird, wenn die Anfrage, die zuletzt gesendet wurde, in utResponse zu finden ist. Eigentlich dachte ich, ich könnte das recht einfach lösen, aber alle Versuche und auch ein Lösungsvorschlag mit einer Joblist, aus einem anderen Beitrag hier, haben bei mir nur zu Fehlern geführt (zumal ich die Register nicht auslesen kann, siehe erstes Problem).

    Die Variablen hätte ich wie folgt deklariert:
    Code:
    PROGRAM ModbusTCP_1
    VAR_INPUT
        // Sollwerte von U I und P  werden übergeben und sollen nacheinander gesendet werden.
        // Wurde ein Wert gesendet soll erst die Antwort (ein Echo) überprüft werden
        // im Anschluss werden die Werte gemessen und zurück ans Hauptprogramm gegebenausgegeben. 
        
        wertU:        WORD;
        wertI:        WORD;
        wertP:        WORD;
        // Istwert Strom lesen: (regNr:=16#03, readAdd:= 16#01FB, readQua:=1, writAdd:=0, writQua:=0);
        // Istwert Spannung lesen: (regNr:=16#03, readAdd:= 16#01FC, readQua:=1, writAdd:=0, writQua:=0);
        // Istwert Leistung lesen: (regNr:=16#03, readAdd:= 16#01FD, readQua:=1, writAdd:=0, writQua:=0);
    END_VAR
    VAR_OUTPUT
        messWertU:        WORD;
        messWertI:        WORD;
        messWertP:        WORD;
    END_VAR
    VAR
        // Spannung    
        regNrU:        BYTE := 16#06;
        writAddU:    WORD := 16#01F4;
        writQuaU:    WORD := 1;
        // Strom
        regNrI:        BYTE := 16#06;
        writAddI:    WORD := 16#01F5;
        writQuaI:    WORD := 1;
        // Leistung
        regNrP:        BYTE := 16#06;
        writAddP:    WORD := 16#01F6;
        writQuaP:    WORD := 1;
            
        myTcpMaster     : FbMbMasterTcp :=  (  xConnect        := TRUE,
                                               sHost        := '192.168.1.6',    // IP of the remote server
                                               wPort        := 502,                // port at the remote server
    
                                                utKeepAlive    := (    xEnable      := TRUE, // use keep alive
                                                                    tMaxIdleTime := T#5S, //  Maximum time of inactivity
                                                                    tInterval    := T#2S, //  Interval between two successive KA-Packets
                                                                    udiProbes    := 5     //  Number of KA retry before giving up
                                                                ),
                                                                
                                                eFrameType  := eMbFrameType.ETHERNET,
                                                tTimeOut    := T#30MS
                                            );
    
        utQuery         : typMbQuery := (   bUnitId         := 0,            // Slaveaddress
                                            bFunctionCode   := 0,            // write input registers
                                            uiReadAddress   := 0,            // Startaddress
                                            uiReadQuantity  := 0,            // Quantity of wanted registers
                                            uiWriteAddress  := 0,            // Startadresse
                                            uiWriteQuantity := 0,            // Quantity of wanted registers
                                            awWriteData        := [124(0)]        // array to write
                                        );
    
        xTxTrigger      : BOOL;             (* Set this variable once for start a job. This variable will be automaticly reset by the master if the job is done.*)
        utResponse      : typMbResponse;    (* After the job is done you can find at this structure the result.*)
        tonDelay        : TON := (PT := T#30MS); // This is the silence time between two requests
    END_VAR
    Im Programm wollte ich bFuctionCode bis awWriteData immer mit den passenden Informationen überschreiben.

    Ich muss dazu sagen, ich hatte mit Wago und Modbus noch nie etwas am Hut und bin, was das angeht, absoluter Anfänger. Verschiedene Dokus und das ein oder andere Video hatten mich bei meinen Problemen leider nicht groß weitergebracht.
    Bin für jeden Tipp dankbar.


    Viele Dank.
    Zitieren Zitieren e!Cockpit Modbus-TCP  

  2. #2
    Registriert seit
    20.01.2012
    Beiträge
    177
    Danke
    0
    Erhielt 62 Danke für 59 Beiträge

    Standard

    Hallo,

    hast Du denn schon einmal das auch in dem anderen Beitrag erwähnte qmodmaster oder ähnliches ausprobiert?

    Wie fragst Du denn die Daten im Programm ab, könntest Du eventuell mal den Teil des Codes zeigen? Da Du die Daten hier jetzt einzeln abfragst mußt Du auch erst jedesmal abwarten bis ein Auftrag fertiggestellt ist. Mit der Jobliste wären das bereits drei einzelne Jobs.

    Da die drei Adressen aufeinanderfolgen solltest Du versuchen die Daten in einem Rutsch, d.h. mit einem Auftrag, zu lesen (readQua:=3). Das minimiert die Ablaufzeit und die zu übertragende Datenmenge erheblich..

    Gruß

    PS: Warum benutzt Du nicht den Modbuskonfigurator von e!cockpit?
    Geändert von Thruser (13.06.2018 um 13:16 Uhr)

  3. #3
    Pari ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo Thruser,

    danke für die Antwort. Das Problem mit dem Leerbleiben der Response hat sich erledigt, ich bekomme nun eine Antwort, weiß beim besten Willen nicht wo der Fehler war und warum es zuvor nicht funktioniert hat. Ich glaube manchmal spinnt auch einfach nur die Last. qModMaster kannte ich schon.

    Danke für den Tipp, mehrere Register gleichzeitig zu lesen, das funktioniert tadellos. Mehrere Register gleichzeitig beschreiben lässt die Last aber nicht zu, daher müsste ich das über die Joblist erledigen. Bei dieser verstehe ich jetzt aber nicht genau wie diese funktioniert bzw. wie sie programmiert wird. Ich weiß, dass ich in den Variabeln ein Array erstellen muss vom Typ utQuery, mehr habe ich bisher aber nicht verstanden.

    Hier mal der Quelltext zur Jobliste:
    Code:
    PROGRAM Test
    // Test mit Joblist
    VAR
        Jobliste: ARRAY [0..3] OF typMbQuery :=  [//JOB 1 Spannung schreiben
                                              (    bUnitId         := 0,            // Slaveaddress
                                                bFunctionCode   := 16#06,        // write input registers
                                                uiReadAddress   := 0,            // Startaddress
                                                uiReadQuantity  := 0,            // Quantity of wanted registers
                                                uiWriteAddress  := 16#01F4,        // Startadresse
                                                uiWriteQuantity := 1,            // Quantity of wanted registers
                                                awWriteData        := [124(0)]        // array to write
                                              ), //JOB 2 Strom schreiben
                                              (    bUnitId         := 0,            // Slaveaddress
                                                bFunctionCode   := 16#06,        // write input registers
                                                uiReadAddress   := 0,            // Startaddress
                                                uiReadQuantity  := 0,            // Quantity of wanted registers
                                                uiWriteAddress  := 16#01F5,        // Startadresse
                                                uiWriteQuantity := 1,            // Quantity of wanted registers
                                                awWriteData        := [124(0)]        // array to write
                                              ),//JOB 3 Leistung schreiben
                                              (    bUnitId         := 0,            // Slaveaddress
                                                bFunctionCode   := 16#06,        // write input registers
                                                uiReadAddress   := 0,            // Startaddress
                                                uiReadQuantity  := 0,            // Quantity of wanted registers
                                                uiWriteAddress  := 16#01F6,        // Startadresse
                                                uiWriteQuantity := 1,            // Quantity of wanted registers
                                                awWriteData        := [124(0)]        // array to write
                                              ),//JOB 4 Werte auslesen
                                              ( bUnitId         := 0,            // Slaveaddress
                                                bFunctionCode   := 16#03,        // write input registers
                                                uiReadAddress   := 16#01FB,        // Startaddress
                                                uiReadQuantity  := 3,            // Quantity of wanted registers
                                                uiWriteAddress  := 0,            // Startadresse
                                                uiWriteQuantity := 0,            // Quantity of wanted registers
                                                awWriteData        := [124(0)]        // array to write
                                               )];
        Responseliste:ARRAY [0..3] OF typMbResponse;
        iCounter: INT := 0;
        xTrigger:BOOL:=TRUE;
        FB_ModbusMasterTCP:FbMbMasterTcp;
        
    END_VAR
    
    ===============================================================================
    
    FB_ModbusMasterTCP    (    xConnect    := TRUE,
                            sHost        := '192.168.1.6',    // IP of the remote server
                            wPort        := 502,                // port at the remote server
    
                            utKeepAlive    := (    xEnable      := TRUE, // use keep alive
                                                tMaxIdleTime := T#5S, //  Maximum time of inactivity
                                                   tInterval    := T#2S, //  Interval between two successive KA-Packets
                                                udiProbes    := 5     //  Number of KA retry before giving up
                                             ),
                                        
                            eFrameType  := eMbFrameType.ETHERNET,
                            tTimeOut    := T#30MS,
                            utQuery:=Jobliste[iJobCounter], 
                            xTrigger:=xTrigger, 
                               utResponse:=Responseliste[iJobCounter]);
                         );
                    
    // Fehler --> Weiß nicht weiter
    Das ist noch so ziemlich mein einziges Problem, wobei ich die Response, der ausgelesenen Werte, noch gerne in einem kleinen Array abspeichern würde.


    Grüße

  4. #4
    Registriert seit
    20.01.2012
    Beiträge
    177
    Danke
    0
    Erhielt 62 Danke für 59 Beiträge

    Standard

    Hi,

    schau Dir noch mal das Beispiel von hier an: Wago "Modbus TCP"-Kommunikation mit 750-8100 (Master) und 852 (Slave) unter e!Cockpit

    Da ist eigentlich schon alles dabei.

    Ansonsten müssen die Sollwerte in
    Jobliste[0].awWriteDate[0] für Spannung
    Jobliste[1].awWriteDate[0] für Strom
    Jobliste[2].awWriteDate[0] für Leistung



    Zitat Zitat von Pari Beitrag anzeigen
    // Fehler --> Weiß nicht weiter
    Zumindest ein Fehler ist das iCounter und iJobCounter verwendet wird.

    Zitat Zitat von Pari Beitrag anzeigen
    Das ist noch so ziemlich mein einziges Problem, wobei ich die Response, der ausgelesenen Werte, noch gerne in einem kleinen Array abspeichern würde.
    Die Daten stehen doch schon in einem Array: Responseliste[3].awData[0] bis Responseliste[3].awData[2]

    Gruß

  5. #5
    Pari ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Danke,

    irgendwie habe ich gerade festgestellt, dass sich fast alle meine Fragen von selbst aufgelöst haben. Muss wohl auch mal sein, obwohl man sich dann schön dämlich vorkommt. Hatte den Beitrag bestimmt schon zweimal gelesen, da ich das mit der Jobliste ja aus diesem hatte.

  6. #6
    Pari ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hey Thruser,

    hast Du noch einen Tipp, wie man auf die Zeiten, die zwischen den einzelnen Requests vergehen, bei der Jobliste besser eingehen kann? Ich habe den Verdacht, dass meine Last nicht alle Anfragen bearbeiten kann und würde daher gerne 30ms Zeit zwischen jedem Request lassen? Der FB_F_Trig löst ja direkt nach einer Anfrage aus oder verstehe ich das falsch? Ich hätte das Ganze jetzt so versucht:


    //Auf Jobende warten
    FB_F_Trig (clk:=xTrigger); // Bei Flanke startet
    delay(IN := FB_F_Trig.Q, PT := T#30MS); // TON

    //Jobende erfolgt, nächsten Job starten
    IF delay.Q THEN
    xTrigger :=TRUE;
    iJobCounter := (iJobCounter+1) MOD 4;
    END_IF

    bei dem Versuch gibt es jedoch garkeine Rückmeldung mehr.


    Grüße

  7. #7
    Registriert seit
    20.01.2012
    Beiträge
    177
    Danke
    0
    Erhielt 62 Danke für 59 Beiträge

    Standard

    Hallo,
    Zitat Zitat von Pari Beitrag anzeigen
    Hey Thruser,

    hast Du noch einen Tipp, wie man auf die Zeiten, die zwischen den einzelnen Requests vergehen, bei der Jobliste besser eingehen kann? Ich habe den Verdacht, dass meine Last nicht alle Anfragen bearbeiten kann und würde daher gerne 30ms Zeit zwischen jedem Request lassen? Der FB_F_Trig löst ja direkt nach einer Anfrage aus oder verstehe ich das falsch? Ich hätte das Ganze jetzt so versucht:


    //Auf Jobende warten
    FB_F_Trig (clk:=xTrigger); // Bei Flanke startet
    delay(IN := FB_F_Trig.Q, PT := T#30MS); // TON

    //Jobende erfolgt, nächsten Job starten
    IF delay.Q THEN
    xTrigger :=TRUE;
    iJobCounter := (iJobCounter+1) MOD 4;
    END_IF

    bei dem Versuch gibt es jedoch garkeine Rückmeldung mehr.


    Grüße
    FB_F_Trig ist immer nur einen Zyklus aktiv, daher funktioniert das nicht.

    Den kannst Du aber rausschmeissen:
    Code:
    delay(IN:=not xTrigger, PT := T#30MS);
    Gruß

  8. #8
    Pari ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Sprich ich muss mein Programm mehrfach aufrufen und die Zeit zwischen zwei Requests kann ich nicht genauer einstellen?


    Gruß

  9. #9
    Registriert seit
    20.01.2012
    Beiträge
    177
    Danke
    0
    Erhielt 62 Danke für 59 Beiträge

    Standard

    Hallo,

    Zitat Zitat von Pari Beitrag anzeigen
    Sprich ich muss mein Programm mehrfach aufrufen und die Zeit zwischen zwei Requests kann ich nicht genauer einstellen?
    Nein und Nein.

    Wenn Du mit dem TON Timer arbeiten willst, darfst Du nicht mit der Flanke arbeiten, da die Flankenauswertung nur ein Impuls ist, der Timer aber ein dauerhaftes Signal benötigt. Daher einfach das negierte xTrigger Signal für den Timer verwenden.

    Code:
    delay(IN := not xTrigger, PT := T#30MS); // TON
    
    
    //Jobende erfolgt, nächsten Job starten
    IF delay.Q THEN 
      xTrigger :=TRUE;
      iJobCounter := (iJobCounter+1) MOD 4;
    END_IF
    Dadurch muß xTrigger für 30ms false sein, bevor es wieder auf true gesetzt wird.

    Gruß

  10. #10
    Pari ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    04.06.2018
    Beiträge
    6
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    hab wieder ein altes Problem mit meinem geliebten Modbus. Meine beiden Programme wurden bisher zyklisch aufgerufen, nun sollen diese einmalig aufgerufen werden. Anbei mal zwei Screenshots, einmal ein Programm für einzelne Sonderbefehle und ein Programm mit einer Jobliste. Das Programm mit den Sonderbefehlen muss ich dreimal aufrufen, damit meine Last einen Befehl bekommt, meine Jobliste muss ein vielfaches davon aufgerufen werden.
    Versuche das Problem mit Schleifen oder Timer zu lösen, schlugen fehl. Gibt es hier eine Möglichkeit das Problem ohne zyklischen Aufruf zu lösen?


    Grüßesonderbefehle.jpgJoblist.jpg

Ähnliche Themen

  1. Antworten: 15
    Letzter Beitrag: 16.11.2018, 10:59
  2. Antworten: 16
    Letzter Beitrag: 17.05.2018, 12:22
  3. Antworten: 2
    Letzter Beitrag: 19.01.2018, 11:37
  4. Antworten: 1
    Letzter Beitrag: 03.11.2016, 17:28
  5. Antworten: 3
    Letzter Beitrag: 18.09.2015, 08:28

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •