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

Ergebnis 1 bis 1 von 1

Thema: Vorschlag für Error-Handling mit WinCC-Fehlerauswertung/-anzeige & Einzelquitt.

  1. #1
    Registriert seit
    28.03.2009
    Beiträge
    81
    Danke
    16
    Erhielt 4 Danke für 4 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich musste für einen Kunden das 'Fehlerhandling' vereinheitlichen und habe mir lange den Kopf darüber zerbrochen.
    Entstanden sind drei Funktionen und zwei Excel-Tabellen, mit der man das Anlegen, Quittieren, Einzelquittieren,
    In-und Exportiereren von Fehlermeldungen relativ komfortabel erledigen kann.

    Schaut euch das 18minütige Video an.
    War schon fast mehr Arbeit als wie das Ausdenken und Umsetzen des Codes
    1.png

    2.png

    3.png

    Das Ergebnis ist sicherlich nicht der Weisheits letzter Schluss und ausbaufähig.
    Es ist in AWL programmiert und ist mit Zeilenkommentaren versehen.
    Vllt hilft es dem einen oder anderen. Wiederverwendung, Verbesserung ist explizit erwünscht.
    Oder falls Jemand noch Anwendungsbeispiele 'Any, AR1, AR2, Loop, etc...' braucht - hier findet ihr alles

    Da nicht alles auf dem 1.Blick ersichtlich ist, habe ich mir auch erlaubt Video zu erstellen.
    Hier wird die Funktion, der Aufbau bishin zur Simulation mit PLCsim erklärt.


    Ich hätte das Demo-Projekt hochgeladen. Allerdings verpfuscht Siemens alle möglichen
    Stellen im Projekt mit personen-und firmenbezogenen Angaben.

    Darum müssen AWL-Quellen und das Video ausreichen

    Hochgeladen habe ich das Packet bestehend aus drei AWL-Quellen, ExcelTabellen und ein Video
    auf mega.nz... mir ist auf die schnelle kein besserer Filehoster eingefallen.
    https://mega.nz/#F!xJcXARLT!YykSh7HUorCOcAbCYdIN9Q

    Viel Spass. Feedback/Kritik ist erwünscht

    Edit: Die exportierten AWL Quellen befinden sich auf dem Hoster.
    Falls Jemand Hoster nicht mag, hier sind sie auch...

    Code:
    FUNCTION "1_MoveFaultsToHMI" : VoidTITLE = Verodere Ext. Quittierbits mit Fehlermeldungen und schiebe es zum HMI-Array
    { S7_Optimized_Access := 'FALSE' }
    VERSION : 0.1
       VAR_INPUT 
          iResPLC : Bool;   // Internal/Global reset request from PLC
          iResExt : Bool;   // Internal/Global reset request from external
          iFaults : Any;   // Pointer for the source of all faults
          iExtResets : Any;   // Pointer for the source of the external request requests
          qHMITrigArray : Any;   // Pointer for the destination HMI array, where the faults and the reset requests are stored
       END_VAR
    
    
       VAR_OUTPUT 
          qResExt : Bool;   // Collective reset from external
          qfault : Bool;   // fault: target array is not large enough
       END_VAR
    
    
       VAR_TEMP 
          hexFF : Byte;   // local 'constant' with B#16#FF
          hex00 : Byte;   // local 'constant' with B#16#00
          loop01 : Int;   // loop counter
          retval : Int;   // just return value, for some 'calls'
          tFaults : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tExtResets : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tHMITrigArray : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          WorkAnySource : Any;   // Any pointer for the 'source'
          WorkAnyTarget : Any;   // Any pointer for the 'destination'
          StartAdress2ndHalfTarget : DWord;   // adres-pointer for the 2nd half of the destination
       END_VAR
    
    
    
    
    BEGIN
    NETWORK
    TITLE = Lokaldaten initialisieren
          L b#16#0;
          T #hex00;
          L b#16#ff;
          T #hexFF;
    NETWORK
    TITLE = Eingänge 'zerlegen' und in Lokaldaten kopieren
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iFaults;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tFaults;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iExtResets;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tExtResets;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##qHMITrigArray;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tHMITrigArray;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    NETWORK
    TITLE = Prüfen ob das Zielfach ausreichen groß ist
    //load source byte length and multiply by 2
    //reason: in the target array, the first half are the triggers
    //        the 2nd half will be the reset bits through the hmi
    //        Hence, the destination array must have the double size
    //        of the source.
    //load source
          L #tFaults.repetition;
          L 2;
          *I;
    //load destination
          L #tHMITrigArray.repetition;
    //if the source is bigger than the destination = fault
          >I;
          = #qfault;
    //if we have a fault, no further processment is required
    //programming error
          BEC;
    NETWORK
    TITLE = Kopiere 1.Hälfte in Ziel-Array: Fehlermeldungen
    //build a temporary anypointer for the SOURCE
          LAR1 P##WorkAnySource;
          L #tFaults."10h";
          T B[ AR1, P#0.0];
          L #tFaults.DataType;
          T B[ AR1, P#1.0];
          L #tFaults.repetition;
          T W[ AR1, P#2.0];
          L #tFaults.db_no;
          T W[ AR1, P#4.0];
          L #tFaults.adres;
          T D[ AR1, P#6.0];
    //build a temporary anypointer for the DESTINATION
          LAR1 P##WorkAnyTarget;
          L #tHMITrigArray."10h";
          T B[ AR1, P#0.0];
          L #tHMITrigArray.DataType;
          T B[ AR1, P#1.0];
          L #tHMITrigArray.repetition;
          T W[ AR1, P#2.0];
          L #tHMITrigArray.db_no;
          T W[ AR1, P#4.0];
          L #tHMITrigArray.adres;
          T D[ AR1, P#6.0];
    
    
    //just copy data now
          CALL BLKMOV
          {blk_type := 'Variant'}
          (  SRCBLK                      := #WorkAnySource , 
             RET_VAL                     := #retval , 
             DSTBLK                      := #WorkAnyTarget
          );
    NETWORK
    TITLE = Kopiere 2.Hälfte in Ziel-Array: Fehlermeldungen - bei Reset PLC oder EXT Zielbereich mit FF überschreiben
    //build a temporary anypointer for the SOURCE
          LAR1 P##WorkAnySource;
          L #tExtResets."10h";
          T B[ AR1, P#0.0];
          L #tExtResets.DataType;
          T B[ AR1, P#1.0];
          L #tExtResets.repetition;
          T W[ AR1, P#2.0];
          L #tExtResets.db_no;
          T W[ AR1, P#4.0];
          L #tExtResets.adres;
          T D[ AR1, P#6.0];
    
    
    //#################################################################
    //before we build the DESTINATION Array,
    //we must correct/adapt the start adress.
    //as described in a previous network, the external
    //reset requests has to be placed into the 2nd half of 
    //the target array.
    
    
    //take the length (repition factor)
          L #tHMITrigArray.repetition;
    //divide by 2 (=the half)
          L 2;
          /I;
    //multiply by 8, to get the right format (bitwise adresing)
          SLD 3;
    //start adres is calculated right now
    //we should also take the memory area from the origin any pointer
          L #tHMITrigArray.adres;
    //take only the lowest byte
    //wordwise OR accu1 (memory area) with accu2 (calculated start adres)
          OD;
    //save for later usage
          T #StartAdress2ndHalfTarget;
    //#################################################################
    
    
    //build a temporary anypointer for the DESTINATION
          LAR1 P##WorkAnyTarget;
          L #tHMITrigArray."10h";
          T B[ AR1, P#0.0];
          L #tHMITrigArray.DataType;
          T B[ AR1, P#1.0];
          L #tHMITrigArray.repetition;
          T W[ AR1, P#2.0];
          L #tHMITrigArray.db_no;
          T W[ AR1, P#4.0];
    //take the previously calculated start adres for the 2nd half of 
    //destination array
          L #StartAdress2ndHalfTarget;
          T D[ AR1, P#6.0];
    
    
    //just copy data now
          CALL BLKMOV
          {blk_type := 'Variant'}
          (  SRCBLK                      := #WorkAnySource , 
             RET_VAL                     := #retval , 
             DSTBLK                      := #WorkAnyTarget
          );
    
    
    //#################################################################
    //if there is PLC or External reset request fill the whole destination
    //area with B#16#FF
    //We are going to fill only the area, which is neccessary.
    //This is the reason, why we are calculation the destination pointer again
    
    
          O #iResPLC;
          O #iResExt;
          JCN nofi;
    
    
    //build a temporary anypointer for the DESTINATION
          LAR1 P##WorkAnyTarget;
          L #tHMITrigArray."10h";
          T B[ AR1, P#0.0];
          L #tHMITrigArray.DataType;
          T B[ AR1, P#1.0];
    //instead of the length of the destination area (is longer than source)
    //we will use the length of source...we make sure, that we are only
    //filling/initialising the are, which is neccessary.
    //      L     #tAnyHMITrigArray.repetition
          L #tExtResets.repetition;
          T W[ AR1, P#2.0];
          L #tHMITrigArray.db_no;
          T W[ AR1, P#4.0];
    //take the previously calculated start adres for the 2nd half of 
    //destination array
          L #StartAdress2ndHalfTarget;
          T D[ AR1, P#6.0];
    
    
          CALL FILL
          {ptr_type := 'Variant'}
          (  BVAL                        := #hexFF , 
             RET_VAL                     := #retval , 
             BLK                         := #WorkAnyTarget
          );
    
    
    nofi:      NOP 0;
    NETWORK
    TITLE = Prüfe ob irgendeine Reset-Anforderung von Extern anliegt und baue ein 'collective_reset' daraus
    //initialise the local bool, for evaluating if any external reset is existent
          CLR;
          = #qResExt;
    
    
    //here we are going to check, if there is any reset request existent from 
    //the external source... this will be done by a loop
    //we are going to 'scan' the external requests requests bytewise
    
    
    //as first, open the corresponding data block, where the information is stored
          OPN DB[ #tExtResets.db_no];
    
    
    //load the adres pointer into AR1
          LAR1 #tExtResets.adres;
    //the length (in bytes) of the source area, will be the counter for the 
    //loop, hence we're going to scan 'byte-wise'
          L #tExtResets.repetition;
    lp01:      T #loop01;
    
    
    //open the first byte, and check it 'not equal zero'
          A(;
          L B[ AR1, P#0.0];
          L #hex00;
          <>I;
          );
    //if its something else than zero (no jump), set '#qResExt' to '1' and exit loop
    //if its zero (jump), put an offset to the AR1 (next byte) and go to next loop scan
          JCN next;
          S #qResExt;
          JU olop;
    
    
    next:      +AR1 P#1.0;
          L #loop01;
          LOOP lp01;
    
    
    olop:      NOP 0;
    
    
    //if there is a external global request, set as well the output to true
          A #iResExt;
          S #qResExt;
    
    
    END_FUNCTION
    Code:
    FUNCTION "2_SplitHMIReset" : VoidTITLE = Einzelquittierung von der Visualisierung splitten und in ein Strukt kopieren
    { S7_Optimized_Access := 'FALSE' }
    VERSION : 0.1
       VAR_INPUT 
          iHmiResetArray : Any;   // Pointer of the source of all HMI reset requests (array of word)
          qHmiResetSplitted : Any;   // Pointer for the destination, where the requests will stored
          iHelpArray : Any;   // Pointer of the source with help flags (array of word)
          iEdgeEval : Bool;   // 1=with edge evaluation, 0=without edge evaluation
       END_VAR
    
    
       VAR_OUTPUT 
          qHmiReset : Bool;   // collective reset request from HMI received
       END_VAR
    
    
       VAR_TEMP 
          tiHmiResetArray : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tqHmiResetSplitted : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tiHelpArray : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tEdgeEval : Bool;   // 1=with edge evaluation, 0=without edge evaluation
          loop01 : Int;   // loop counter
          retval : Int;   // just return value, for some 'calls'
          repetition_in_word : Int;   // interim value, for the calculation of the loop counter
          result_word_loop : Word;   // interim value, for saving
       END_VAR
    
    
    
    
    BEGIN
    NETWORK
    TITLE = Initialisation
          A #iEdgeEval;
          = #tEdgeEval;
    NETWORK
    TITLE = Eingänge 'zerlegen' und in Lokaldaten kopieren
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iHmiResetArray;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tiHmiResetArray;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split DestinationAny into local data
    //copy any pointer of source into AR1
          L P##qHmiResetSplitted;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tqHmiResetSplitted;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split DestinationAny into local data
    //copy any pointer of source into AR1
          L P##iHelpArray;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tiHelpArray;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    NETWORK
    TITLE = Werte Einzelquittierung aus
    //issue: the hmi is sending always '1' as acknowledgment for the corresponding
    //fault, if there is no reset request neccessary.
    //it's is not good style, to occupy the reset input of flip flop with a
    //'1', if there is no reason for that.
    //that is the reason, why we have to evaluate the rising edge (one shot) only.
    //for that, unfortunately we need for each ack-bit a help bit.
    //we are going to start a loop, whom the result will be stored in the local data
    //after loop, the local data will be copied into the destination.
    
    
    //open the source data block, where the acknowledgement bits are coming from
          OPN DB[ #tiHmiResetArray.db_no];
    //load the start adres into AR1
          LAR1 #tiHmiResetArray.adres;
    
    
          L #tqHmiResetSplitted.repetition;
    //divide by /2, hence we are going to scan wordwise
          L 2;
          /I;
          T #repetition_in_word;
    lp01:      T #loop01;
    
    
    //if EdgeEvaluation is not desired, jump directly to copying of data
    //without evaluating of risingedge evaluation
          AN #tEdgeEval;
          JC noed;
    
    
    //calculate coresponding adres for help words and open data instance
          L #tiHelpArray.adres;
    //disable memory area format (usually b#16#84 (=DB) is located here
          AD DW#16#00ffffff;
    //add '85' as memory area (=DI)
          OD dw#16#85000000;
    //put the result into AR2
          LAR2;
    //calculate offset for the adres
    //1st run: e.g. (32-32)*2 = Offset = 0 bytes
    //2nd run:  (32-31)*2 = 1*2= 2 bytes
    //3rd run: (32-30)*2 = 6 bytes
    //etc...
          L #repetition_in_word;
          L #loop01;
          -I;
          L 2                  ;//*2, hence we are scanning word-wise
          *I;
    //bring to correct pointer format in bits = multiply by 8
          SLD 3;
    //add the adres to AR2
          +AR2;
    //opn data block in to DI register
          OPN DI[ #tiHelpArray.db_no];
    
    
    //#############################################
    //check for rising edge - wordwise
    //check current values with help flags, if there is a difference
          L DBW[ AR1, P#0.0];
          L DIW[ AR2, P#0.0];
          INVI;
          AW;
    //hence we have only two adres registers, we must save the value into
    //local data, so that we can use it later
          T #result_word_loop;
    
    
    //overwrite help flags with current values
          L DBW[ AR1, P#0.0];
          T DIW[ AR2, P#0.0];
          JU write;
    //#############################################
    
    
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //this part will only be executed, if edge evaluation doesnt
    //has been desired / not wished
    noed:      L DBW[ AR1, P#0.0];
          T #result_word_loop;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
    write:      NOP 0;
    //calculate adres of target
    //description, what we are doing here, is described few lines above
          L #tqHmiResetSplitted.adres;
          AD DW#16#00ffffff;
          OD dw#16#85000000;
          LAR2;
          L #repetition_in_word;
          L #loop01;
          -I;
          L 2                  ;//*2, hence we are scanning word-wise
          *I;
          SLD 3;
          +AR2;
          OPN DI[ #tqHmiResetSplitted.db_no];
    
    
    //take the saved value from the local stack and put into the target
          L #result_word_loop;
          T DIW[ AR2, P#0.0];
    
    
    //add offset of two for next scan into AR1
          +AR1 P#2.0;
          L #loop01;
          LOOP lp01;
    NETWORK
    TITLE = Globales Reset durch HMI - wurde irgendeine Einzelquittierung ausgeführt?
    //initialise the local bool, for evaluating if any external reset is existent
          CLR;
          = #qHmiReset;
    
    
    //here we are going to check, if there is any reset request existent from 
    //the HMI... this will be done by a loop
    //we are going to 'scan' bytewise
    
    
    //as first, open the corresponding data block, where the information is stored
          OPN DB[ #tqHmiResetSplitted.db_no];
    
    
    //load the adres pointer into AR1
          LAR1 #tqHmiResetSplitted.adres;
    //the length (in bytes) of the source area, will be the counter for the 
    //loop, hence we're going to scan 'byte-wise'
          L #tqHmiResetSplitted.repetition;
    lp02:      T #loop01;
    
    
    //open the first byte, and check it 'not equal zero'
          A(;
          L DBB[ AR1, P#0.0];
          L b#16#0;
          <>I;
          );
    //if its something else than zero (no jump), set '#qResExt' to '1' and exit loop
    //if its zero (jump), put an offset to the AR1 (next byte) and go to next loop scan
          JCN next;
          S #qHmiReset;
          JU olop;
    
    
    next:      +AR1 P#1.0;
          L #loop01;
          LOOP lp02;
    
    
    olop:      NOP 0;
    END_FUNCTION
    Code:
    FUNCTION "3_CollectiveFault" : VoidTITLE = Prüfen auf Sammelfehler
    { S7_Optimized_Access := 'FALSE' }
    VERSION : 0.1
    //Dieses Baustein kann sechs Strukturen auf Sammelfehler überprüfen.
    //Die Fehlerstrukturen müssen sich in einem globalen Datenbaustein (DB) befinden.
    //Es dürfen nicht die Instanzdaten eines FB's ein (DI).
       VAR_INPUT 
          iGroup_All : Any;   // Pointer of the source, where all faults are located
          iGroup1 : Any;   // Pointer of a source/group, where should be shown for a collective fault
          iGroup2 : Any;   // Pointer of a source/group, where should be shown for a collective fault
          iGroup3 : Any;   // Pointer of a source/group, where should be shown for a collective fault
          iGroup4 : Any;   // Pointer of a source/group, where should be shown for a collective fault
          iGroup5 : Any;   // Pointer of a source/group, where should be shown for a collective fault
       END_VAR
    
    
       VAR_OUTPUT 
          qerror : Bool;   // Input parameters are wrong
          qFault_All : Bool;   // Collective Fault
          qFault1 : Bool;   // Collective fault in Group 01
          qFault2 : Bool;   // Collective fault in Group 02
          qFault3 : Bool;   // Collective fault in Group 03
          qFault4 : Bool;   // Collective fault in Group 04
          qFault5 : Bool;   // Collective fault in Group 05
       END_VAR
    
    
       VAR_TEMP 
          tGroupAll : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tGroup1 : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tGroup2 : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tGroup3 : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tGroup4 : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tGroup5 : Struct   // splitted any pointer
             "10h" : Byte;
             DataType : Byte;
             repetition : Int;
             db_no : Int;
             adres : DWord;
          END_STRUCT;
          tloop : Int;
       END_VAR
    
    
    
    
    BEGIN
    NETWORK
    TITLE = Initialisierung
          CLR;
          = #qerror;
          = #qFault_All;
          = #qFault1;
          = #qFault2;
          = #qFault3;
          = #qFault4;
          = #qFault5;
    NETWORK
    TITLE = Eingänge 'zerlegen' und in Lokaldaten kopieren
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup_All;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroupAll;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup1;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroup1;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup2;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroup2;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup3;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroup3;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup4;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroup4;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    
    
    //###Split SourceAny into local data
    //copy any pointer of source into AR1
          L P##iGroup5;
          LAR1;
    //copy any pointer of target into AR2
          LAR2 P##tGroup5;
    //1st bytes is always 10h for s7
          L B[ AR1, P#0.0];
          T B[ AR2, P#0.0];
    //copy data type
          L B[ AR1, P#1.0];
          T B[ AR2, P#1.0];
    //copy repetition factor
          L W[ AR1, P#2.0];
          T W[ AR2, P#2.0];
    //copy db number
          L W[ AR1, P#4.0];
          T W[ AR2, P#4.0];
    //copy pointer (start adres)
          L D[ AR1, P#6.0];
          T D[ AR2, P#6.0];
    //################################################
    NETWORK
    TITLE = Prüfe GroupAll nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroupAll.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroupAll.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en01;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroupAll.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err1;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroupAll.db_no];
          LAR1 #tGroupAll.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroupAll.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp01:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne01;
          S #qFault_All;
          JU en01;
    
    
    ne01:      +AR1 P#2.0;
          L #tloop;
          LOOP lp01;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en01;
    
    
    err1:      SET;
          S #qerror;
    
    
    en01:      NOP 0;
    NETWORK
    TITLE = Prüfe Group1 nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroup1.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroup1.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en02;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroup1.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err2;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroup1.db_no];
          LAR1 #tGroup1.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroup1.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp02:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne02;
          S #qFault1;
          JU en02;
    
    
    ne02:      +AR1 P#2.0;
          L #tloop;
          LOOP lp02;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en02;
    
    
    err2:      SET;
          S #qerror;
    
    
    en02:      NOP 0;
    NETWORK
    TITLE = Prüfe Group2 nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroup2.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroup2.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en03;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroup2.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err3;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroup2.db_no];
          LAR1 #tGroup2.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroup2.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp03:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne03;
          S #qFault2;
          JU en03;
    
    
    ne03:      +AR1 P#2.0;
          L #tloop;
          LOOP lp03;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en03;
    
    
    err3:      SET;
          S #qerror;
    
    
    en03:      NOP 0;
    NETWORK
    TITLE = Prüfe Group3 nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroup3.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroup3.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en04;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroup3.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err4;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroup3.db_no];
          LAR1 #tGroup3.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroup3.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp04:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne04;
          S #qFault2;
          JU en04;
    
    
    ne04:      +AR1 P#2.0;
          L #tloop;
          LOOP lp04;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en04;
    
    
    err4:      SET;
          S #qerror;
    
    
    en04:      NOP 0;
    NETWORK
    TITLE = Prüfe Group4 nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroup4.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroup4.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en05;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroup4.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err5;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroup4.db_no];
          LAR1 #tGroup4.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroup4.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp05:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne05;
          S #qFault2;
          JU en05;
    
    
    ne05:      +AR1 P#2.0;
          L #tloop;
          LOOP lp05;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en05;
    
    
    err5:      SET;
          S #qerror;
    
    
    en05:      NOP 0;
    NETWORK
    TITLE = Prüfe Group5 nach einem Sammelfehler
    //at first, we will check if the input any pointer contents meaningful
    //data (db no, start adres, repetition factor)
    //the pointer must contain a data block number
          O(;
          L #tGroup5.db_no;
          L 0;
          <=I;
          );
    
    
    //the pointer must containt a length/repetition factor
          O(;
          L #tGroup5.repetition;
          L 0;
          <=I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC en06;
    
    
    //check for the correct memory area '84' = data block
          O(;
          L #tGroup5.adres;
    //for comparing only the first byte with memory area, we must 'disable'
    //the start adress (the following three bytes)
          AD dw#16#ff000000;
          L dw#16#84000000;
          <>I;
          );
    //if one this checks are positive jump and dont execute the rest of 
    //this network
          JC err6;
    
    
    //########################################################################
    //the structure will be scanned by a loop word-wise.
    //if there is something equal than 'not zero' the corresponding
    //flag will be set
    
    
    //opn data block
          OPN DB[ #tGroup5.db_no];
          LAR1 #tGroup5.adres;
    //&&&&&&&&&&&&&&& LOOP &&&&&&&&&&&&&&&&&&&&&&&&&
          L #tGroup5.repetition;
    //divide thorugh to, hence we are going to scan wordwise
          L 2;
          /I;
    lp06:      T #tloop;
    
    
    //if its not zero, set fault and jump out of the loop
          L W[ AR1, P#0.0];
          L 0;
          <>I;
          JCN ne06;
          S #qFault2;
          JU en06;
    
    
    ne06:      +AR1 P#2.0;
          L #tloop;
          LOOP lp06;
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
          JU en06;
    
    
    err6:      SET;
          S #qerror;
    
    
    en06:      NOP 0;
    END_FUNCTION
    Geändert von logo78 (04.09.2016 um 20:06 Uhr)
    Zitieren Zitieren Vorschlag für Error-Handling mit WinCC-Fehlerauswertung/-anzeige & Einzelquitt.  

Ähnliche Themen

  1. Antworten: 11
    Letzter Beitrag: 15.09.2014, 11:19
  2. Vorschlag für die Wahl
    Von waldy im Forum Stammtisch
    Antworten: 1
    Letzter Beitrag: 23.09.2013, 06:58
  3. WinCC V7.0SP3 -HAndling von ARRAYS
    Von soundmachine123 im Forum HMI
    Antworten: 8
    Letzter Beitrag: 21.05.2013, 11:53
  4. Handling Störmeldungen WinCC flexibel
    Von Markus im Forum HMI
    Antworten: 29
    Letzter Beitrag: 13.09.2011, 18:51
  5. Antworten: 13
    Letzter Beitrag: 30.11.2010, 23:16

Lesezeichen

Berechtigungen

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