TIA Struktur variabler Länge an einen FB übergeben (Variant)

Smicon

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

ich programmiere mit TIA V13 eine 1513er Steuerung. Wie mein Titel schon so schön sagt, möchte ich einem FB eine Struktur variabler länge übergeben. Der Funktionsbaustein soll überprüfen, ob sich ein Wert der Struktur geändert hat. Die Struktur befindet sich in einem globalen DB und enthält Bool-Variablen. Ich habe mir schon die Funktionen zu Variant angesehen. Um die Anzahl von Variablen abzufragen, gibt es die CountOfElements() Funktion. Leider funktioniert diese aber nur mit Arrays. Gibt es eine Möglichkeit die Strukturgröße zu erfassen oder die Anzahl der Elemente zu ermitteln?
 
Was ist das für eine Struktur? Ein Datentyp?

Es gibt
Code:
TypeOfElements()
um den Datentyp zu erkennen.

Danach musst du diesen sichern und wenn der gleiche wieder kommt mit dem gesicherten vergleichen. Aber das gibt ein wenig Schreibarbeit...
 
Sag lieber was für ein Datentyp mit Variabler länge du übergeben möchtest?

Eine Struktur kann mehre Variablen unterschiedlicher Typen enthalten. Und damit ist dann auch die Länge variabel.
Er will also anscheinend Struktur A und B und C und ... jeweils an einen FB übergeben. Und die Srukturen sind zumindest in der Länge Variabel.
So würde ich seine Aussage interpretieren.
 
Ok ich muss anscheinend noch genauer drauf eingehen was ich machen will. Aktuell wird meinem Baustein eine Struktur über einen Any Pointer übergeben. In der Struktur befinden sich 80 Bools. Das soll aber wie gesagt variabel bleiben. Aktuell wird vom Any Pointer die Länge ermittelt und mit einer for-Schleife überprüft ob sich der Wert eines Bools geändert hat. In diesem Fall wird ein Event gesetzt. Diesen Baustein will ich jetzt auf Variant ändern um die optimierten Bausteine nutzen zu können.

@Rodger Wenn ich die 80 Bits in einen Datentyp packe und dann vergleiche ist die länge ja wieder festgelegt. Oder was meinst du mit Typ?

Code:
   VAR_INPUT 
      Events : Any;
      EventsPtr { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} AT Events : Struct   // Pointer at Warnings
         Synctax_ID { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : Byte;
         DataType { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : Byte;
         Count { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : Word;
         DB_Nr { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : Word;
         Byte_Ptr { S7_HMI_Accessible := 'False'; S7_HMI_Visible := 'False'} : DWord;
      END_STRUCT;

   END_VAR

   VAR_OUTPUT 
      Event : Bool;
      Error : Bool;
      FB_RET_VAL : Int;
   END_VAR

   VAR 
      Index : Int;
      tmrAcknowledge {OriginalPartName := 'TON'; LibVersion := '1.0'} : TON;
      Edge_Ack : Bool;
      SFC_RET_VAL : Int;
   END_VAR

   VAR_TEMP 
      AllDataLength : Int;
      NrOfWords : Int;
      CheckWord : Int;
      Actual : Any;
      ActualPtr AT Actual : Struct   // Pointer at Actual
         Synctax_ID : Byte;
         DataType : Byte;
         Count : Word;
         DB_Nr : Word;
         Byte_Ptr : DWord;
      END_STRUCT;
      Falseword : Word;
      Trueword : Word;
   END_VAR

   VAR CONSTANT 
      ERR_INVALID_DATATYPE : Byte := 16#0001;
      ERR_DATA_LENGTH_IS_NULL : Byte := 16#0002;
      ERR_SFC_BLKMOV_FAILED : Byte := 16#0005;
      ERR_SFC_FILL_FAILED : Byte := 16#0006;
      ERR_SFC_FILL_FAILED_1 : Int := 6;
      ERR_INVALID_DATATYPE_1 : Int := 1;
      ERR_DATA_LENGTH_IS_NULL_1 : Int := 2;
      ERR_SFC_BLKMOV_FAILED_1 : Int := 5;
   END_VAR


BEGIN

    
        // Constants
        #Falseword := 0;
        #Trueword := 16#FFFF;    

      // Check if ANY-Pointer is Type "Byte"
      IF(#EventsPtr.DataType <> b#16#02) THEN
            
        #FB_RET_VAL := #ERR_INVALID_DATATYPE_1;
        #Error := true;
      
      ELSE
        #AllDataLength := WORD_TO_INT(#EventsPtr.Count);
        
        IF(#AllDataLength < 2) THEN
          
          #FB_RET_VAL := #ERR_DATA_LENGTH_IS_NULL_1;  
          #Error := true;
          
        ELSE  
        
          #NrOfWords := #AllDataLength / 2;
          
          #Event := 0;
          #Actual := #Events;
          #ActualPtr.Count := 2;
                  
          FOR #Index := 1 TO #NrOfWords BY 1 DO
            
             #ActualPtr.Byte_Ptr :=  DINT_TO_DWORD(DWORD_TO_DINT(#EventsPtr.Byte_Ptr) +  DWORD_TO_DINT(SHL(IN:=INT_TO_DWORD(2 * (#Index - 1)),N:=3)));
            
            #SFC_RET_VAL := BLKMOV(SRCBLK := #Actual, DSTBLK => #CheckWord); 
              
            IF(#SFC_RET_VAL > 0) THEN
              
              #FB_RET_VAL := #ERR_SFC_BLKMOV_FAILED_1;
              #Error := true;
              
            ELSE
              
              IF(#CheckWord <> 0) THEN
                
                #Event := true;
                
              END_IF;


              
            END_IF;
            
          END_FOR;
        
        END_IF;
    
      END_IF;

    
END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Dann Pack die Bits in ein Array ansonsten sehe ich schwarz für deinen Baustein.

Alles andere ist, wie ich finde, auch ein wenig ein gebastel.
 
Zurück
Oben